Skip to content

Revenue attribution for SaaS: which traffic actually pays

Tie Stripe, Lemon Squeezy, Polar or Dodo payments to the traffic that earned them, pick an attribution model, and know which numbers to trust.

Karthick Published Last updated 13 min read

On this page

Revenue attribution credits each payment to the marketing source, campaign or page that brought the customer. You see revenue by channel instead of visits by channel. For a SaaS, that means connecting your analytics to your payment provider and deciding which visit gets the credit.

What is revenue attribution?

Revenue attribution, sometimes called SaaS marketing attribution when it's applied to subscriptions, answers one question: which traffic paid you? It joins two records that normally live apart: the visit (where someone came from) and the payment (what they paid).

Revenue attribution vs traffic analytics vs product analytics

  • Traffic analytics counts visits: sources, pages, campaigns, countries. It tells you what brings people in.
  • Product analytics follows signed-in users inside your app: feature use, retention, activation.
  • Revenue attribution sits between them. It takes the payment and traces it back to the visit that started the journey.

A channel can send lots of visitors and no customers. Revenue attribution shows that.

Why SaaS is harder

A shop sale usually happens in one visit. SaaS purchases rarely do:

  • Trials and delays. People sign up, try the product and pay days or weeks later.
  • Renewals. Most revenue arrives months after the first visit, with no visit attached.
  • Refunds. A payment can be partly or fully reversed later.
  • Several devices. Someone reads your blog on their phone and buys on their laptop.

Each breaks the simple "visit then purchase" link.

Why your analytics and Stripe don't agree

Your analytics tool knows sources but not payments. Your billing tool knows payments but not sources. One founder described it on Hacker News:

"We're living in this unfortunate split where tools like Google Analytics tell you where people came from, and Stripe tells you who paid, but there's no simple way to connect the two." (Lrodd, HN)

The same post adds: "UTMs and custom attribution params get lost after signup. Stripe doesn't track attribution."

There's a second problem: "direct" inflation. A customer finds you through a Reddit thread, comes back two weeks later by typing your URL, and pays. A tool that credits the last visit says "Direct". The Reddit thread that did the work gets nothing.

How revenue attribution works, step by step

1. Capture the visit

Record where each visit came from: referrer, UTM tags (utm_source, utm_medium, utm_campaign) and landing page. Tag your own links consistently. Newsletter and newsletter become two rows in most tools, so pick lowercase names and keep a list. Never put an email address or customer ID in a UTM tag; links get shared and logged.

2. Carry an identifier into checkout

The payment provider doesn't know which visit started checkout. You have to tell it. When the visitor starts checkout, read an identifier in the browser (a visit ID, or the UTM values themselves) and pass it to your server. Your server adds it to the checkout's metadata.

Do this when checkout starts, not on the thank-you page, which may belong to a later visit.

3. Match the payment to the visit

When the payment succeeds, the provider sends a webhook. The payment carries the metadata you added. Your system, or your tool, looks up the visit by that identifier.

4. Credit a source under a model and lookback window

If the customer visited more than once, a model decides which visit gets credit. A lookback window decides how far back to look. Both should be explicit settings, not hidden defaults.

5. Handle renewals, refunds and payments you can't match

  • Renewals: credit them to the source that won the customer. The renewal was earned by whatever brought them in.
  • Refunds: subtract them, and credit them against the original payment's source.
  • No match: keep the payment in your totals as "unattributed". Don't assign a guess.

Attribution models for small SaaS

An attribution model is the rule that decides which visit gets credit when a customer visited more than once.

Last non-direct

Credit the most recent visit before the payment that didn't come straight in (typed URL or bookmark). If every visit was direct, the payment counts as Direct.

This fixes the "direct" inflation problem. It shows you what closes sales.

First touch

Credit the earliest visit in the lookback window. This shows you what finds customers in the first place. It's useful for judging content and SEO, which often start journeys but rarely finish them.

Multi-touch models

Linear models split credit evenly across visits. Time-decay models give more to recent visits. Position-based models weight the first and last.

They pay off with many paid channels and enough data to trust small differences. Most small SaaS teams aren't there yet; two simple models compared side by side teach more.

Choosing a lookback window

The window should cover your normal time from first visit to first payment. If most customers pay within a week of signing up, 30 days is plenty. If buyers research for months, go longer. Too short, and early sources lose credit. Too long, and an old visit gets credit for a sale it had little to do with.

