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.

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 → conversioninstead 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.