You spent $200 acquiring a customer. When does their revenue cover that cost? Stripe has the subscription and charge data you need—you just have to connect it with your CAC numbers and visualize the payback timeline. This shows which customer cohorts are profitable fastest.
Fetch Customer Revenue from Stripe
Start by pulling all revenue tied to a specific customer—both one-time charges and recurring subscriptions.
Retrieve the customer from Stripe
Use the Customers section of the Stripe Dashboard or the API. You'll need the customer ID to query their revenue history.
const stripe = require('stripe')('sk_live_...');
const customer = await stripe.customers.retrieve('cus_Ixfe5tXlJXF8gP');List all charges for the customer
Get every one-time charge or payment. Use the charges.list() method with the customer filter to retrieve the full payment history and calculate total collected.
const charges = await stripe.charges.list({
customer: 'cus_Ixfe5tXlJXF8gP',
limit: 100
});
const totalCharges = charges.data.reduce((sum, charge) => {
return sum + (charge.amount / 100);
}, 0);
console.log(`Total charges: $${totalCharges}`);List invoices to capture subscription revenue
Subscriptions generate invoices. Loop through Invoices to get the full recurring revenue picture. Filter by status: 'paid' to count only revenue actually received, excluding draft or void invoices.
const invoices = await stripe.invoices.list({
customer: 'cus_Ixfe5tXlJXF8gP',
status: 'paid',
limit: 100
});
const totalInvoiced = invoices.data.reduce((sum, invoice) => {
return sum + invoice.total / 100;
}, 0);
console.log(`Total invoiced: $${totalInvoiced}`);charges and invoices or you'll miss subscription revenue. Charges are one-time payments; invoices come from subscriptions. Some customers have both, so total revenue = charges + invoiced amount.Calculate CAC Payback Time
Combine your CAC (from your CRM or internal database) with the Stripe revenue to find the exact month payback occurs.
Fetch or calculate CAC per customer
Your CAC lives elsewhere—marketing database, CRM, or your backend. Query it for the customer. CAC can be per-cohort (monthly ad spend ÷ customers acquired) or per-customer (actual spend attributed to that user). Be explicit about which you're using.
// Example: CAC from your database or marketing tool
const cacDatabase = {
'cus_Ixfe5tXlJXF8gP': 150 // Spent $150 to acquire this customer
};
const cac = cacDatabase['cus_Ixfe5tXlJXF8gP'];
const signupDate = new Date(customer.created * 1000);
console.log(`CAC: $${cac}, Signup: ${signupDate.toISOString().slice(0, 7)}`);Build monthly revenue timeline and find payback
Group Stripe payments by month, accumulating revenue over time. Find the first month where cumulative revenue exceeds CAC—that's your payback month.
const monthlyRevenue = {};
// Group invoices by month
invoices.data.forEach(invoice => {
const month = new Date(invoice.date * 1000).toISOString().slice(0, 7);
monthlyRevenue[month] = (monthlyRevenue[month] || 0) + (invoice.total / 100);
});
const cumulativeRevenue = [];
let cumulative = 0;
Object.keys(monthlyRevenue).sort().forEach(month => {
cumulative += monthlyRevenue[month];
cumulativeRevenue.push({ month, revenue: monthlyRevenue[month], cumulative });
});
const paybackMonth = cumulativeRevenue.find(row => row.cumulative >= cac)?.month;
const paybackMonths = cumulativeRevenue.findIndex(row => row.cumulative >= cac) + 1;
console.log(`Payback achieved: ${paybackMonth} (${paybackMonths} months after signup)`);Visualize the Payback Curve
Plot cumulative revenue against CAC as a horizontal reference line. The intersection point is where the customer becomes profitable. This is useful for cohort analysis—which acquisition channels pay back fastest?
Format data for charting
Convert your monthly revenue and CAC threshold into a format that works with any charting library. Include the CAC as a reference line and the payback point as a marker.
const chartData = cumulativeRevenue.map((row, index) => ({
month: row.month,
cumulativeRevenue: row.cumulative,
cac: cac,
isPaidBack: row.cumulative >= cac
}));
console.log(JSON.stringify(chartData, null, 2));Plot with a charting library
Use Chart.js, Recharts, or D3 to visualize. Plot Cumulative Revenue as a line and CAC as a dashed horizontal line. Highlight the intersection month to show payback visually.
// Example with Chart.js
const ctx = document.getElementById('paybackChart').getContext('2d');
const paybackChart = new Chart(ctx, {
type: 'line',
data: {
labels: chartData.map(d => d.month),
datasets: [
{
label: 'Cumulative Revenue',
data: chartData.map(d => d.cumulativeRevenue),
borderColor: '#171717',
backgroundColor: 'rgba(23, 23, 23, 0.05)',
fill: true,
tension: 0.3
},
{
label: `CAC ($${cac})`,
data: Array(chartData.length).fill(cac),
borderColor: '#999',
borderDash: [5, 5],
fill: false
}
]
},
options: {
responsive: true,
plugins: { title: { text: 'CAC Payback Timeline', font: { size: 14 } } }
}
});Common Pitfalls
- Forgetting to include both charges and invoices. Subscription revenue lives in invoices, not charges. Mix them incorrectly and your payback timeline is broken.
- Using invoice total instead of amount paid. Invoices include refunds, discounts, and partial payments. Always filter by
status: 'paid'and use thetotalfield on paid invoices only. - Not accounting for refunds or churned customers. If a customer churns and you refund them, their cumulative revenue goes negative. Subtract refunded amounts from revenue to show true payback.
- Confusing CAC by cohort vs. per-customer. Monthly cohort CAC (ad spend ÷ customers acquired that month) differs from actual per-customer acquisition spend. Be explicit which metric you're comparing against.
Wrapping Up
You now have a payback curve for any customer or cohort. This tells you how fast your acquisition investments convert to revenue—and which customer segments are profitable soonest. Run this analysis monthly to spot acquisition quality trends. If you want to track this automatically across tools, Product Analyst can help.