FOUNDATIONS

Revenue attribution: connect website visits to payments

Learn how revenue attribution joins visits to verified payments, chooses a credit rule, and keeps missing sources, refunds and currencies honest.

What revenue attribution actually tells you

Revenue attribution assigns credit for a recorded payment to an eligible marketing interaction under a stated rule. It answers “Which recorded source gets credit?” It does not prove that the source caused the sale, and it cannot reconstruct a journey that was never observed.

For a small SaaS, the useful starting point is not a complicated model. It is a reliable relationship between three records: a consented acquisition touch, the account or checkout associated with it, and an authoritative payment. Keep those records separate so a missing browser event cannot erase genuine money, and a repeated pageview cannot manufacture a purchase.

Keep the browser journey and financial evidence separate

A click on Upgrade shows intent. A checkout page opening shows another step. Even a return to a success URL is not sufficient evidence that money settled successfully. The financial record should come from your trusted payment integration, with the status, currency, amount and provider identifier retained.

Stripe supports asynchronous webhook delivery. Verify signatures and design processing for repeated events rather than incrementing a sales counter on every request. The durable payment identifier, not the number of deliveries, identifies a payment. This is a financial integrity concern before it is an attribution concern.

Once the payment exists, attribution is a second operation. If no trustworthy association exists, keep the payment and mark its source as unknown. You can still reconcile money while you investigate the missing join.

A worked example: one customer, three possible stories

Consider a fictional customer who first arrives from a tagged newsletter, returns through a search result, and pays after opening a bookmark. All dates, sources and amounts below are synthetic. Assume each eligible visit was recorded with permission and the payment can be associated with the same customer.

A first-touch rule credits the newsletter. A last-touch rule may credit the final Direct visit. A last-non-direct rule may credit search. These are different questions applied to the same history, not three contradictory bank balances. If your system records only the final session, it cannot truthfully display the earlier newsletter merely because that explanation feels plausible.

Synthetic journey, one USD payment
Day 1   newsletter  -> eligible recorded touch
Day 6   search      -> eligible recorded touch
Day 9   bookmark    -> recorded Direct visit
Day 9   payment     -> USD 40 verified receipt

First touch: newsletter   Last touch: Direct
Last non-direct: search   Total money: still USD 40

Write down your attribution contract

Choose the entity being measured: a browser session, an authenticated account, or a customer. A session identifier should not be described as a person across devices. Then choose which touches qualify, how far back to look, which timestamp ends the window, and how to handle Direct visits and missing information.

For example: “Credit the earliest recorded, consented touch in the 30 days before payment; otherwise use Unattributed.” Specify whether a later refund revises that payment’s credited amount and whether a late-arriving touch is allowed to change historical reports. Freezing a source when a payment is accepted makes comparisons easier to reproduce, but it is a design choice to document, not a universal standard.

Google Analytics also separates acquisition dimensions by scope. A first-user source and a session source are not interchangeable. Before comparing any two products, align their identity, window and credit rules rather than expecting identical rows.

Connect checkout on the trusted server

An opaque association identifier can carry the link between the permitted web journey and checkout. It should not be an email address, a full browsing history, or a credential. Your application must determine the account, project and allowed price on the server; a visitor-controlled value must never decide who owns the revenue.

With one-time Stripe Checkout, Session metadata and PaymentIntent metadata are separate. To attach a value to the PaymentIntent created by Checkout, use the payment_intent_data.metadata parameter. Do not assume arbitrary metadata automatically propagates between every Stripe object. Subscription invoices and renewals need their own explicit association design.

If the identifier is absent because consent was denied or the session ended, omit it. Guessing or silently fingerprinting someone to make the chart more complete is not a repair.

Compare channels using a complete denominator

Suppose fictional source A has 100 observed visitors and USD 200 in attributed receipts, while B has 20 and USD 120. Receipts per observed visitor are USD 2 and USD 6 respectively. B looks more valuable on this narrow measure, but that does not establish profit or tell you what would happen if you tripled its volume.

Label whether receipts include renewals, subtract refunds, and exclude tests. Use the same currency and conversion window. Show Unattributed beside named channels, not in an invisible excluded bucket. A channel report covering only the easiest-to-track customers can otherwise look precise while omitting the people it most needs to explain.

The first useful acceptance test

Test one permitted journey from a known campaign through a successful payment and partial refund. Repeat the webhook delivery and verify that money is not duplicated. Then repeat without a visitor association: the payment should remain visible and its source should remain unknown. Finally, compare the provider’s payment identifier and amount with the analytics record.

The related reconciliation guide covers the money checks in detail; Direct versus Unattributed explains the two different missing-information cases. Start with those foundations before experimenting with more attribution models. A modest, explainable report is more actionable than a sophisticated one with an unreliable join.

References

Educational guidance. Worked examples are illustrative, not customer results or a promise of traffic, revenue or search visibility. Check the cited sources and your own implementation.
Explore the synthetic demo →