Tracking & Attribution

How Do You Fix Shopify Tracking, Attribution, and Catalog?

Shopify tracking, attribution, and product feeds in one place — server-side conversions, identity stitching, and Meta/Google catalog feeds.

Quick answer

Fix Shopify tracking by firing conversions from the order record server-side instead of the thank-you page, attribution by stitching a buyer's sessions into one identity, and catalog by generating Meta and Google feeds from the same product sync. Doing all three in one place removes the double-firing and conflicting numbers that come from stacking three separate apps, each with its own pixel.

Tell us what's broken. We'll fix your tracking — free.

Describe the tracking/attribution problem you're stuck on and we'll map it to a fix: server-side conversions to Meta, Google, TikTok and Pinterest, plus first-party tracking that survives Safari. No code required.

Fix Shopify tracking by firing conversions from the order record server-side instead of the thank-you page. Fix attribution by stitching a buyer’s sessions into one identity so the purchase connects back to the ad click that caused it. Fix catalog by generating Meta and Google feeds from the same product sync. And do all three from one install — because stacking a tracking app, an attribution app, and a feed app means three pixels, three sets of numbers, and conversions counted twice.

If your Shopify admin says 180 orders and Meta says 240, and you’ve got four apps installed that all claim to fix tracking, this article is for you. It covers where Shopify specifically loses conversions, what “accurate tracking” can and cannot honestly mean, and why one pipeline beats three.


Why do Shopify stores lose conversions to ad platforms?

Shopify breaks conversion tracking in ways other platforms don’t, because custom tracking code runs in a sandbox — a security boundary that keeps third-party scripts away from checkout. Four consequences:

The thank-you page is not guaranteed to load. Payment redirects through PayPal, Klarna, or a bank send the buyer off-site. Shopify records the order when the gateway confirms payment — but the buyer may close the tab at the gateway and never return. The order exists; the browser pixel never fired; the ad platform never hears about the sale.

The sandbox strips data the pixel needs. Shopify’s Customer Events environment returns an empty user-agent on a large share of sessions and restricts cookie access. Events that do fire often ship degraded, with match data missing.

Visitor IDs regenerate mid-journey. The sandbox re-initialises storage frequently, so the ad-click session and the checkout session can look like two unrelated anonymous visitors. The purchase carries no click ID and reports as “Direct” — the campaign that drove the sale gets nothing.

Ad blockers and privacy browsers block the script outright. Industry estimates put blocker prevalence above 30% on desktop. A blocked script is a silent, invisible loss.

Every one of these is a browser problem. None of them touch the order record sitting in your Shopify admin.


What does “accurate Shopify tracking” actually mean?

Worth being precise here, because “100% accurate tracking” gets promised a lot and the honest picture has two halves that behave very differently.

Half one — delivery: this genuinely can be complete, and you can verify it. When conversions fire from Shopify’s order webhook server-to-server, every order that exists in your admin produces a conversion event. Gateway redirects, closed tabs, ad blockers, and sandbox failures all become irrelevant, because the buyer’s browser was never in the loop. This is the checkable half: reconcile your admin order count against the events dispatched over the same window, and they should match. If you take one test away from this article, make it that reconciliation.

Half two — matching: this is maximised, never guaranteed. Whether Meta or Google can tie that event back to a specific user and a specific ad click depends on the identifiers you captured and on the platform’s own ability to resolve them. Users who opted out of tracking on iOS, users the platform simply can’t match, consent-denied sessions — those are decided on the platform’s side of the wire, and no tool controls them.

So the honest framing is: you can control dispatch completely; you can only improve matching. Any vendor promising 100% attribution is promising something that isn’t theirs to give. What a good pipeline does is close every gap that’s actually closable — and the closable set is far bigger than most stores realise, because nearly every loss above is a browser-dependency problem with a server-side answer.


Why does stacking separate apps make it worse?

The usual Shopify stack accretes over time: the native Meta sales channel, then a server-side tracking app, then an attribution app, then a product-feed app. Each one wants its own pixel on the page. The result is predictable.

Conversions get counted more than once. Two or three emitters fire the same purchase with different event IDs. Platforms deduplicate only when the IDs match — different IDs means every purchase counts twice or three times. Reported ROAS inflates, the account scales on numbers that aren’t real, and the gap between your admin and Ads Manager grows with your spend.