Check how long your trials take to convert and set the window a bit beyond that. A window longer than the checkout visit only helps if earlier visits are linked to the buyer by a stored identifier, such as a first-party cookie.

Worked example: one customer, three visits, two models

This is an illustrative example with made-up numbers, not customer data.

A customer makes three visits before subscribing at $29 a month:

VisitWhenSource
1Day 1Google organic search, lands on a blog post
2Day 12Your newsletter (utm_source=newsletter)
3Day 15Types your URL, starts checkout, pays $29
  • Last non-direct credits the newsletter. Visit 3 was direct, so the model skips it.
  • First touch credits Google organic search.

Now follow the subscription. The customer renews for five more months, then asks for a refund on month 3. Under either model, every renewal inherits the first payment's source:

Amount
Six payments × $29$174
Refund of month 3−$29
Net revenue credited to the source$145

Same $145, two answers, neither wrong: the newsletter closed the sale, search found the customer.

One catch: this example needs the three visits linked to one person across 15 days. That takes a stored identifier, such as a first-party cookie. Without one, only visit 3 is linked to the payment, and it would count as Direct.

The metrics that matter

MetricWhat it tells you
Revenue by source, campaign and landing pageWhere money comes from (payments minus refunds)
Paying customersHow many distinct customers each source brought
Conversion rateFirst-time buyers ÷ unique visitors
Revenue per visitor (RPV)Revenue ÷ unique visitors, for the same period and segment
LTV by first sourceAll revenue so far from customers first won through that source
UnattributedThe share of revenue you couldn't link to a visit

Revenue per visitor is the fairest way to compare sources of different sizes.

Three ways to set it up

DIY: UTMs into Stripe metadata

The cheapest route. Read UTM values in the browser when checkout starts, send them to your server, and add them to the Checkout Session's metadata. For subscriptions, add them to the subscription's metadata too, so renewal invoices carry them. Then export payments and group by source in a spreadsheet or SQL.

Stripe Payment Links also accept utm_source, utm_medium, utm_campaign, utm_content and utm_term in the link URL and pass them to your redirect URL (Stripe docs, accessed 22 Oct 2026). Stripe warns never to put sensitive information such as card or bank details in metadata (Stripe docs, accessed 22 Oct 2026).

What DIY doesn't give you: multiple visits, models, refunds netted against the right source, or an unattributed line. You build those yourself.

GA4 + Stripe

Google Analytics 4 can record ecommerce purchase events (Google Analytics help: recommended events, accessed 22 Oct 2026). To use it for SaaS revenue, you send purchase events with amounts, usually from your server after Stripe confirms payment, and handle renewals and refunds yourself. It works, but it's a real project for a small team. As the same Hacker News post puts it, "wiring together GA, BigQuery, and Stripe is way too much for a small team" (HN).

A revenue-attribution analytics tool

These tools sync payments from your provider and do the matching for you. When comparing them, check:

  • Payment-provider sync for the provider you use, not just an events API.
  • Renewals and refunds: do renewals keep their source? Are refunds subtracted?
  • Unattributed handling: are unmatched payments shown, or quietly assigned?
  • Model choice: can you compare at least two models? Is the lookback window a setting?
  • Privacy default: cookieless or cookie-based by default, and what each mode can link.
  • What the price is based on: sites, team members or event volume.

How traffic.cx does it

traffic.cx is one tool built for this. You connect Stripe, Lemon Squeezy, Polar or Dodo Payments, or send payments through the Payments API. Your checkout passes a pageview ID in its metadata.

It offers two models, last non-direct (default) and first touch, with a toggle. The lookback window is 90 days by default and can be set from 7 to 365 days. In the default cookieless mode, a payment links only to the visit where checkout started; a longer lookback needs cookie mode (same browser only). Renewals and repeat customers inherit the attribution of the customer's first payment. Refunds are subtracted on the day they happen and credited to the original payment. Payments it can't match stay in totals as "Unattributed" (how it works).

Plans start at $5 a month for 5,000 events, as of 22 October 2026, with unlimited sites and team members on every paid plan (pricing). For side-by-side comparisons, see traffic.cx against Plausible Analytics and DataFast.

