You match this morning's paid iDEAL orders against the cookie banner register. The shopper accepted marketing on the catalogue. The checkout custom pixel still sent checkout_completed with marketing denied, so the Conversion API tag stayed dark.
That mismatch is the job: confirm the storefront banner wrote the grant into Shopify Customer Privacy, then verify the checkout custom pixel read that record after the payment redirect and repair the handoff.
Introduction
This article teaches you to confirm the storefront cookie banner writes marketing consent into Shopify Customer Privacy, then verify checkout custom pixels read that record after a payment redirect and repair the handoff. Pasted Thank you scripts that went silent on 26 August 2026 are a separate failure, covered in Shopify Additional Scripts Cutoff on 26 August 2026.
Soft navigation that never delivers page_viewed into pixel sandboxes belongs in Shopify Soft Navigation and the Web Pixel Gap. Checkout steps that stall before payment belong in How to Fix Shopify Checkout Abandonment When Your Funnel Looks Healthy.
Merchant and developer threads this week keep returning to the same leak. A third-party CMP and server-side GTM look coherent on the storefront, then checkout pixels fire without a marketing grant, while Shopify order counts stay intact and Meta or Google Ads look like a quiet week.
What merchants are running into
The storefront path can be coherent, with Consent Mode combinations validating and server GTM logs showing Meta only receiving events when ad_storage is granted. The break appears once the shopper is inside checkout, especially after a redirect payment such as iDEAL.
Three symptoms show up together:
- The CMP register records an accept, while the purchase hit that reached server GTM carries Google Consent Mode
gcs=G100(marketing denied). - The same order appears twice in pixel logs: denied at
checkout_completed, then granted 10 to 30 seconds later whenvisitorConsentCollectedfinally arrives. - Android and in-app bank browsers account for most of the empty-consent purchases, because thank you opened somewhere other than the browser that saw the banner.
Shopify's native Google and Meta channel apps that subscribe to checkout_completed through Customer events still fire. The custom pixel you added for server-side GTM, a CMP, or a CAPI bridge is the one that reads an empty or denied state and correctly refuses to send marketing.
This reflects patterns we see regularly across the Shopify merchant and developer community: brands that rebuilt tracking after Additional Scripts, then discovered the replacement pixel could not see the banner's grant.
Why this happens
Checkout custom pixels run in a lax sandbox on Shopify's domain. They do not share the first-party cookies your CMP wrote on yourdomain.com. Reading the banner's storage cookie from inside the pixel is expected to return nothing. Shopify's Pixel Privacy docs point pixels at init.customerPrivacy and at customerPrivacy.subscribe('visitorConsentCollected'), which is the only subscribe string that API accepts today.
The storefront Customer Privacy API is a different object. Themes and CMP scripts call window.Shopify.customerPrivacy.setTrackingConsent() after consent-tracking-api loads, and Shopify stores that decision in _tracking_consent. Docs tell you never to read or patch that cookie yourself, because the format changes. A CDN or edge worker that strips cookies on the apex, or a CMP that only talks to Google Consent Mode, can leave checkout with an empty Shopify record.
Timing is a second, independent leak. The CMP's own checkout pixel often updates Shopify consent asynchronously. Your tracking pixel may already have handled checkout_completed with the init snapshot (marketingAllowed: false in a collect-after-consent region). A late visitorConsentCollected then flips the grant. Without a replay that reuses the same event_id, Meta treats the late hit as optional or drops it, and Google Ads never sees the conversion.
The third leak is the payment-provider redirect. iDEAL, and similar bank flows, send the shopper out of Shopify and back through /payment_providers/.../redirect/processing. On Android that return frequently opens Samsung Internet or the bank's in-app browser. No CMP cookie exists there. No third-party banner can render inside checkout. Shopify Payments test mode for iDEAL skips that redirect, so a test order can pass while live orders do not.
Checkout consent diagnostic
Cart attributes and orders/paid webhooks sit outside this diagram on purpose. They can carry a copy of the grant if you wrote it before checkout started, and they can also freeze an old decision or invent a send the shopper never confirmed in the checkout browser.
How to diagnose it
Start from Shopify's Customer Privacy record rather than from a GTM debug view, then work outward through the pixel and the order.
- Confirm Customer privacy settings in admin under Settings, then Customer privacy. For the Netherlands, Belgium, and other collect-after-consent regions, non-essential purposes stay denied until a grant exists. If Shopify's own cookie banner is off, a third-party CMP must perform the write, and channel apps still honour that setting when they load.
- Prove the storefront write on a product page after the banner accept by calling
window.Shopify.customerPrivacy.currentVisitorConsent()andmarketingAllowed(). You wantmarketing: 'yes'(ortruefrom the Allowed helper), not an empty string. If the CMP register shows accept and this API still returns empty, the banner never integrated with Shopify, so fix that write before touching checkout pixels. - Log the pixel snapshot rather than the CMP cookie. In the custom pixel, at init, push
init.customerPrivacyto your server endpoint, subscribe tovisitorConsentCollected, and push the update. Compare those two payloads withcheckout_completedfor the same checkout token. If init is denied,checkout_completedis denied, and the subscribe event grants 15 seconds later, you have the timing leak. If all three stay empty, the write never reached Shopify. - Split same-browser orders from redirect orders. Pick ten live paid orders that used a redirect method, then note device, referrer, and whether thank you stayed in the original browser. Shopify's iDEAL test mode skips the bank webview, so you need a real bank return, or a device farm that opens the return URL in a second browser, to see the empty-consent slice.
- Check the order, not only the pixel. If you already write a consent flag to a cart attribute, open the order and see whether
note_attributesstill hold it after iDEAL. Community reports say the redirect is where that copy disappears, so treat a missing attribute as a failed persist rather than as a pixel bug. - Confirm who owns marketing sends. If the Facebook and Instagram app still has customer data sharing on, you may have a native purchase event plus a custom CAPI hit. Deduping with one
event_idonly works when both layers see the same consent decision. Turn native sharing off while you prove the custom path, or accept that Shopify's pixel layer and your GTM layer can disagree.
Admin tasks that still hop across five tools belong in How to Fix Shopify Operational Friction When Simple Tasks Still Take Too Long. This diagnosis stays on one record: Customer Privacy in the pixel.
How to fix it
Repair the Shopify write first. Then make the checkout pixel wait. Only then consider a server-side copy that travelled with the order.
| Failure | What you see | Repair |
|---|---|---|
| CMP never wrote Customer Privacy | Storefront API empty after accept; checkout init denied | Call setTrackingConsent from the banner on the storefront. Keep Shopify's native banner if the CMP cannot do that write. |
| Pixel reads CMP cookies | Sandbox storage empty; GTM defaults to denied | Stop reading banner cookies in the custom pixel. Gate tags on init.customerPrivacy and visitorConsentCollected. Pass that boolean as an event parameter into sGTM, not as a first-party cookie the sandbox cannot set. |
Grant arrives after checkout_completed | Denied hit, then granted 10 to 30 seconds later | Subscribe to visitorConsentCollected, update the snapshot, replay purchase once with the same event_id. Pixel Privacy documents this wait. |
| Payment redirect opens a new browser | Android or bank webview; no CMP cookie; no banner | Do not invent a grant from a missing cookie. If a cart attribute written on the storefront is present on the order, a webhook may send CAPI for that order only. If the attribute is missing, leave the conversion unsent. |
CDN strips _tracking_consent | Apex proxy or edge worker; API empty on return to storefront | Allow Shopify's consent cookie through to the origin. Still use the API rather than parsing the cookie in your own code. |
A working custom pixel looks like this in outline. Keep the snapshot in the pixel, subscribe once, and only send marketing when the Allowed flag is true.
let customerPrivacyStatus = init.customerPrivacy;
api.customerPrivacy.subscribe('visitorConsentCollected', (event) => {
customerPrivacyStatus = event.customerPrivacy;
if (customerPrivacyStatus.marketingAllowed && pendingPurchase) {
sendPurchase(pendingPurchase, { replay: true });
}
});
analytics.subscribe('checkout_completed', (event) => {
pendingPurchase = event;
if (customerPrivacyStatus.marketingAllowed) {
sendPurchase(event, { replay: false });
}
});
Use one event_id derived from the order or checkout token for both the first send and the replay so Meta and Google Ads dedupe.
Cart attributes are a backup copy, not a second source of truth. Write them on catalogue pages or at add to cart, while the shopper is still in the storefront browser. Pixel event payloads can include checkout attributes. Confirm on a live iDEAL order that the value still exists on the order before you wire orders/paid to CAPI. A webhook that always fires Purchase will bypass the denied check that correctly stopped the pixel.
Plus checkout UI extensions can collect extra fields at checkout. They do not replace Customer Privacy for pixels. If you are scoping display versus logic at checkout, use When to Use Checkout UI Extensions vs Shopify Functions and keep consent on the privacy API.
Headless or Hydrogen storefronts must pass checkoutRootDomain, storefrontRootDomain, and a Storefront access token into setTrackingConsent. Liquid storefronts load consent-tracking-api through Shopify.loadFeatures and do not need those extra fields.
When to get help
Bring in a partner when the CMP, the custom pixel, server-side GTM, and a redirect payment all have to agree on one grant. That wiring is integration work: who writes Customer Privacy, which pixel is allowed to send marketing, and which orders are allowed to replay.
Thank you no longer runs pasted tracking on non-Plus stores after 26 August 2026, and Plus lost Additional Scripts a year earlier, so a checkout UI extension that renders a third-party cookie banner still leaves marketing hits to the pixel sandbox.
If the catalogue already loses shoppers before payment, finish that path first with the abandonment guide. If route-level page_viewed is missing on a partials theme, finish the soft-navigation pixel gap before you trust browse attribution.
Conclusion
You can now confirm whether the storefront banner wrote marketing consent into Shopify Customer Privacy, verify that checkout custom pixels read that record after a payment redirect, and repair the handoff without Thank you scripts. The storefront accept is only useful when Shopify stored it. The checkout pixel is only useful when it waits for that store, then stays silent when the grant never arrived.
If the CMP, custom pixels, and redirect payments need one owner, book a discovery call and we will map the write, the subscribe, and the replay against live orders. For the broader tracking and CMP wiring, start with integrations and system optimisation.



