Subscription LTV attribution: credit every renewal to its channel
Subscription LTV attribution credits every renewal, upgrade and refund to the channel that won the customer. See the Stripe join, the math and where it breaks.
Muzahid Maruf, FounderUpdated
On this page
- 01What the first invoice leaves out
- 02How subscription LTV attribution works in Stripe
- 03Stripe events that change a channel's lifetime revenue
- 04Three ways to credit renewals
- 05Upgrades, refunds and trials
- 06Comparing channels by lifetime value
- 07What TrackRev does with a renewal
- 08Cases the join can't see
Explore with AI
Opens this article inside the chosen assistant with a ready-made prompt.
Subscription LTV attribution credits every renewal, upgrade and refund on a subscription to the channel that won the customer. A $49 plan that renews for 12 months produces $588, and a first-invoice report credits the channel with $49 of it.
In Stripe the fix takes one join and one rule: tie the first charge to a click, then let every later invoice on the same subscription ID inherit that channel.
Key takeaways
- At constant monthly churn, the first invoice equals the churn rate as a share of lifetime revenue: $49 of an expected $980 on a $49 plan at 5% churn.
- Every later invoice inherits the channel of the subscription's first charge, keyed by subscription ID, so renewals and upgrades credit the channel that won the customer.
- Count revenue from invoice.paid, and treat customer.subscription.updated as state, since it also fires on renewals, coupons and plan changes.
- A 14-day trial plus a 20-day gap between click and signup puts the first charge outside a 30-day attribution window, and every renewal then inherits no channel.
- Compare channels on cohorts of equal age and the same plan, because all-time revenue per customer favors older channels.
What the first invoice leaves out
Assume a customer pays the same price every month and each month carries the same chance of ending the subscription.
Lifetime revenue is then the price divided by the monthly churn rate, the arithmetic Paddle's CLV guide gives as average revenue per user divided by churn.
The first invoice is one month of that lifetime, so its share equals the churn rate.
| Monthly churn | Expected lifetime | Lifetime revenue at $49 | First invoice as a share | Still subscribed after 12 months |
|---|---|---|---|---|
| 1% | 100 months | $4,900 | 1% | 89% |
| 2% | 50 months | $2,450 | 2% | 78% |
| 3% | 33.3 months | $1,633 | 3% | 69% |
| 5% | 20 months | $980 | 5% | 54% |
| 8% | 12.5 months | $612.50 | 8% | 37% |
| 12% | 8.3 months | $408 | 12% | 22% |
| 20% | 5 months | $245 | 20% | 7% |
Constant-churn model on a $49 monthly plan, with no expansion, discounts or margin. Arithmetic, not customer data.
Take two channels that both deliver $49 on the first invoice, with newsletter readers churning at 3% a month and cold paid social at 8%. A first-invoice report calls them equal.
Over a lifetime the newsletter customer is worth $1,633 and the paid-social customer $612.50, a 2.7x gap. Both churn rates are assumptions.
Real churn is not constant.
David Skok's SaaS metrics essay uses cohort analysis to check whether a business loses most of its customers in the first couple of months, so use actual paid invoices for any cohort old enough to have them.
How subscription LTV attribution works in Stripe
Four links connect an ad click to the ninth invoice of a subscription. Each lives in a different system, and a break at any one of them orphans every invoice after it.
| Link | What holds it | Where it lives |
|---|---|---|
| 1. Click to visitor | A first-party visitor ID | Your tracking script and cookie |
| 2. Visitor to first charge | client_reference_id, metadata or the buyer's email | Checkout Session, PaymentIntent or Customer |
| 3. First charge to subscription | The subscription ID on the invoice | Invoice parent.subscription_details.subscription |
| 4. Subscription to each renewal | The same subscription ID | Every later invoice, with billing_reason subscription_cycle |
The first two links are identity problems. If the visitor ID never reaches Stripe Checkout, nothing downstream can recover the channel, and Stripe metadata attribution setup covers the write side.
When you start from a charge, as a refund event does, links 3 and 4 depend on your Stripe API version.
Stripe's subscription webhook documentation moves the subscription ID at 2025-03-31.basil, and a handler written for one version reads an empty field on the other.
| Stripe API version | Charge to invoice | Invoice to subscription |
|---|---|---|
| Before 2025-03-31.basil | charge.invoice | invoice.subscription |
| 2025-03-31.basil and later | No invoice field: take the PaymentIntent and list its invoice payments | invoice.parent.subscription_details.subscription |
Field paths from Stripe's subscription webhook documentation, October 2026.
You can also stamp the source on the subscription once. Stripe's metadata guide says each invoice a subscription creates gets a one-time snapshot of its metadata under parent.subscription_details.metadata, so every invoice.paid event carries the channel without a lookup.
Fixing a typo after month 3 leaves invoices 1 to 3 as they were.
Stripe events that change a channel's lifetime revenue
| Event | What Stripe says it means | What to do with it |
|---|---|---|
| invoice.paid | The invoice was successfully paid | Add amount_paid to the subscription's channel. billing_reason separates the first invoice (subscription_create), a renewal (subscription_cycle) and a plan change (subscription_update). |
| customer.subscription.updated | A subscription starts or changes, including renewals, coupons and plan changes | Track MRR movement. Add no revenue from it. |
| invoice.payment_failed | A payment for an invoice failed | Add nothing. Smart Retries can still turn the invoice into invoice.paid later. |
| charge.refunded | A subscription charge received a full or partial refund | Subtract the refunded amount from the same channel. |
| charge.dispute.created | A customer or their bank disputed a charge | Flag the revenue as at risk and subtract it if the dispute is lost. |
| customer.subscription.deleted | A customer's subscription ends | Stop accruing revenue and record the churn date for cohorts. |
Event descriptions from Stripe's subscription webhook documentation, October 2026. The right-hand column is a recommendation.
Stripe retries a failed live-mode webhook delivery for up to 3 days with exponential backoff, so key each revenue row by invoice ID and a replayed event changes nothing.
Three ways to credit renewals
A customer who pays $49 for 12 months produces $588, and the credit rule decides how much of it the winning channel books: all of it, 70% of it, or a forecast made on day one.
Carry the first credit forward
The channel that won the customer keeps all 12 invoices, $588 on a $49 plan, which answers which channel pays your MRR directly and costs one lookup per invoice.
It over-credits acquisition when a lifecycle email sequence or an onboarding call is what keeps people subscribed. I would start here and add complexity only when a budget decision demands it.
Decay the credit over time
A decay rule gives the acquisition channel a falling share and moves the remainder to a retention bucket.
With 100% for months 1 to 3, 80% for months 4 to 6, 60% for months 7 to 9 and 40% for months 10 to 12, a $49 plan credits the channel 49 x (3 x 1.0 + 3 x 0.8 + 3 x 0.6 + 3 x 0.4) = $411.60 of the $588 paid that year, or 70%.
The schedule is arbitrary and earns its place only when someone owns retention spend.
Book a projected lifetime value at signup
Forecasting books expected lifetime revenue to the channel at the first payment: $980 for a $49 plan at 5% churn. A team can judge a campaign in its first week instead of its twelfth month.
The cost is a churn estimate per channel, and an estimate from a 3-month-old cohort is mostly noise, so keep actual paid revenue beside the projection.
Upgrades, refunds and trials
Take a newsletter subscriber on the $49 plan who upgrades to $99 at the month 6 renewal, cancels after month 9 and gets the last invoice refunded.
| Months | Stripe activity | Invoices | Channel total after |
|---|---|---|---|
| 1 | subscription_create | $49 | $49 |
| 2 to 5 | 4 subscription_cycle invoices | 4 x $49 = $196 | $245 |
| 6 | Plan change to $99, billed at renewal | $99 | $344 |
| 7 to 9 | 3 subscription_cycle invoices | 3 x $99 = $297 | $641 |
| 9 | charge.refunded on the month 9 invoice | -$99 | $542 |
Worked example with round numbers.
The newsletter ends with $542 credited, and the opening $49 is 9% of it. First-invoice attribution would hold $49 and never see the upgrade or the refund.
A mid-cycle upgrade lands differently.
Stripe's proration documentation works through a customer who upgrades from a $10 plan to $20 halfway through the period: a $5 credit for unused time plus $10 for the rest of the period on the new plan, so $5 more is billed.
The default create_prorations creates those items without invoicing them at once, so they usually land on the next invoice. Expansion revenue then arrives one cycle late, and a daily MRR chart disagrees with an invoice-based table until it is paid.
Upgrades made through the billing portal are covered in Stripe Customer Portal attribution.
Trials and the attribution window
A free-trial subscription sits in trialing status and becomes active when the first payment arrives, so there is nothing to credit before then. The click that won the customer happened before the trial began.
A 14-day trial and a visitor who clicked 20 days before signing up put the first charge 34 days after the click, outside a 30-day window. That charge receives no channel, and every renewal after it inherits none either.
Set the window to cover the trial plus a normal consideration period.
Comparing channels by lifetime value
All-time revenue per customer rewards age. Compare cohorts of equal age, or fix one window, such as the first 6 months, and apply it to every channel.
| Cohort age | Invoices at $49 | Most one customer can have paid |
|---|---|---|
| 3 months | 3 | $147 |
| 6 months | 6 | $294 |
| 12 months | 12 | $588 |
| 24 months | 24 | $1,176 |
Ceiling for a customer who never churns or changes plan.
Plan mix distorts the comparison too.
ChartMogul's SaaS Retention Report, covering more than 2,100 SaaS businesses, found net revenue retention above 100% at 2.7% of companies with ARPA under $10 a month and at 41.1% of those with ARPA over $500.
A channel that sells your top plan will retain better for reasons unrelated to the channel, so split by plan before crediting the channel with the difference.
TrackRev's attribution benchmarks, built from Q2 2026 workspace data, report a median 12-month LTV multiplier of 2.1x for organic search and 0.8x for paid social, measured against each workspace's average customer, with a median of 12.4 months to first churn for organic search against 6.2 for paid social.
Lifetime revenue becomes a budget signal once it meets cost.
Paddle puts the SaaS benchmark for CLV to CAC above 3:1, and Skok adds that many of the best businesses recover CAC in 5 to 7 months, with profitability turning anemic past 12.
| Channel | CAC | Monthly churn | Lifetime revenue | LTV:CAC | Months to recover CAC |
|---|---|---|---|---|---|
| Newsletter sponsorships | $300 | 3% | $1,633 | 5.4:1 | 6.1 |
| Paid social | $250 | 8% | $612.50 | 2.45:1 | 5.1 |
Illustrative numbers. Recovery time is CAC divided by the $49 monthly price, before churn and gross margin.
Paid social recovers its cost a month sooner and still fails the 3:1 test, while the newsletter passes it and takes a month longer.
What TrackRev does with a renewal
TrackRev reads Stripe with a read-only restricted key and syncs charges hourly, with instant syncs from a Stripe webhook when the key allows it.
The first charge for a subscription finds its visitor from metadata.vid, then the Checkout Session's client_reference_id, then the buyer's email.
It earns credit from clicks inside the attribution window under your model: last touch (the default), first touch or linear, as the attribution model comparison lays out. The window defaults to 30 days and accepts 1 to 365.
Every later charge whose invoice carries the same subscription ID copies the first order's channel and link split, rescaled to the renewal amount. A $49 plan that becomes $99 credits $99 to the same channel from then on.
The same carry-forward runs for Paddle, Polar and Lemon Squeezy subscriptions, keyed on each provider's own subscription ID.
A Stripe charge reported as refunded drops out of the lifetime table, and a partly refunded charge loses its whole credit instead of only the refunded portion.
The Channels page lists customers, orders including renewals, lifetime revenue and average LTV per customer for each channel, as described on the channel analytics page. It sums all time with no cohort-age cut, so apply the comparison rules above.
Revenue figures need a paid plan: Starter at $39 a month, Growth at $99 or Scale at $199 (pricing). The free plan tracks links only. Setup steps are on the Stripe integration page.
A renewal whose first order earned no credit earns none either, and the first sync reaches back 30 days, so subscriptions that began before you connected arrive without their original click. Changing the attribution model affects new orders only.
Cases the join can't see
An invoice a sales rep sends by hand has no browser session behind it, so no visitor gets credit. Billing in Chargebee or Recurly sits outside the four processors TrackRev reads: Stripe, Paddle, Polar and Lemon Squeezy.
For those deals a CRM field holding the source is the better record. The click-to-charge walkthrough is in attributing Stripe revenue to marketing channels.
Found this useful? Share it.
Frequently asked questions
- No. Lifetime value is a dollar figure for a customer or a cohort, and attribution assigns that figure to a marketing channel.
- Use invoice.paid and read billing_reason. The value subscription_cycle marks a renewal, subscription_create the first invoice and subscription_update a plan change. customer.subscription.updated also fires for coupons, so revenue counted from it can be counted twice.
- Pick one window and apply it to every channel. A 6-month window gives usable data soon after launch and 12 months catches a full upgrade cycle. Annual plans need 12 months or more, since a 6-month view of an annual subscriber holds no renewal.
- They should. Leaving a refund in flatters channels that run aggressive offers, so subtract the refunded amount from the channel that earned the original charge.
- No. The free plan covers link tracking with 50 links and 1,000 tracked events a month. Revenue figures, including lifetime value by channel, start on the Starter plan at $39 a month.
- Nothing is credited until the first payment, and that payment must still fall inside your attribution window counted from the click. Lengthen the window to cover the trial, or the first charge and its renewals get no channel.
- Not automatically. Stripe issues a new subscription ID when a customer returns after canceling, so a subscription-keyed join sees a new first order and credits whichever click brought them back. Decide once whether win-backs belong to the original channel, perhaps inside a fixed win-back period, and write the rule down before comparing channels.

Written by
Founder, TrackRev.io & Contant.io
Muzahid Maruf is the founder of TrackRev.io and Contant.io. He writes about marketing attribution, link tracking, and revenue analytics for SaaS teams.
Writes about Marketing attribution · Link tracking · Revenue analytics · SaaS growth
Stop guessing where your revenue comes from.
Set up TrackRev in about five minutes. The free plan covers 1,000 events a month, no card needed.
Start free