Shopify conversion tracking in 2026:
the rebuild.
Checkout Extensibility, Web Pixels, Meta Conversions API, server-side tagging, deduplication, Event Match Quality. What broke, a ten-check diagnostic you can run in an afternoon, and the order to fix it in. Written from the engagements, with every platform claim linked to the doc it came from.
By Daria Dovzhikova · Updated September 2026
TL;DR
- Shopify removed the places purchase pixels used to live. checkout.liquid and additional scripts left the Thank you and Order status pages on August 28, 2025; script tags leave the Order status page for non-Plus stores on August 26, 2026.
- Tracking now runs in a sandbox that blocks window.document and enforces CORS. Old snippets do not fail loudly. They fail quietly, in Ads Manager, weeks later.
- The fix is a server event with a deterministic event_id, hashed customer parameters, consent read at runtime, and a weekly reconciliation against Shopify orders. Everything else is a vendor template.
- Measure the gap between orders of record and platform-reported purchases before you touch anything. That number is the leak, and it is the only number that proves the rebuild worked.
What changed in 2026
Five platform changes, each documented by the platform that made it. None of them announces itself in your ad account.
checkout.liquid and additional scripts are gone from the pages that report the sale
Shopify's own doc: "checkout.liquid and additional scripts were sunset for the Thank you and Order status pages on August 28, 2025." Script tags followed on the Order status page, August 28, 2025 for Plus stores and August 26, 2026 for everyone else. If your purchase pixel lived in Additional Scripts, it stopped firing on the day that applied to you, and nothing in Ads Manager told you.
Source: shopify.dev, checkout.liquid→Tracking now runs inside a sandbox, on purpose
Web pixels load in a strict sandbox (app pixels) or a lax sandbox (custom pixels). Shopify says it plainly: "Traditional JavaScript pixels that use browser APIs such as window.document won't work in this environment." Custom pixels cannot reach the top frame, and any outbound request "must explicitly support cross-origin resource sharing (CORS)." The old copy-paste snippet that read the DOM and dropped a cookie is exactly the thing the sandbox was built to stop.
Source: shopify.dev, about web pixels→The purchase event has one chance to fire, and post-purchase moves it
checkout_completed fires "once for each checkout, typically on the Thank you page." With upsells, "the checkout_completed event is triggered on the first upsell offer page instead. The event isn't triggered again on the Thank you page." And: "If the page where the event is supposed to be triggered fails to load, then the checkout_completed event isn't triggered at all." Browser-only tracking inherits every one of those gaps.
Source: shopify.dev, checkout_completed→Consent is a runtime state, not a checkbox
The pixel API exposes init.customerPrivacy with four flags: analyticsProcessingAllowed, marketingAllowed, preferencesProcessingAllowed, saleOfDataAllowed. Consent "can change without a page refresh," and the pixel has to subscribe to visitorConsentCollected to hear about it. A pixel that reads consent once at load and never again either over-fires in the EU or under-fires everywhere.
Source: shopify.dev, pixel privacy→Server-side is the only path Meta calls optimal, and it needs deduplication
Meta: "For optimal ad performance, we recommend that advertisers implement the Conversions API alongside their Meta Pixel." And in the same breath: advertisers "must set up a deduplication method." Turning on CAPI without dedup is how reported purchases double. Turning it on with a broken event_id is how they look fine for a week and then double.
Source: developers.facebook.com, deduplication→The ten-check diagnostic
Run these in order with one test order. Each check names the screen to open and what a pass looks like. Most broken stores fail check one or check four, and the rest of the afternoon is spent finding out why.
| # | Check | Where to look | Pass |
|---|---|---|---|
| 01 | Does the purchase event arrive at all? | Events Manager > Data Sources > your pixel > Test Events. Place a test order. Watch for Purchase from both Browser and Server. | Both rows appear for one order, within seconds of each other. |
| 02 | Does Shopify itself see the purchase? | Shopify admin > Settings > Customer events. Confirm checkout_completed is subscribed by the pixel that should be reporting it. | The pixel is connected and not paused; the order shows in Shopify Orders. |
| 03 | Is CAPI actually connected? | Events Manager > Settings tab on the data source. Then Diagnostics. A dead connection shows as server events at zero for the last 7 days. | Server events count is non-zero and recent. |
| 04 | Are browser and server events deduplicated? | Events Manager > Overview > Purchase > Event Deduplication. Compare processed vs deduplicated. | Near 100% of server Purchase events show as deduplicated against a browser event, or the reverse, depending on which arrives first. |
| 05 | Does event_id match across sources? | Test Events detail panel. Open a Browser Purchase and a Server Purchase for the same order and compare event_id. | Identical string on both, ideally the Shopify order id or a hash of it. |
| 06 | What is Event Match Quality? | Events Manager > Overview > Purchase > Event Match Quality. Click into it for the parameters Meta received. | Email, phone, first and last name, external_id, IP, user agent, fbp and fbc all present on the server event. |
| 07 | Which domains are sending to the pixel? | Events Manager > Settings > Traffic permissions, and Business Settings > Brand Safety > Domains. | Only your storefronts and your marketing site, each verified. No dev stores, no agency test domains, no expired campaign microsites. |
| 08 | Does the purchase survive an upsell? | Place a test order through a post-purchase offer. Check where checkout_completed fired and whether the platform saw it. | One Purchase per order regardless of the upsell path. |
| 09 | Does consent gate the right events? | Load the store from an EU IP without accepting the banner, then accept. Watch Test Events before and after. | Marketing events fire only after marketingAllowed flips, and fire on the same page without a reload. |
| 10 | Does the server container see what the browser saw? | Server GTM > Preview, or your CAPI gateway logs. Stape's own guide warns that checkout events "won't be displayed in GTM Preview due to the isolated environment on these pages." Use the server-side log, not the web preview. | One inbound purchase request per order with cookies, order id and customer parameters attached. |
The rebuild, in order
Seven steps. The order matters because each one removes a variable the next one would otherwise blame.
- 01
Count the orders of record first
Pull 30 days of Shopify orders. That number is the truth every platform gets reconciled against. Write it down before touching a tag, because the temptation once tracking improves is to celebrate the new reported number instead of measuring the gap.
- 02
Decide the source of the server event
Three options with different failure modes. Shopify's Meta channel at Enhanced or Maximum data sharing sends "the purchase event between Shopify and Facebook servers" with name, location, email and phone. A server GTM container fed by a custom pixel and a data tag, which you control end to end. Or a CAPI gateway app. Pick one. Two of them at once is a duplication problem you will spend a month diagnosing.
- 03
Move every browser tag into a pixel
Anything still in a theme file, a script tag, or a leftover Additional Scripts field either already stopped on the checkout pages or will. Rebuild it as an app pixel (strict sandbox) or a custom pixel (lax sandbox). Test the fetch calls against CORS before assuming they work.
- 04
Make event_id deterministic
The browser event and the server event need the same event_id and the same event_name. Derive it from the order id, on both sides, from the same field. A random UUID generated in the browser only works if it is also handed to the server, and inside the sandbox that handoff is the fragile part.
- 05
Pass the customer parameters, hashed
Meta's list of high-value fields: "email address (em), IP address (client_ip_address), name (fn and ln), phone number (ph)." Meta's guidance is to hash if you are not using the Business SDK. The server side has all of these from the order. The browser side rarely does.
- 06
Wire consent into the pixel, not around it
Read init.customerPrivacy, subscribe to visitorConsentCollected, and gate marketing events on marketingAllowed. Do this in code. A consent app that hides the pixel and a pixel that ignores the app produce the same broken result from opposite directions.
- 07
Reconcile weekly, in one sheet finance will read
Orders of record, platform-reported purchases, deduplicated purchases, EMQ, and the gap between them, one row per week per platform. When the gap moves, something changed in the stack. When it does not move, you are done.
Deduplication mechanics
Meta documents two methods. The recommended one: "a Meta Pixel's eventID must match the Conversion API's event_id" and "a Meta Pixel's event must match the Conversion API's event_name." The fallback compares event_name with fbp and/or external_id, and Meta notes it "only works for deduplicating events sent first from the browser and then through the server."
The window: "Events are only deduplicated if they are received within 48 hours of when we receive the first event with a given event_id." A server event that arrives from a delayed webhook three days later counts as a second purchase.
On Shopify the practical rule is to derive event_id from the order id on both sides. The pixel has it in the checkout_completed payload, where the order id "will be null for all events except checkout_completed." The server has it from the order. Two systems reading the same field produce the same string without a handoff. Anything generated at random in the browser and passed through the sandbox is the part that breaks first.
Sources: Meta, deduplicate pixel and server events · Shopify, checkout_completed
Event Match Quality, and which parameters move it
Meta's definition: "An event's EMQ score (out of 10) indicates how effective your server event's customer information may be at matching it to a Facebook or Meta account." The consequence is the sentence that matters for money: "You can use only matched events for ads attribution and ad delivery optimization." Unmatched events count for basic measurement and nothing else.
The parameters Meta names as high value: "email address (em), IP address (client_ip_address), name (fn and ln), phone number (ph)." Meta's guidance is to hash if you are not using the Business SDK. Every one of those fields sits in the Shopify order object the server already has. A Purchase event with totals and no customer parameters is a receipt Meta cannot use to find the buyer, which is why EMQ on browser-only setups stalls in the low single digits.
Shopify's native Meta channel at Enhanced or Maximum sends "name, location, email address, and phone number" with the server purchase event. If you are building your own server path, match that list at minimum, then add external_id, fbp, fbc, and user agent.
Sources: Meta, Conversions API best practices · Shopify, Meta data sharing levels
The reporting view finance will accept
Ads Manager is a claim, not a ledger. Shopify orders are the ledger. One sheet, one row per platform per week, five columns:
| Column | Source | Why it is there |
|---|---|---|
| Orders of record | Shopify Orders export | The denominator for everything |
| Platform-reported purchases | Ads Manager, Google Ads | The claim, before dedup |
| Deduplicated purchases | Events Manager dedup view | Whether pixel and server agree |
| Event Match Quality | Events Manager, Purchase event | Whether the platform can use what it got |
| Gap | Orders minus platform-reported, as a percentage | The leak. The number the rebuild is measured on. |
Cost per purchase and ROAS get computed off orders of record, not off the platform's count. The platform's count is what the optimizer uses, and that is a separate problem the rebuild fixes by feeding it a fuller signal. Reconciling weekly catches a dead CAPI connection in seven days instead of a quarter.
Common failure modes
| Symptom | Usual cause | Fix |
|---|---|---|
| Purchases in Ads Manager are a fraction of Shopify orders | Browser-only tracking after the Thank you page migration, or CAPI connected but not sending. | Confirm server events are non-zero in Diagnostics; if zero, the connection is dead regardless of what the settings page says. |
| Purchases in Ads Manager are roughly double Shopify orders | Pixel and CAPI both firing with mismatched or missing event_id. | Same event_id and event_name on both. Meta only deduplicates "if they are received within 48 hours of when we receive the first event with a given event_id." |
| Reported cost per purchase jumps after a checkout redesign | Post-purchase upsell moved checkout_completed to the first offer page and the old pixel logic waited for the Thank you page. | Subscribe to checkout_completed in a pixel; stop keying on the page. |
| Event Match Quality stuck at 3 or 4 | Server event carries order totals but no hashed email, phone or name. | Attach the customer fields from the order object; Meta cannot use unmatched events "for attribution or ad delivery optimization." |
| AddToCart fires, Purchase never does | Storefront tags run in the theme; checkout runs in the sandbox where the theme tag cannot execute. | Move the funnel events into one pixel that covers storefront, checkout and post-purchase. |
| Events arrive from domains you do not recognise | The pixel id was pasted into dev stores, agency test sites and old landing pages, and none were verified. | Verify the real domains, remove the rest, and set traffic permissions on the data source. |
| Numbers look fine in the EU, wrong in the US, or the reverse | Consent gating applied globally by a banner app while the pixel ignores the consent flags. | Gate in the pixel on the four customerPrivacy flags; the banner is an input, not the gate. |
What this looks like in a real account
151 purchases. Meta saw 7.
A DTC fitness-hardware brand: a WordPress marketing site in front of four regional Shopify Plus stores. Meta Ads Manager reported 7 purchases in a period where the stores recorded 151. Reported cost per purchase read $2,440. The real figure, computed off orders, sat somewhere between $700 and $1,200 depending on the region. Every budget decision for months had been made off the $2,440.
Events Manager gave up the causes in an afternoon. The Conversions API was not firing at all; the diagnostic string on the connection read cdl=API_unavailable. Where browser events did arrive, the event id generated on the WordPress side did not match the one the Shopify stores produced, so nothing deduplicated across the domain boundary. And 28 unverified domains were sending to the same pixel id, from dev stores and old campaign sites nobody had cleaned up.
The remediation ran as an eight-week plan: CAPI repair, cross-domain event id, domain cleanup, GTM consolidation, consent rollout across the four storefronts. The after-numbers are the client's to publish. The before-numbers are the point of this page: nothing in the ad account said anything was wrong. The 7 was reported with complete confidence.
If you would rather not spend the afternoon
The Growth Pilot, $5,000, four weeks.
Week one runs the ten checks above as the baseline and hands you the ranked list: server-side events, Meta CAPI with deduplication, GA4, the Shopify event layer, consent, and the reconciliation sheet. Then two experiment cards run against the clean numbers. Measured on match rate and attributed revenue before and after.
Want the size of the gap first? The Attribution Leak Calculator turns reported and actual purchases into wasted spend and undercounted revenue.
FAQ
Is Shopify conversion tracking actually broken in 2026, or is this vendor noise?
Both. The vendor noise exists because the break is real. Shopify sunset checkout.liquid and additional scripts on the Thank you and Order status pages on August 28, 2025, and script tags on the Order status page follow on August 26, 2026 for non-Plus stores. Any purchase pixel that lived in those places stopped. The vendors selling the fix are right about the problem and mostly selling a template.
What is the Meta Conversions API and do I need it if I have the pixel?
The Conversions API sends conversion events from your server to Meta instead of from the shopper's browser. Meta's own recommendation is to run it alongside the pixel, with deduplication, because browser events get lost to blockers, consent, and pages that never load. Yes, you need it. The pixel alone reports a fraction of what happened.
How does Meta deduplicate pixel and CAPI events?
The recommended method matches the pixel's eventID to the server's event_id and the pixel's event name to the server's event_name. Meta only deduplicates events received within 48 hours of the first one carrying that event_id. The fallback method uses event_name plus fbp and/or external_id, and it only works when the browser event arrives first.
What is Event Match Quality and what number is good?
EMQ is a score out of 10 that indicates how effective a server event's customer information is at matching it to a Meta account. Meta says only matched events can be used for attribution and ad delivery optimization. The fields that move it are the ones a Shopify order already has: email, phone, first and last name, plus IP and user agent from the request. Treat anything under 6 on Purchase as a data problem, not a Meta problem.
Does Shopify's own Meta integration send CAPI events?
At the Enhanced and Maximum data-sharing levels, yes. Shopify's help doc says the Conversions API sends the purchase event between Shopify and Facebook servers, and shares name, location, email address and phone number. If you also run your own CAPI via server GTM or a gateway app, you now have two server sources for the same purchase. Pick one.
What is server-side tagging on Shopify and when is it worth it?
A server GTM container on your own subdomain receives events from a custom pixel or data tag and forwards them to Meta, Google and anyone else, with your first-party cookies attached. It is worth it when you need one place that owns event_id, consent and customer parameters across several platforms. It is not worth it for a single store on a single ad platform that Shopify's native channel already covers.
Why does the Meta browser pixel misbehave inside a Shopify custom pixel?
The custom pixel runs in a lax sandbox with no top-frame access and CORS-only network calls. Practitioners on Stape's community report browser events like AddToCart firing while others do not from inside the sandbox, with the server-side CAPI path working normally. The reliable pattern is to make the server event authoritative and treat the browser event as the dedup partner.
What does an attribution gap cost, in money?
Two things. The spend the ad platform steers on a partial signal, because its optimizer only sees the conversions that reported. And the decisions your team makes on a cost per purchase that is off by a multiple. The Attribution Leak Calculator on this site turns your reported and actual numbers into an estimate of both.
How long does a rebuild take?
Four weeks for a single Shopify Plus store with one ad platform when the access exists on day one: Meta Business Manager, the Shopify admin, GTM if it is in the stack. Multi-store, multi-region setups with a separate marketing site take the full eight-week plan, and the first two weeks are usually spent getting admin access to accounts the last agency set up.
What do you measure before and after?
The same four numbers. Orders of record from Shopify. Platform-reported purchases. Deduplicated purchases. Event Match Quality on Purchase. The gap between the first two is the leak. The program is done when the gap is stable and small and finance accepts the reconciliation sheet.
Platform sources on this page: Web Pixels API, about web pixels, checkout_completed, pixel privacy, checkout.liquid, script tag blocking (Shopify); deduplication, Conversions API best practices (Meta); Meta data sharing on Shopify; server-side tagging for Shopify and a custom pixel limitations thread (Stape). Read at publication; verify against the current doc before acting on a date.
Related guides
Is the gap on your account bigger than you think?
Thirty minutes to find out. If the tracking is fine, the call says so.