Meta Says 105 Purchases. Shopify Says 30. Who's Lying?
Nobody — but one of you might be double counting. The two-minute dedup check that forks every diagnosis, the nine causes sorted by gap size and direction, the honest 'how far apart is normal' answer, and a 70-minute worked cleanup of the classic 105-vs-30 case.

Check one number first: the Purchase dedup rate in Events Manager. Under 80% means you’re double-counting — fixable in an hour with a shared event ID. At 95%+ your tracking is fine and the gap is attribution: Meta reporting 10–25% more than Shopify is normal, because they count different things on different clocks.
DEDUP <80% = DOUBLE COUNT 95%+ = HEALTHY +10–25% GAP IS NORMAL DIFFERENT CLOCKS
The two-minute check that settles most cases

Dedup rate is the fork in the road — everything else in this guide depends on which branch you're on.
The forum version of this problem ("Meta shows 105 purchases, Shopify shows zero — is Facebook stealing from me?") almost always skips the one diagnostic that separates broken from normal: the deduplication rate. Meta receives your Purchase event twice by design — once from the browser pixel, once from the Conversions API — and merges the copies using a shared event_id. When that merge works (95%+ dedup rate), every real order counts once. When it doesn't — no event_id, mismatched IDs, or a third sender nobody remembers installing — every order counts twice, and your dashboard inflates toward that mythical 105. Meta's own deduplication documentation covers the mechanics; the operational summary is simpler: the fix is sending the order ID as the event_id from both sides, and the verification is watching browser+server rows merge with a checkmark in Test Events.
The three mismatches (and which one you have)

Gap size and direction diagnose the cause — treat the branch you're actually on.
Direction is diagnostic: 2-3x high = duplication (fixable), modestly high = attribution (definitional), low = signal loss (fixable). Most panicked threads conflate all three.
The part nobody says out loud: they're answering different questions
Shopify's order count answers "what happened in my store?" Meta's purchase count answers "what do I estimate my ads caused, under my attribution settings?" Those are different questions and their answers differ legitimately: a customer who clicked your ad Tuesday and bought Friday is a Friday order in Shopify and a Tuesday conversion in Ads Manager (purchases report on the click's date — which alone destroys every day-level comparison). A customer who saw-but-didn't-click and bought within a day is a view-through conversion Meta claims and Shopify can't see the reason for. A repeat buyer who engaged with two campaigns may be claimed by both in some views. And on iOS traffic, part of Meta's number is modeled — a statistical estimate of conversions it can no longer observe directly. Stack those legitimacies and a clean, well-deduplicated account still reports 10–25% more purchases than the store most months. That's not fraud; it's epistemology. The number to escalate about is 2–3x — that's never attribution; that's duplication.
The full 10-minute audit, in order
1. Dedup rate (Events Manager → Purchase): under 80% → fix event_id and stop here; the rest is noise until this is clean. 2. Sender inventory: list everything that can fire Purchase — Shopify's channel app, any tracking app, manual pixel code, GTM containers, old theme snippets. One integration owns the event; disable the rest. (After Shopify's checkout-extensibility migration, "the old snippet still in the theme" became the classic silent double-counter.) 3. Test purchase: Test Events tab open, buy something cheap, watch for exactly one merged Purchase with browser+server icons. 4. Attribution accounting: switch reconciliation reports to click-only columns and compare cohorts (a week of clicks vs the orders those clicks produced) rather than calendar days. 5. Direction check: if Meta is below the store, the problem inverts — you're losing signal (no CAPI, pixel-only setups, consent banners, ad blockers) and delivery optimization is starving; the fix is server-side events with real match keys, not reporting hygiene. 6. Monthly truth: whatever the dashboards say, reconcile net revenue and blended MER once a month — the number that survives refunds, definitions and modeling. This audit catches the 2026 wrinkle too: after the January and March definition changes, older comparisons broke — any reconciliation crossing those dates needs rebaselining first.
The third witness: what GA4 adds to the argument
Once Meta and Shopify are reconciled, many operators pull in GA4 and reopen the panic — because GA4 shows a third number, usually the lowest of all. That's expected: GA4 runs last-click attribution by default, loses cross-device journeys the platforms model, undercounts everything consent banners and tracking prevention eat, and books conversions on the order's date rather than the click's. The triangle is stable in a healthy account: Shopify highest fidelity on WHAT happened, Meta highest (and premium-priced) on WHAT ADS CAUSED, GA4 lowest but most neutral on the journey. Escalate only when the triangle's shape changes suddenly — a corner moving alone is a tracking event, all three moving together is a business event. The full three-way framework gets its own guide shortly; for reconciliation purposes, two witnesses (store + dedup-clean Meta) are enough.
Worked example: 105 vs 30, dissected
The composite behind a hundred threads: a home-goods store, new to Meta, sees 105 purchases in Ads Manager against 30 Shopify orders for the same week. Audit: dedup rate 51% — the store runs Shopify's Meta channel app AND a tracking app AND a theme snippet from a 2024 tutorial, three senders with no shared event_id. Cleanup (channel app keeps Purchase; app's duplicate sender disabled; snippet deleted) drops the report to 41. Still 37% over — cohort analysis explains the rest: 6 view-through conversions, 3 window-timing artifacts from the prior week's clicks, 2 modeled. Final steady state: Meta ~36-38 against 30 store orders — a 20-25% definitional premium the owner now understands instead of fears. Total fix time: 70 minutes. The panic had lasted three weeks. Postscript worth noting: the store's CPA reporting stabilized within a fortnight of the fix — not because performance changed, but because delivery stopped learning from phantom purchases, and budget decisions stopped being made against a dashboard that priced conversions at half their real cost.

Count once, then let the definitions differ — reconciliation is a monthly discipline, not a daily argument.
Frequently asked questions
Why does Facebook show more purchases than my Shopify store?+
What is a normal difference between Meta purchases and Shopify orders?+
Where do I check my deduplication rate?+
What should I use as the event_id?+
Why do purchases show on days when I got no orders?+
Meta shows FEWER purchases than Shopify — same problem?+
Can duplicate events hurt performance, or just reporting?+
How do I find every source firing the Purchase event?+
Did Shopify's checkout changes cause my duplicates?+
Do refunds explain part of the gap?+
Which number do I actually optimize and report from?+
Did the 2026 attribution changes affect this comparison?+
Is Triple Whale / an attribution tool the answer?+
How often should I re-verify all this?+
Does double counting affect my billing or just my reports?+
My agency says the gap is 'just iOS' — is that a sufficient answer?+
Clean signal, steady accounts
Whitelisted infrastructure — stable rails under your tracking, headroom over your scaling, replacement cover when reviews misfire.