Cross-domain checkout: keep the source of every sale
By Devendra Variya, co-founder of Virling. Published 2026-11-05.
To keep the traffic source of a sale when checkout is on another domain, pass the visitor ID into checkout before the buyer leaves your site. Cookies stay on the domain that set them, so without that ID the payment arrives with no link to the visit, and your best channel looks like it earned nothing.
Why the source gets lost
Your analytics script sets a first-party cookie on your domain. When the buyer moves to checkout.stripe.com, a hosted Paddle checkout or a store on another domain, that cookie does not travel with them. The provider records who paid. Your analytics records a visit that ended at checkout. Nothing connects the two, so the sale lands in Direct or stays unattributed.
The fix depends on where checkout lives. There are three cases.
Case 1: checkout on a subdomain
If visitors move from example.com to app.example.com or shop.example.com, you may have nothing to do. A first-party cookie set on the registrable domain, example.com, is shared with its subdomains, so the visitor keeps the same ID. Check that the same script runs on both and that your tool counts them as one site.
Case 2: checkout hosted by your payment provider
This is the most common setup. Read the visitor ID on your site and hand it to the provider when you create the checkout:
- Stripe Checkout: set
client_reference_idon the Checkout Session, or put the ID inmetadataon your own PaymentIntent. See how to track Stripe revenue by traffic source - Stripe Payment Links: add
client_reference_idto the link when the visitor clicks it - Paddle: pass the ID as custom data. See how to track Paddle revenue by traffic source
- Shopify: orders with no known source land in Direct. See why Shopify orders show up as Direct
If your checkout code can run before the analytics script has loaded, wait for the script first, or the ID will be empty.
Case 3: a second domain you own
If your marketing site is example.com and your app is example-app.net, the cookie is not shared, because they are two registrable domains. Read the visitor ID on the marketing site, add it to the link into the app, keep it there, and pass it to checkout when the visitor pays. The sale then joins to the visit that started on the first domain.
Stop checkout from becoming a new source
A second problem shows up after payment. The buyer returns from the checkout domain to your thank-you page, and a tool that treats every outside domain as a referrer starts a new visit from the payment provider. Now the provider gets credit for the sale. Exclude checkout and sign-in domains from your referrers, so a return from checkout continues the same visit.
Links that cannot carry the ID
A payment link opened from an email, a QR code or another site never passed through your page, so it has no visitor ID. Expect some unattributed revenue from these. Report it as its own line rather than folding it into a channel, and use UTM tags on the page you send people to, instead of sending them straight to the payment link, whenever you can.
How to check it works
- Open your site from a tagged link in a private window, for example with
utm_source=test - Go through checkout in your provider's test mode
- Find the payment in the provider's dashboard and confirm the visitor ID is on it
- Confirm the sale shows the source you tagged, not Direct
Doing it with Virling
Virling sets its virling_vid cookie on your registrable domain, so subdomains share it. Stripe Payment Links on your pages get the ID added when clicked, with no code. For other checkouts you read the cookie on your server or call window.virling.vid() in the browser; the checkout guide has the code for each provider. A return from Stripe, Dodo Payments, Polar, LemonSqueezy and Paddle checkouts never starts a new session, and you can add your own domains under Same-visit domains in Site settings. The dashboard shows what share of payments matched a visit, so you can see a broken checkout quickly. You can look around the demo first.
Frequently asked questions
Why does my analytics lose the source at checkout?
Cookies belong to one domain. When a buyer moves to a checkout on another domain, your analytics cookie stays behind, so the payment has no link to the visit unless you pass the visitor ID into checkout.
Do subdomains need cross-domain tracking?
No. A first-party cookie set on example.com is shared with app.example.com and shop.example.com, so the same visitor ID works on all of them.
How do I pass the visitor ID to Stripe Checkout?
Set client_reference_id on the Checkout Session, or put the ID in metadata on your own PaymentIntent. With Virling, Stripe Payment Links on your site get the ID added automatically when clicked.
Can a payment link in an email be attributed?
Not from the visit, because a link opened from an email, a QR code or another site carries no visitor ID. With Virling, a Stripe payment can still be matched by a hash of the payer's email if that visitor shared it before.
Will the checkout page show up as a referrer?
It can in tools that treat every outside domain as a new source. Virling treats a return from Stripe, Dodo Payments, Polar, LemonSqueezy and Paddle checkouts as the same visit, and you can add your own domains under Same-visit domains.
Start a 14-day free trial at app.virling.com.