Nothing agrees with anything. Your tracking app reports one conversion count, your attribution app another, Ads Manager a third, and Shopify admin a fourth. Reconciling them becomes a weekly ritual with no resolution, because each tool measures a slightly different event with a slightly different definition.

Every app is a separate failure point. Four apps means four sets of credentials to rotate, four things that break when Shopify updates its pixel API, and four support queues when the numbers go wrong. Diagnosing which layer failed is most of the work.

And the catalog usually drags tracking along with it. Turning on the native Meta channel for product feeds also turns on its own pixel and conversion events — which is how stores that deliberately chose a custom tracking setup end up double-firing anyway.

Multiple Shopify apps each firing their own pixel for the same order, producing duplicate conversions and conflicting numbers


How does PartialLeads do all three from one install?

One tag plus your Shopify connection covers tracking, attribution, and catalog — with the pieces sharing a single source of truth instead of competing.

Tracking: conversions fire from the order, not the browser. The purchase event is dispatched server-side from Shopify’s orders/create webhook, carrying the full order — value, currency, line items, customer email and phone. Gateway redirects and blockers can’t intercept what the browser never handled. Refunds flow through as their own events and net against revenue, so your reported numbers stay honest rather than gross. The upper-funnel events (ViewContent, AddToCart, InitiateCheckout, AddPaymentInfo) fire server-side too, so the ad algorithm trains on the whole journey.

And the sandbox gotchas are patched, not worked around. When Shopify’s sandbox returns an empty user-agent, the real one is recovered from the HTTP request instead. When the sandbox regenerates a visitor ID mid-journey, sessions from the same device and window inherit their sibling’s attribution — a real case: a $219 order reporting as “Direct” was correctly re-attributed to Google Ads because the buyer’s earlier same-visit session carried the click ID.

Attribution: one buyer, one identity, across sessions and devices. Every purchase is matched to its originating session through tiered identity resolution — the visitor ID when the order carries it, then normalised email, then phone, then IP. A shopper who clicks your Meta ad on a phone Tuesday and checks out on a laptop Thursday still resolves to Tuesday’s click. Each matched purchase writes both first-touch and last-touch attribution, so you can see the channel that introduced the customer and the one that closed them, per campaign, with revenue attached.

Deduplication is structural, not configured. Every event’s ID is derived deterministically from the order record and backed by a send ledger, so a webhook retry, a re-send, or two paths racing all produce the same ID and get blocked before dispatch. The multi-app double-counting problem can’t reproduce through this pipeline.

Catalog: product feeds from the same connection. Paste a Shopify Admin API token and your products sync on a rolling schedule into hosted feed URLs for Meta Commerce and Google Merchant Center, at the per-variant grain both platforms expect. Feeds are protected by an unguessable token, and a Catalog Intelligence view shows feed health — which items Google or Meta will reject or downrank, and what your catalog is actually made of — so you fix problems before the platform silently drops products. WooCommerce catalog sync works the same way.

Crucially, catalog is optional and decoupled. Turning on feeds doesn’t switch on a competing pixel, doesn’t require the native Meta sales channel, and doesn’t touch your conversion tracking. Stores that want feeds get feeds; stores that deliberately don’t want catalog coupling keep tracking exactly as it was. That separation is the thing the native channel doesn’t give you.

One install handling conversion tracking, identity-based attribution, and product feeds from a single connection

Setup is free to start. The free tier covers a full verification cycle: connect, run live orders, reconcile your admin count against dispatched events, and check attribution on real purchases before paying anything.

Honest boundaries. Keep a base Meta Pixel installed — its browser cookie feeds match quality on the server-side events, and upper-funnel browser signals remain useful. Catalog feeds require a Shopify custom-app Admin API token, and PartialLeads produces the feed rather than configuring your Meta Shop for you. Per-product sales performance — which feed items actually sell — isn’t available yet. And as covered above, matching is improved rather than guaranteed: the platform owns its half of that.

The Shopify gap, closed in one view:

