Revenue Not Attributed to Your Ads, but Every Tag Fires in GTM? Check the Click ID (2026)
Short version
The whole problem in under a minute
Watch the test, then read on for the full checklist and the fix.
Revenue isn't being attributed to your ad platforms, yet GTM debug shows every tag firing perfectly? Check whether the ad click ID survives the trip to checkout.
Everything looked fine
I had exactly this on a recent client audit. Google Ads and Meta were reporting far fewer sales than the store was making.
So I opened GTM Preview and made a test purchase. Page view, add to cart, begin checkout, purchase: every tag fired, with the right value and the right transaction ID. On paper, the tracking was perfect.
But a test purchase in debug mode doesn't behave like a real buyer. A real buyer arrives from an ad, so the URL carries a click ID: gclid from Google, fbclid from Meta. That ID is what ties the sale back to the ad. So I ran the test again, this time the way a real ad visitor arrives.
What happened when I added gclid and fbclid
The ads sent people to a landing page on the brand's main domain. The Buy Now button went to a store on a completely different domain, not a subdomain, run on a separate ecommerce platform. Each site had its own cookie banner.
That detail matters. If the store were store.brand.com, both sites could share first-party cookies set on .brand.com, and the click ID would carry over on its own. With two separate domains, the browser keeps their cookies apart, so the only way the click ID reaches the store is in the link URL.
I opened the landing page with fake click IDs, picked an option on the banner, clicked Buy Now, and checked the store URL:
Landing page:
https://www.example.com/?gclid=TEST_G&fbclid=TEST_F
| What I did on the landing page banner | Store URL after Buy Now | gclid | fbclid |
|---|---|---|---|
| Accepted | store.example.org/season-pass?_gl=1*k2x9… | ✓ (inside _gl) | ✗ |
| Rejected | store.example.org/season-pass | ✗ | ✗ |
| Ignored | store.example.org/season-pass | ✗ | ✗ |
fbclid never made it to the store, whatever I chose. gclid only made it if I accepted. Then the store showed a second banner from a different account. If I ignored that one, which most people do one click before paying, the store's marketing tags stayed blocked, even though I'd already said yes.
The tags were firing. They just had no click ID to send, so the platforms couldn't credit the ad.
Try it yourself. Pick what the visitor does with each banner, then switch to After the fix:
Why debug mode didn't catch it
- No click ID. A test purchase starts with a clean URL, so there's nothing to lose.
- You accept everything. Testers click Accept on every banner. Real visitors ignore or reject a lot of them.
- "Tag fired" isn't "conversion attributed". GTM shows the request went out. It doesn't show whether Google or Meta could match it to an ad click.
Step by step: where does your click ID drop?
Run this with your own landing page and store open. Each step follows the visitor one hop further, so the first No shows where the click ID gets lost.
- 1Does a test purchase fire every tag in GTM Preview?Run a test order in Preview on the store container. Look for the purchase tags for Google Ads, Meta and GA4.
- 2Does the landing page set a consent default before any tag fires?
- 3Accept the banner, click Buy Now. Does the store URL contain _gl?
- 4Does the store URL also contain fbclid=TEST_F?
- 5Did the store show a second cookie banner?
- 6Now reject the banner instead. Does the store URL still contain _gl?
- 7Does the store’s Conversion Linker fire on the first store page?
- 8Does the Meta pixel fire on that first store page and set the _fbc cookie?
- 9Does Events Manager show the purchase from both Browser and Server, deduplicated?
Checklist
Interactive checklist
Cross-domain consent and attribution audit
Tick items as you verify them. Progress is saved in this browser.
Consent
0/3
- Site / store team
- Site / store team
- Site / store team
Click ID handoff
0/3
- Tag manager / ads
- Tag manager / ads
- Site / store team
Conversions
0/3
- Tag manager / ads
- Tag manager / ads
- Site / store team
Test
0/1
- Tag manager / ads
How to fix it
1. One consent decision for both domains. Use one CMP account for the landing page and the store, or turn on your CMP's cross-domain consent sharing. Accepting once should mean no second banner.
2. Load the banner before the tag manager. Put the CMP script in <head> above GTM, with no defer or lazy-loading, and exclude it from Cloudflare Rocket Loader (data-cfasync="false"). Turn on Consent Mode so a default exists before any tag fires. (My consent audit post shows how to verify it.)
3. Carry gclid across domains with the Conversion Linker. The Conversion Linker tag reads gclid from the URL and saves it in a first-party cookie. At purchase, the Google Ads conversion tag reads that cookie. The store is a different domain and can't read the landing page's cookies, so:
- Fire a Conversion Linker on All Pages in both containers, landing page and store.
- On the landing page's linker, turn on Enable linking across domains and add the store domain (
example.org) to Auto Link Domains. Buy Now links then carry the click in a_glparameter, and the store's linker reads it. - Turn on Enable URL passthrough on the linker (or set
url_passthroughtotrueon the Google tag). The click information then still travels in links when consent is denied, without cookies (Google docs). - If you use GA4, list both domains in GA4's cross-domain settings too, so sessions don't split at the store.
4. Forward fbclid to the store. Meta's pixel needs fbclid on the page where it loads (Meta docs). This Custom HTML tag on the landing page adds it to store links when they're clicked:
<script>
(function () {
var STORE_HOST = 'store.example.org'; // the store's domain, not yours
var fbclid = new URLSearchParams(location.search).get('fbclid');
if (!fbclid) return;
document.addEventListener('click', function (e) {
var a = e.target.closest && e.target.closest('a[href]');
if (!a) return;
var url = new URL(a.href);
if (url.hostname !== STORE_HOST || url.searchParams.has('fbclid')) return;
url.searchParams.set('fbclid', fbclid);
a.href = url.toString();
}, true);
})();
</script>
Three things to know about fbclid:
- It has to be in the URL when the store's pixel loads. The pixel sets
_fbcfrom the page it fires on. If the visitor accepts the store banner on a later page, the parameter is already gone. Fix 1 (one shared consent) removes most of this problem. - Don't change the value.
fbclidis case-sensitive, so forward it exactly as it arrived. - Without it, Meta still matches some sales, through logged-in users and advanced matching. A missing
fbclidweakens attribution rather than removing it, which is why the numbers look low instead of zero.
5. Send Meta purchases server-side. Add the Conversions API, using the order ID as event_id so pixel and server events count once (Meta deduplication). Respect the visitor's consent choice here too.
6. Bid on the product you advertise. Make a purchase conversion that fires only when the order contains the advertised product, set it as Primary, and keep "any purchase" as Secondary.
7. Add email and phone to the purchase dataLayer. This lets enhanced conversions and Meta match buyers who arrive without a click ID (Google enhanced conversions).
Re-run the test
Open the landing page with ?gclid=TEST_G&fbclid=TEST_F in a fresh incognito window, three times: ignore the banner, reject it, accept it. Each time, both IDs should appear on the store URL, the store's Conversion Linker should fire on that first page (check in the store container's Preview), there should be no second banner, and a test purchase should be counted exactly once in each platform.
If your tags all fire and revenue still isn't attributed, this is the test to run first.
For Hands-On Implementers
Stuck on this? Get it fixed live on a call.
1-hour screen-share debug session with me: bring your broken GTM, sGTM, or GA4 setup and leave with it working. $150 USD. If I can't help in the first 10 minutes, full refund.
Need Expert Help With Your Tracking Setup?
I handle complex tracking implementations so you can focus on growing your business.