Skip to main content

Stripe

Everything else

When there is nowhere to put metadata and no return URL, match on e-mail.

Some flows have nowhere to put metadata and no return URL to read: an invoice you send from the Stripe dashboard, a subscription created by a third-party tool, a reseller, a payment taken over the phone. The payment still reaches your dashboard — it simply arrives with no visitor attached.

If the customer does land back on your site, use a Payment Link with session_id — that is stronger than anything on this page. What follows is for when they do not.

Match on the e-mail address

Tell us the address the customer paid with, and we match it against the payment Stripe reports.

window.truestat("payment", { email: "customer@example.com" });

Fire this on your own success page, with the address used at checkout.

Why this is weaker, and when it is enough

The match needs the address to be identical. A customer who pays with a work address and signed up with a personal one stays unattributed, and there is no way for us to know the two are the same person.

It also cannot tell one visit from another. Metadata carries a session id as well as a visitor id, so it can say which visit produced the sale; e-mail matching can only say which person did.

Firing it twice is safe. Only a payment that is still unattributed is ever filled in, so a success page the customer reloads changes nothing after the first time.

What it cannot do

It cannot attribute a renewal. The success page fires once, when the customer first buys; the renewals that follow arrive from Stripe with no e-mail event beside them. Subscriptions attributed this way show their first payment against a channel and their renewals as unattributed.

That is the strongest argument for metadata where you have the choice: it carries forward on its own, for the life of the subscription. Both the Checkout Session and the PaymentIntent API pages set it.

Was this page helpful?

Last updated September 9, 2026