Attribution

Why your payment dashboard cannot show where buyers came from

Ownlytics team · · 6 min read

Your payment dashboard can't tell you where buyers came from because the visit happened on your site, before the buyer ever reached the payment page, and the processor never saw it. It records the customer, the amount and the product. The tweet, search or newsletter that sent them is only known to your own analytics, so something has to carry it across.

A payment dashboard

Revenue$2,226
Customers46
Where they came fromnot recorded

With Ownlytics

Revenue$2,226
Customers46
Where they came fromx.com 9 · google 14 · newsletter 7

Fig.Same sales, one extra column. That column is the point. Sample data, not a real site.

What the processor actually sees

When a buyer pays, the processor records details about the payment itself: the amount, the product, the customer's email, the time, the card result, and whether it was a renewal or a refund.

What it does not record is the browsing that came first. The pages read, the referrer, the campaign tag and the number of visits before buying all sit in your analytics tool, in a different system, with no shared identifier.

Think of two notebooks. One lists every purchase. The other lists every visit. Nothing written in either notebook tells you which entries are the same person.

Why that matters in practice

Without the join, you can answer "how much did we make?" but not "what worked?". You may end up crediting the wrong thing, for example thanking the channel with the most visitors rather than the one whose visitors paid. We walk through that difference in revenue per visitor.

It also hides slow decisions. A buyer might read your site on Monday and pay on Friday through a payment link in an email. The payment shows "email". The real introduction was something else. You need both ends of the story.

The fix: give the payment an identifier

The solution is not a smarter dashboard. It is carrying one id across the gap. In Ownlytics the script gives each visitor a first-party id on your domain, and when that id reaches the payment, the sale is credited to the visit, source and campaign that produced it. The revenue docs describe the three routes:

  1. Payment links on your pages get tagged by the script automatically.
  2. Server-created checkouts receive the visitor and session ids as metadata that you pass in.
  3. Success pages link the payment when the buyer returns with the provider's checkout id in the URL.

For Stripe, that means client_reference_id on Payment Links and metadata on Checkout Sessions, and subscription_data.metadata so renewals keep the visitor. The Stripe-specific guide shows each case. Polar, Dodo Payments and Creem each have their own setup, described in the revenue docs. The Stripe and Polar pages show the result.

Example (made-up numbers for illustration)

Here is what the same month looks like in two views, for an invented store with 20 sales at $40.

ViewWhat you can say
Payment dashboard only"20 sales, $800, average $40, 2 refunds."
Payment dashboard joined to visits"9 sales from search, 6 from a newsletter, 3 from social, 2 unattributed. Newsletter has the highest revenue per visitor."

Same money, very different next steps. The first view says to keep going. The second says where to put the next hour.

The common workarounds, and where they break

Founders usually try one of these first.

Ownlytics does use a form of timing as a last resort: when no visitor id arrives, it checks whether exactly one visitor clicked a checkout link for that provider in the three hours before the sale. These matches are labeled estimated, and real metadata replaces them when it arrives. When several people clicked, it waits 30 minutes and credits only the one who came back from the payment page, or the only one who clicked in the last 30 minutes. Otherwise the sale stays unattributed. The reasoning is in sources and attribution.

Ownlytics alertsbot · online
New sale · $49Dodo Payments · India
Source: x.com → /blog/setup-guide
3 visits over 12 days
New sale · $9Polar · Germany
Source: google.com → /pricing

Fig.A sale alert in Telegram: the source and the page, not just the amount. Sample data, not a real site.

What to check first

  1. Look at how your buyers reach payment: a link on your page, or a checkout your server creates?
  2. Test one purchase end to end, if your provider has a test mode.
  3. Open the sale and confirm it shows a source and a landing page.
  4. Look at the share of unattributed sales. A big share means the wiring is incomplete.
  5. Only then compare sources.

When this isn't worth solving

If you sell mostly through direct invoices, calls or marketplaces where the payment never touches your own site, there's no visit to join. And if you make only a few sales a month, reading each sale by hand tells you more than a ranking would. Also expect gaps: cross-device purchases and cleared cookies will always leave some sales without a source. Our post on direct traffic and dark social explains one of the main causes.

A payment dashboard answers "who paid". To answer "what brought them", the payment has to carry an id from the visit.

Next step

To see what a sale tied to its visit looks like, the demo shows a sample site with sales attached to sources.

FAQ

Can Stripe tell me the referrer of a sale?

Not by itself. It records payment details, not your site's referrer. You pass the source in through link parameters or metadata, as described in the Stripe guide.

Do I need to change my checkout code?

Not for tagged payment links, which the script handles. For checkouts your server creates, you add the visitor and session ids to the metadata, which is a small change.

What happens to refunds?

In Ownlytics, refunds come off the same source as the original sale, so a channel's numbers aren't inflated by money you gave back.

Does this work for subscriptions?

Yes. The first paid invoice is credited to the checkout's visitor, and renewals inherit it.

See the live demo · View pricing

Keep reading