Cross-domain tracking: the checkout-domain trap

When your funnel crosses to an external checkout, the session dies at the border and your best-converting clicks get credited to the checkout domain instead of the ad that earned them. How to spot it, fix the GA4 side and the ads side, and stitch the data when you don't control the other domain.

Kay Vink
Kay Vink

Your ad traffic looks healthy and almost none of it converts, while direct/(none) keeps swallowing sales you know came from ads. The usual cause is a domain hop: your funnel sends buyers to an external checkout, and because cookies are scoped to one domain, the session resets at the border, so the conversion credits the checkout domain instead of the ad that earned it, with no error thrown anywhere. The 2-minute check: click through your own funnel and watch whether ?_gl= survives onto the second domain. Below are the three signatures that confirm the leak, then the fix on the analytics side and the ads side.

#The checkout-domain trap: a lived example

A ticketing business we work with ran ads to their marketing site while every purchase happened on their ticketing provider's checkout domain, the standard setup for ticketing, booking, and hosted-payment stacks. The breakage was invisible from inside any single report: the marketing site showed healthy ad traffic that mostly "didn't convert"; the analytics showed a swelling direct/(none) bucket and their own checkout domain as a top "referrer" of purchases; the ad platforms, seeing few conversions they could claim, optimized toward whatever they could see. Their sessions were breaking at exactly the moment of highest intent, the handoff to checkout, so the ads were flying blind on precisely their best converters. The magnitudes here are illustrative of the pattern, but the shape is the one this setup always produces: direct/(none) claiming a third or more of purchases that were really ad-driven, the checkout domain sitting in the top referrer rows, and the break running undetected for months because no single report owned it.

The trap generalizes: nothing errors, every individual report looks plausible, and the pattern only appears when you know the three signatures below. Discrepancies like this are normal and diagnosable (the position the whole Conversion tracking & signal quality takes), and this one is among the most mechanical to fix.

#How a domain hop breaks the session

Cookies don't cross domains. That's the entire failure in four words. GA4's client ID lives in a first-party cookie scoped to yoursite.com; when the visitor lands on checkout.example-pay.com, that cookie is unreadable, so analytics mints a new client ID: new user, new session, no memory of the ad click. Everything identifying dies at the border at once:

  • The client ID. The purchase belongs to a "new" user whose source is the referring site: your own funnel, as a referral.
  • Click IDs. The gclid/fbclid captured on the landing domain don't follow (Click IDs: what gclid, fbclid, and wbraid do), so ad-platform matching loses the thread too.
  • Consent state. The consent choice recorded on domain one isn't known on domain two, which can suppress tracking there entirely.

Subdomains are the benign case. shop.example.com and example.com can share a cookie scoped to the parent domain, so the session survives the hop. This is also where a first-party pixel earns its keep: Buron's sets its cookie at the root domain (.example.com), so it persists across shop., checkout., and www. on its own, with no linker and no cross-domain config to maintain. The real trap is genuinely different domains: a separate checkout domain that isn't a subdomain can't share a cookie by browser rule, so that case still needs the client ID passed across by hand (the rest of this page).

#Diagnose it: the three signatures

Any one of these says cross-domain loss; two confirm it.

  • A direct/(none) spike concentrated at the money step. Purchases and high-intent sessions over-index as direct while upper-funnel attribution looks normal. Where to look: conversions by session source/medium, filtered to the conversion event.
  • Self-referrals. Your own domains appear as referral sources of each other: the checkout domain "referring" purchases, or your main site "referring" traffic to itself when visitors return from checkout. Where to look: the referral report; your own hostnames shouldn't be in it.
  • The checkout domain inside conversion paths. Attribution paths show ad click → (session ends) → referral from checkout domain → conversion instead of one continuous session. Where to look: advertising/path reports, and hostname as a secondary dimension.

#The fix, GA4 side

