A shopper accepts marketing cookies on your catalogue, pays by iDEAL, and the checkout custom pixel still sends checkout_completed with marketing denied, so the Conversion API tag stays dark.
The order is real and Shopify counts it.
What went missing is the grant, and the fix is to confirm the storefront banner wrote it into Shopify Customer Privacy, then make the checkout pixel read that record after the payment redirect.
Introduction
This article teaches the cloakroom ticket walk: confirm the storefront cookie banner writes marketing consent into Shopify Customer Privacy, then verify checkout custom pixels read that ticket 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 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.
Why does checkout ignore my cookie banner?
Think of a theatre cloakroom. The attendant hands back your coat against the cloakroom's own numbered ticket, and a note you wrote yourself saying "my coat is the blue one" gets you nothing, however neat the handwriting.
I call this the cloakroom ticket. Shopify Customer Privacy issues the only ticket a checkout pixel will honour, and a third-party CMP's accept is the handwritten note until the banner hands it to Shopify.
Checkout custom pixels run in a lax sandbox on Shopify's domain, so they cannot see the first-party cookies your CMP wrote on yourdomain.com. Reading the banner's cookie from inside the pixel should 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.
On the storefront, themes and CMP scripts call window.Shopify.customerPrivacy.setTrackingConsent() after consent-tracking-api loads, and Shopify stores that decision in _tracking_consent. The docs tell you never to read or patch that cookie yourself, because its 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 holding no ticket at all.
What does the leak look like in the logs?
The storefront can look coherent, with Consent Mode combinations validating and server GTM logs showing Meta only receiving events when ad_storage is granted. The trouble starts inside checkout, especially after a redirect payment.
- The CMP register records an accept, while the purchase hit that reached server GTM carries Google Consent Mode
gcs=G100, which means marketing denied. - The same order appears twice in pixel logs, denied at
checkout_completedand then granted whenvisitorConsentCollectedarrives 10 to 30 seconds later. - 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, which 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 reading an empty or denied state and correctly refusing to send marketing.
These patterns come up regularly across Shopify merchant and developer threads, usually from brands that rebuilt tracking after Additional Scripts and then found the replacement pixel could not see the banner's grant.
Why would a grant arrive late, or vanish?
Timing is the first extra leak. The CMP's own checkout pixel often updates Shopify consent asynchronously, so 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, and without a replay that reuses the same event_id, Meta treats the late hit as optional or drops it while Google Ads never sees the conversion.
The payment redirect is the second. iDEAL and similar bank flows send the shopper out of Shopify and back through /payment_providers/.../redirect/processing, and on Android that return frequently opens Samsung Internet or the bank's in-app browser. That new browser has no CMP cookie, and no third-party banner can render inside checkout.
Shopify Payments test mode for iDEAL skips the redirect entirely, which is why a test order can pass while live orders fail.
Checkout consent diagnostic
Cart attributes and orders/paid webhooks sit outside this diagram on purpose. They can carry a photocopy of the ticket 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 do I find which ticket went missing?
Start from Shopify's Customer Privacy record and work outward through the pixel and the order, leaving the GTM debug view until last.
- Check admin under Settings, then Customer privacy. In the Netherlands, Belgium, and other collect-after-consent regions, non-essential purposes stay denied until a grant exists, and with Shopify's own banner off a third-party CMP must do the write. Channel apps still honour that setting when they load.
- On a product page after the banner accept, call
window.Shopify.customerPrivacy.currentVisitorConsent()andmarketingAllowed(). You wantmarketing: 'yes'(ortruefrom the Allowed helper). If the CMP register shows accept while this API returns an empty string, the banner never integrated with Shopify, so fix that write before touching checkout pixels. - In the custom pixel, push
init.customerPrivacyto your server endpoint at init, subscribe tovisitorConsentCollected, and push the update too. Compare both payloads withcheckout_completedfor the same checkout token. Denied at init and atcheckout_completed, then granted 15 seconds later, is the timing leak, and three empty payloads mean the write never reached Shopify. - Pick ten live paid orders that used a redirect method and note device, referrer, and whether thank you stayed in the original browser. Because iDEAL test mode skips the bank webview, 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.
- Open the order as well as the pixel log. If you already write a consent flag to a cart attribute, check whether
note_attributesstill hold it after iDEAL. Community reports say the redirect is where that copy disappears, so a missing attribute is a failed persist rather than a pixel bug. - Confirm who owns marketing sends. With customer data sharing still on in the Facebook and Instagram app, you may have a native purchase event plus a custom CAPI hit, and deduping on 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 the two layers 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 do I repair the handoff?
Repair the Shopify write first, then make the checkout pixel wait, and only after that 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, since the sandbox cannot set a first-party cookie. |
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 | Leave the conversion unsent unless a cart attribute written on the storefront is present on that order, in which case a webhook may send CAPI for that order only. |
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 keeps the snapshot, subscribes once, and only sends 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 });
}
});
Derive one event_id from the order or checkout token and use it for both the first send and the replay, so Meta and Google Ads can dedupe.
What about redirect orders with no ticket at all?
A payment redirect that opens a new browser leaves you with an Android or bank webview, no CMP cookie, and no banner. Leave the conversion unsent unless a cart attribute written on the storefront is present on that order, in which case a webhook may send CAPI for that order only.
Treat cart attributes as a photocopy of the ticket, useful only when Shopify's record is the original. Write them on catalogue pages or at add to cart, while the shopper is still in the storefront browser, and confirm on a live iDEAL order that the value survives before you wire orders/paid to CAPI. Pixel event payloads can include checkout attributes, but 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, yet consent for pixels still belongs on the Customer Privacy API. 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, while Liquid storefronts load consent-tracking-api through Shopify.loadFeatures and need none of those fields.
Pasted tracking stopped running on Thank you for non-Plus stores after 26 August 2026. Plus lost Additional Scripts a year earlier, so even a checkout UI extension that renders a third-party cookie banner still leaves marketing hits to the pixel sandbox.
Conclusion
You can now confirm whether the storefront banner wrote marketing consent into Shopify Customer Privacy, verify that checkout custom pixels read that ticket after a payment redirect, and repair the handoff without Thank you scripts. Hand Shopify the ticket, then let the pixel wait for it. When the grant never arrived, the pixel stays silent.
When the CMP, the custom pixel, server-side GTM, and redirect payments all need one owner, a Shopify stack assessment will map the write, the subscribe, and the replay against live orders. Book a discovery call if you want that wiring owned as one integration rather than three tools that disagree.



