Your marketing team spent $50k acquiring customers last month, but you don't know when you'll break even on that investment. CAC payback period—how many months until a customer's revenue covers their acquisition cost—is essential for forecasting unit economics. Stripe has all the data you need; you just need to extract it correctly.
Pull Subscription and Customer Data from Stripe
Extract your revenue data using Stripe's API. You'll need customer acquisition dates and subscription amounts to calculate anything meaningful.
Fetch customers by creation date
Use the Customers API endpoint with a created filter to get all customers acquired during a specific period. Stripe returns the created timestamp (Unix seconds) for each customer, which marks their acquisition date.
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
// Get all customers created in January 2025
const customers = await stripe.customers.list({
limit: 100,
created: {
gte: Math.floor(new Date('2025-01-01') / 1000),
lte: Math.floor(new Date('2025-01-31T23:59:59') / 1000)
}
});
customers.data.forEach(customer => {
const acquiredDate = new Date(customer.created * 1000);
console.log(`${customer.id}: acquired ${acquiredDate.toISOString()}`);
});Get subscription revenue per customer
For each customer, fetch their Subscriptions and sum the unit_amount from active subscriptions. This gives you the monthly recurring revenue (MRR) per customer. Filter out trials and inactive subscriptions.
const customerId = 'cus_abc123';
const subscriptions = await stripe.subscriptions.list({
customer: customerId,
status: 'all'
});
let monthlyRevenue = 0;
subscriptions.data.forEach(sub => {
// Only count active subs, exclude trials
if (sub.status === 'active' && sub.items.data[0]) {
const item = sub.items.data[0];
// Check if billing is monthly
if (item.price.recurring && item.price.recurring.interval === 'month') {
monthlyRevenue += item.price.unit_amount / 100; // Convert from cents
}
}
});
console.log(`${customerId} MRR: $${monthlyRevenue.toFixed(2)}`);Aggregate MRR by acquisition cohort
Group customers by their acquisition month, calculate each customer's MRR, then average it across the cohort. This tells you the expected monthly revenue from a typical customer acquired in that period.
const cohorts = {};
// Process all customers
for (const customer of customers.data) {
const acquiredDate = new Date(customer.created * 1000);
const cohortKey = `${acquiredDate.getFullYear()}-${String(acquiredDate.getMonth() + 1).padStart(2, '0')}`;
// Get MRR for this customer
const subs = await stripe.subscriptions.list({ customer: customer.id });
let mrr = 0;
subs.data.forEach(sub => {
if (sub.status === 'active' && sub.items.data[0]?.price.recurring?.interval === 'month') {
mrr += sub.items.data[0].price.unit_amount / 100;
}
});
// Add to cohort
if (!cohorts[cohortKey]) cohorts[cohortKey] = { count: 0, totalMRR: 0 };
cohorts[cohortKey].count += 1;
cohorts[cohortKey].totalMRR += mrr;
}
// Calculate average MRR per cohort
Object.entries(cohorts).forEach(([month, data]) => {
const avgMRR = data.totalMRR / data.count;
console.log(`${month}: ${data.count} customers, avg MRR $${avgMRR.toFixed(2)}`);
});created, multiply your date by Math.floor(new Date() / 1000). Also, Stripe's test mode shows up in API results unless you filter with stripe.objects.list({expand: ['data.default_source']})—explicitly exclude test mode in production dashboards.Calculate CAC Payback Period
Now you have the average MRR per customer. Divide your acquisition spend by that MRR to get payback in months.
Get your CAC from marketing spend
Pull your total marketing spend for the cohort (ad spend, sales salaries, tools—whatever your company defines as acquisition cost) and divide by the number of customers acquired that month. Stripe doesn't track this, but you'll have it from your accounting system or ad platform.
// Example: spent $40k acquiring customers in January 2025
const marketingSpendJan = 40000;
const customersAcquiredJan = 200; // from cohorts data above
const CAC = marketingSpendJan / customersAcquiredJan;
console.log(`CAC for Jan cohort: $${CAC}`); // $200Divide CAC by average MRR
The payback period is CAC divided by average monthly revenue per customer. The result is how many months until that customer's subscription revenue matches their acquisition cost.
const CAC = 200; // $200 acquisition cost
const avgMRR = 50; // $50 average monthly revenue (from cohort calculation)
const paybackMonths = CAC / avgMRR;
console.log(`CAC payback period: ${paybackMonths.toFixed(1)} months`);
// Example result: 4 months
// If this customer stays 12+ months, you've 3x'd your acquisition spendTrack Cohort Payback Over Time
Run this calculation monthly for each cohort to watch trends. Is CAC rising while payback lengthens? That's a signal to adjust your acquisition strategy.
Build a payback cohort table
Create a monthly table where each row is a cohort and columns show CAC, average MRR, and payback months. This tells you if new customers are becoming more expensive and harder to recoup.
// Assuming cohorts object from step 3 above and spending data
const marketingSpend = {
'2025-01': 40000,
'2025-02': 50000,
'2025-03': 48000
};
const paybackAnalysis = {};
Object.entries(cohorts).forEach(([month, data]) => {
const spend = marketingSpend[month] || 0;
const cac = spend / data.count;
const avgMRR = data.totalMRR / data.count;
const payback = cac / avgMRR;
paybackAnalysis[month] = {
customers: data.count,
CAC: cac.toFixed(2),
avgMRR: avgMRR.toFixed(2),
paybackMonths: payback.toFixed(1)
};
});
console.table(paybackAnalysis);
// Output shows trends across monthsCommon Pitfalls
- Forgetting to exclude test mode customers—Stripe test environment mixes with live data in API results. Use metadata or filter explicitly by mode when querying.
- Including trial revenue—trials usually mean $0 MRR. Filter for
status: 'active'and confirmunit_amount > 0before summing. - Using gross revenue instead of net—don't forget refunds and chargebacks reduce your take-home. Pull from your Reports API if tracking net is critical.
- Measuring payback on only one month of data—CAC payback requires cohort analysis over time. A customer acquired in January might not churn until October. Calculate payback multiple months out.
Wrapping Up
You now have a way to measure whether your acquisition spend pays back in reasonable time. Run this monthly per cohort to watch your unit economics. If you want to track this automatically across all your tools—not just Stripe—Product Analyst can help.