Cross-domain measurement is one admin setting plus one parameter to respect. In GA4: Admin → Data streams → your web stream → Configure tag settings → Configure your domains: list every domain in the journey (main site, checkout, booking widget host). GA4's tag then appends the _gl linker parameter to links between the configured domains, carrying the client ID (and ad click IDs) across; the destination reads it and continues the same session instead of starting one. Add the checkout domain to the unwanted- referrals list too, so returns from it never count as new referral sessions.

Then protect the parameter, because the linker only works if it survives the hop: redirect chains between your domains can drop the query string exactly like they drop UTMs (UTM parameters: the reference has the registry), and checkout handoffs that submit as a POST or rebuild the destination URL discard it. Test with the funnel, not the docs: click an ad, walk to payment, and watch ?_gl= in the URL bar at each step.

#The fix, ads side

GA4's linker fixes analytics; the ad platforms need their own identifiers to make the same trip. The gclid/fbclid captured on the landing domain must reach the domain where conversion tags fire, via the linker's decoration, your own parameter passthrough, or server-side capture at landing (Click IDs: what gclid, fbclid, and wbraid do covers what each ID unlocks). On Google specifically, the conversion linker behavior in your tagging setup exists for exactly this case (Google Ads conversion tracking: setup and the 7 ways it silently breaks). Two edge cases that undo everything: payment processors that return the visitor through a stripped redirect, and consent banners re-prompting on the second domain, where a declined or unasked consent suppresses the conversion tag no matter how well the IDs traveled (Consent Mode v2 without losing your signal).

#External checkouts you don't control

When checkout belongs to a ticketing or booking SaaS, you fix what you can reach and stitch the rest. Fixable is your side of the hop: linker configuration, passing parameters their platform documents, and whatever analytics injection they support (many accept a GA4 measurement ID or a pixel). Not fixable client-side: their redirects, their consent surface, their DOM. Then the durable answer is matching the records instead of chasing cookies: capture the click and identifiers at landing, let the platform's order webhook or export carry the purchase with an order ID or email, and match the two server-side. Server-side tracking: what it fixes, what it costs, and whether you need it covers the collection pattern, and Identity resolution: how user stitching actually works the stitching pass that makes one customer out of the fragments.

#Verify the fix

Three checks, then a routine: walk the funnel and watch _gl survive every hop on every entry path (ad landing pages included, mobile included); confirm the three signatures recede over the following weeks (direct/(none) share at the conversion step falling, self-referrals gone, continuous paths in attribution reports); and re-run the pass after any checkout-provider, redirect, or consent change, as part of The conversion tracking QA checklist: test it like you'd test code. The receipt looks the same everywhere (illustrative magnitudes): direct/(none) share at the conversion step dropping from the high thirties to the low teens within a couple of weekly cohorts of the linker deploy.

Cross-domain loss went unnoticed in the story above because nobody's job was to look for its signatures. That's the general lesson: session breaks are detectable (direct/(none) inflation at the money step, self-referrals, checkout-domain credit drift), but only if something watches for them, and a one-time fix drifts back the next time a checkout provider changes a redirect. Buron watches for exactly these shapes continuously across your connected data, so a checkout-domain regression surfaces as a finding within days, not as a quarter of blind bidding. And when your platform numbers already disagree, cross-domain loss is one failure mode of several, with Why your GA4 and Google Ads conversions don't match as the full triage.

Frequently asked questions

Why are my conversions showing as direct or referral?

Usually because the session broke between the ad click and the conversion. A hop to another domain (external checkout, booking widget, payment page) resets the session, so the conversion credits the checkout domain as a referral or lands in direct/(none) instead of the campaign that earned it.

Does GA4 track across domains automatically?

Across subdomains, yes: the GA4 cookie is set on the parent domain, so shop.example.com and example.com share a session. Across different domains, no: you must configure cross-domain measurement in the data stream's tag settings so the _gl linker parameter carries the session across.

What is the _gl parameter?

The _gl parameter is Google's cross-domain linker: a short-lived token appended to links between your configured domains, carrying the client ID (and click IDs) so the destination domain continues the same session instead of starting a new one. If it's stripped by a redirect, the session still breaks.