5 min read

How to Visualize CAC Payback in Stripe

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.

javascript
const stripe = require('stripe')('sk_live_...');

const customer = await stripe.customers.retrieve('cus_Ixfe5tXlJXF8gP');
Fetch a single customer record by ID

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.

javascript
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.

javascript
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}`);
Watch out: Include both 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.

javascript
// 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.

javascript
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.

javascript
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.

javascript
// 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 } } }
  }
});
Tip: Run this analysis per acquisition channel (paid search, organic, partner). You'll see which channels have the fastest payback—critical data for marketing budget allocation and channel strategy.

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 the total field 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.

Track these metrics automatically

Product Analyst connects to your stack and surfaces the insights that matter.

Try Product Analyst — Free