The problem PartialLeads mechanism How you verify it
Gateway redirect or closed tab kills the purchase event Purchase dispatched from the orders/create webhook, server-side Every admin order has a matching dispatched event
Sandbox strips the user-agent Real user-agent recovered from the HTTP request Full match parameters on events in Test Events
Visitor ID regenerates → sale reports “Direct” Visit-sibling inheritance + tiered identity matching Journey timeline showing ad click → purchase
Cross-device buyer looks like two strangers Identity resolution: visitor ID → email → phone → IP One lead record carrying the whole journey
Multiple apps double-fire the same order Deterministic event IDs + send ledger Ads Manager count ≈ Shopify admin count
Feed items silently rejected by Meta/Google Catalog Intelligence feed-health view Rejection and downrank issues listed before you push
Catalog sync forces a competing pixel on you Feeds fully decoupled from tracking Tracking unchanged with the native channel off

Tell us what's broken. We'll fix your tracking — free.

Describe the tracking/attribution problem you're stuck on and we'll map it to a fix: server-side conversions to Meta, Google, TikTok and Pinterest, plus first-party tracking that survives Safari. No code required.

Sources

  1. Shopify Dev Docs — Web pixels (Customer Events) sandbox: https://shopify.dev/docs/api/web-pixels-api
  2. Shopify Dev Docs — Order webhooks: https://shopify.dev/docs/api/webhooks
  3. Meta for Developers — Conversions API: https://developers.facebook.com/docs/marketing-api/conversions-api
  4. Meta for Developers — Deduplicate Pixel and Server events: https://developers.facebook.com/docs/marketing-api/conversions-api/deduplicate-pixel-and-server-events
  5. Google Merchant Center — Product data specification: https://support.google.com/merchants/answer/7052112
  6. Meta Commerce — Catalog feed requirements: https://www.facebook.com/business/help/120325381656392

Frequently asked questions

QWhy does Meta report more purchases than my Shopify admin?
Double-firing, almost always. Shopify's native Meta channel sends its own events; a tracking app sends the same purchases with different event IDs; platforms deduplicate only when the IDs match. Run the check: compare Meta's reported purchases against your Shopify admin orders for the same window. A persistent 30%+ overcount means two or more pipelines are competing. The fix is one pipeline with deterministic event IDs, not another app.
QCan any tool really guarantee 100% accurate Shopify tracking?
No, and it's worth understanding why the answer splits in two. **Delivery** can be complete and verifiable — firing conversions from the order webhook means every order in your admin produces an event regardless of browsers, blockers, or redirects. **Matching** — whether the platform ties that event to a user and a click — depends partly on the platform's own ability to resolve the person, which no vendor controls. Treat "100% attribution" claims as a red flag; ask instead what percentage of your admin orders produce a dispatched event, because that number is checkable.
QDo I still need the Meta Pixel if conversions fire server-side?
Keep it. The Pixel handles browser-moment events and sets the cookie that server-side events reuse as a match identifier — removing it lowers match quality on everything you send. The right architecture is both, with the same event ID on any conversion that fires from both sides so the platform deduplicates instead of double-counting.
QWill connecting catalog feeds change my conversion tracking?
Not in this setup, and that's deliberate. Catalog sync and conversion tracking are decoupled — enabling feeds doesn't add a pixel, doesn't require the native Meta sales channel, and doesn't alter how conversions fire. This matters because the common way stores end up double-firing is switching on the native channel for catalog reasons and inheriting its conversion events too.
QWhat do I need to generate Meta and Google product feeds?
A Shopify custom-app Admin API token with product read access. Paste it once and products sync on a schedule into hosted feed URLs at the per-variant grain both platforms expect — then point Meta Commerce and Google Merchant Center at those URLs. PartialLeads generates and maintains the feed; you still connect it on the platform side, since Meta and Google require that step in your own account.
QHow do I check that attribution is actually working?
Open a recent purchase and look at its journey. A correctly attributed order shows the originating ad click, the sessions in between, and the purchase — with first-touch and last-touch both recorded. Then sanity-check at the aggregate level: the share of purchases reporting as "Direct" should drop noticeably once identity stitching is running, because sales that were previously orphaned by regenerated visitor IDs now resolve to their real source.
QIs this worth it for a store doing modest ad spend?
The deciding factor is whether your reported numbers currently match your admin. If Meta says 240 and Shopify says 180, you're making budget decisions on a 33% error — and at small spend, a bad decision costs proportionally more because there's less room to absorb it. If your counts already reconcile closely and your purchases attribute to real campaigns, the marginal gain is smaller and you can wait. Run the reconciliation first; let the gap decide.

Find the qualified leads your forms are currently throwing away.

Install PartialLeads on one landing page, send traffic, and compare what your CRM captured against what PartialLeads recovered and qualified.