See which traffic pays. Start a 7-day trial, no card needed (up to 10,000 events). Connect Stripe, Lemon Squeezy, Polar or Dodo from Settings → Revenue. Start your trial

What to trust, and what not to

Attribution describes the recorded journey; it doesn't prove a campaign caused a purchase.

Unattributed is not a failure

An unattributed payment is real revenue with no visit you can prove. Showing it keeps your total equal to what your provider received. Common causes, in order:

  1. No identifier reached the payment. Check the payment's metadata in your provider's dashboard.
  2. The visit wasn't recorded (ad blocker, missing tracker on that page).
  3. The identifier came from a different visit, such as a thank-you page on another device.
  4. The buyer came back on a later day or another device with no stored identifier.
  5. The visit fell outside the lookback window.

Direct vs Unattributed

They're different. Direct means a visit was matched, and it had no source to credit: a typed URL or bookmark. Unattributed means no visit was matched at all. A high Unattributed share usually means a broken handoff into checkout.

Cookieless analytics avoids storing an identifier in the visitor's browser. The tradeoff: it can link a payment to the visit where checkout started, but not to a visit on an earlier day. traffic.cx's default cookieless mode rotates visitor identity daily, so it doesn't build a journey across days (docs). Other vendors describe the same tradeoff for their cookieless scripts (DataFast docs, accessed 22 Oct 2026).

A cookie mode links visits across days on the same browser, so a long lookback window can do its job. Nothing links a different device. In the worked example above, cookieless mode would credit Direct, and cookie mode would credit the newsletter.

Linking payments to visits goes further than counting pageviews. Whether you need consent depends on your setup, the mode you use and where your visitors are. This isn't legal advice; check with your adviser before switching on cookie-based tracking. For what traffic.cx collects in each mode, see its privacy notice.

A 30-minute setup checklist

  1. Install your analytics script on every page, including pricing and checkout (getting started).
  2. Verify that a test visit shows up with the right source.
  3. Agree on UTM naming: lowercase, underscores, one shared list.
  4. Connect your payment provider (or plan your webhook handler for DIY).
  5. In your checkout code, read the visit identifier when checkout starts.
  6. Add it to the checkout's metadata, and to the subscription's metadata for subscriptions.
  7. Open a tagged link, such as ?utm_source=setup-check&utm_medium=email&utm_campaign=test.
  8. Complete a test payment in your provider's test mode.
  9. Confirm the payment appears once, with the expected source and campaign.
  10. Test a refund and check that revenue drops on the refund date.
  11. Pick a default model and lookback window, and write them down.
  12. Check the unattributed share weekly for the first month.

FAQ

What is revenue attribution?

Crediting each payment to the source, campaign or page that brought the customer. It lets you compare channels by revenue rather than visits.

What is a revenue attribution model?

The rule that decides which visit gets credit when a customer visited more than once, such as last non-direct or first touch.

First touch or last touch: which should a small SaaS use?

Start with last non-direct to see what closes sales, then check first touch to see what finds customers. Compare both before moving budget.

How do I know which marketing channel produces my paying customers?

Carry a visit identifier from your site into checkout, then match each payment back to that visit. Do it yourself with UTMs in Stripe metadata, or use a tool that syncs your payment provider.

Why do customers who found me weeks ago show up as "direct"?

Their last visit was typed or bookmarked. Last-touch models credit it unless they skip direct visits, and linking visits across days needs a stored identifier.

Doesn't Stripe show where customers came from?

Not by itself. Stripe records payments, not marketing sources. You pass source data into checkout metadata or use a connected analytics tool.

What should a revenue attribution report show?

Revenue, paying customers, conversion rate and revenue per visitor by source, campaign and landing page, plus an unattributed line.

What is revenue per visitor?

Revenue divided by unique visitors, for the same period and segment.

Should renewals be credited to the original source?

For subscription businesses, usually yes. The renewal was earned by whatever acquired the customer.

Is "how did you hear about us?" enough?

It's a useful cross-check, but answers are incomplete and fuzzy. Use it alongside tracked attribution.

It depends on your setup and where your visitors are. Linking payments to visits is more than counting pageviews, so check with your adviser.

See revenue by source on your own site

Start a 7-day trial, no card needed, with up to 10,000 events.

Start your trial · See the live demo · How revenue attribution works · Track a UTM campaign through to revenue