top of page
Typographic Black and Blue.png

Meta Pixel Showing Duplicate Purchase Events: The Deduplication Diagnostic for D2C

You ran 18 orders today on Shopify. Meta Events Manager shows 34 Purchase events. Your reported ROAS is inflated by 80% and your campaign optimization is being fed corrupted signal. Duplicate Purchase events are the most expensive silent failure in performance marketing — and one of the easiest to spot once you know where to look.


Here's the deduplication diagnostic for Indian D2C brands.


First: Confirm the Duplication Is Real


Compare three numbers from yesterday.


  • Actual orders in Shopify — orders → all orders, filter by date.

  • Reported Purchases in Meta Events Manager — Events tab → Purchase → daily count.

  • Reported Purchases in Ads Manager — campaign view → Purchases column.


If Events Manager shows 1.5x-2x actual orders, you have duplication. If it shows 0.6-0.9x, you have undercounting (different problem).


Root Cause: Pixel + CAPI Not Deduplicating


In 2026, most Indian D2C brands run both browser pixel and server-side CAPI. Meta is supposed to deduplicate them automatically using matched `event_id` and `event_name`. When dedup fails, both events count — instant doubling of reported conversions.


The 6 Most Common Duplication Patterns


Pattern 1: event_id Missing on Pixel


Your CAPI sends event_id correctly but your browser pixel doesn't. No match key = no dedup. Most common pattern for brands that added CAPI later without updating their pixel snippet.


Pattern 2: event_id Mismatch in Format


Pixel sends `#1042`, CAPI sends `1042`. Same order, different strings. Meta string-matches strictly.


Pattern 3: Different ID Sources


Pixel uses Shopify order ID, CAPI uses a fresh UUID. Both valid, neither matches.


Pattern 4: Two Pixels Installed


Shopify's native Meta channel installs one pixel, your GTM installs another, both fire on the thank-you page. Two browser events with no event_id alignment between them.


Pattern 5: Thank-You Page Refreshed


Customer refreshes the thank-you page. Pixel fires again with the same event_id. Meta's deduplication window is 48 hours — same-day refreshes do dedup. But customers who refresh from a saved bookmark 3 days later trigger a second event.


Pattern 6: Shopify Order Edit Triggers Webhook


Order is edited (refund, address update, partial fulfillment). Shopify fires the order_updated webhook. CAPI sends a second Purchase event. Pixel didn't fire again, so no match — both count.


The Diagnostic Flow


Run this on a single test order.


  1. Place test order in incognito with Network tab open.

  2. Find pixel fire: filter `facebook.com/tr`, find Purchase request, copy event_id.

  3. Check CAPI logs: find matching event, copy event_id.

  4. Compare strings character-for-character.

  5. Check Events Manager → Test Events: should show one deduplicated entry.

  6. Open Events Manager → Diagnostics: look for Server Event Not Deduplicated warning.


The diagnostic reveals which pattern you're in. Most brands match Pattern 1 or 2.


The Fix Per Pattern


Fix for Patterns 1, 2, 3: Align event_id


Use Shopify order ID as a clean string, no `#` prefix. Pixel side: in your Custom Pixel script, pass `eventID: String(event.data.checkout.order.id)`. CAPI side: in your webhook handler, pass `event_id: String(order.id)`. Same source, same format, on both sides. See our [CAPI deduplication guide](https://www.wittelsbach.ai/post/capi-server-side-event-received-not-deduplicated-real-fix-indian-d2c-brands).


Fix for Pattern 4: Remove Duplicate Pixels


Pick one pixel install method. Shopify native + CAPI is the cleanest for most D2C. Remove the GTM-installed pixel or the manually-coded pixel. Search your theme.liquid for `fbq('init'` — should appear exactly once.


Fix for Pattern 5: Same event_id Across Refreshes


Ensure your eventID is deterministic (always the order ID, never a fresh timestamp). Refreshes within the 48-hour dedup window will then collapse correctly. For refreshes beyond 48 hours (rare), nothing helps — Meta only dedups within that window.


Fix for Pattern 6: Filter Order Update Webhooks


In your Shopify webhook handler, only send CAPI Purchase events for the `orders/create` webhook, not `orders/updated`. Order edits should not re-trigger Purchase. If you need to capture refunds, send a separate `Refund` event or use Shopify's `orders/refunded` webhook.


Validation — Confirming Dedup Works


  1. Place 3 test orders in incognito.

  2. Verify Test Events shows 3 deduplicated entries (not 6).

  3. Wait 24 hours.

  4. Check Events Manager Diagnostics — Server Event Deduplicated rate should be 95%+.

  5. Compare Events Manager Purchase count to Shopify orders — should match within 5%.


Impact on Reported ROAS After Fix


Brands that fix duplicate Purchase events typically see reported ROAS drop 30-80% — because the inflation goes away. This is correct and healthy, not a regression. The new ROAS reflects actual revenue impact. Many brands panic when ROAS drops post-dedup-fix and revert their pixel setup, locking themselves into permanent attribution corruption.


How Wittelsbach AI Audits Deduplication Continuously


Bach AI compares your Shopify daily order count to your Meta Purchase event count daily. When the ratio drifts above 1.1x or below 0.85x for 3+ consecutive days, it surfaces a deduplication issue with the specific pattern (event_id missing, format mismatch, duplicate pixels) and the exact fix needed.


Brands using the dedup audit catch duplication within 24 hours instead of weeks — preventing the corrupted reinvestment decisions that come from inflated ROAS. Try Bach AI on your account at [app.wittelsbach.ai](https://app.wittelsbach.ai).


Frequently Asked Questions


What's the acceptable ratio of Meta Purchase events to Shopify orders?


Target 0.95x to 1.05x. Below 0.95x indicates undercounting (pixel/CAPI failures). Above 1.05x indicates duplication. The 5% buffer accounts for legitimate edge cases — orders placed outside of your pixel window, anonymous purchases without identity, multi-currency conversions. Anything more than 5% drift in either direction needs investigation.


Does Meta automatically deduplicate without me sending event_id?


No. Without explicit event_id matching, Meta has no reliable way to know two events represent the same purchase. The fallback heuristics (matching IP + user agent + timestamp) are weak and unreliable. Always pass event_id explicitly on both browser pixel and CAPI. Don't rely on Meta's fallback dedup — it works maybe 30-40% of the time.


Should I use the customer's phone number or email as the deduplication key?


Neither. Use the Shopify order ID as the event_id. Phone or email are user identifiers (used for Event Match Quality), not event identifiers (used for deduplication). Mixing them up is a common mistake — phone/email belong in the `user_data` block, order ID belongs in the `event_id` field.


How long does Meta's deduplication window stay open?


48 hours. Events with matching event_id arriving within 48 hours of each other get deduplicated. Beyond 48 hours, they count as separate events. For real-time CAPI (the standard), all your events fire within seconds — dedup window is never an issue. Brands using batch CAPI (daily upload) sometimes have events arriving 24+ hours after pixel events, which still works but leaves less buffer.


Will fixing duplicate Purchase events affect my Meta algorithm's learning?


Yes, beneficially. With duplicates, the algorithm thinks certain ad variants are 2x as effective as they actually are, which biases delivery toward them and away from others. After dedup is fixed, expect a 7-14 day recalibration where Meta relearns the true performance distribution. ROAS may temporarily fluctuate during recalibration but stabilizes at a more accurate (often higher real) level afterwards.

Comments


bottom of page