Facebook CAPI and Pixel are not rivals — they are two copies of the same event, and the "duplicate events" problem happens when Meta fails to collapse them into one. The fix is deduplication: send an identical event_id and matching event_name on both the browser Pixel and the server CAPI copy of every purchase. When Meta sees a matching ID within its window, it keeps one and discards the other. If your Meta purchases suddenly show roughly twice your Shopify orders, that is a dedup misconfiguration — not real sales — and it is quietly wrecking your ROAS math.

Why you are sending the same event twice on purpose

The top guides on this topic all start in the same place, so let's be clear up front: sending a purchase from both the Pixel and CAPI is the recommended setup, not a mistake.

The browser Pixel fires from the shopper's device. It gets blocked by ad blockers, Safari and Firefox tracking prevention, and consent declines — field estimates put affected traffic around ten to twenty-five percent of users, according to Elevar's analysis via Audiense. Anything the browser drops, you lose.

The Conversions API (CAPI) fires from your server. It does not care about ad blockers or cookie prompts, so it recovers the events the Pixel missed. Run both and you get near-complete coverage.

The catch is obvious once you say it out loud: most purchases get seen by both systems. Meta receives two Purchase events for one sale. Unless you tell it those two are the same event, it counts two conversions. That is the entire "duplicate events" problem.

How Meta deduplicates Pixel and CAPI events

Meta has a documented, stable process for collapsing the two copies. Understanding it is the difference between a five-minute fix and weeks of confused reporting.

The primary method: event_id plus event_name

Per Meta's official Conversions API deduplication docs, the main mechanism is a shared identifier. You send the same unique event_id on the server event and the matching eventID on the Pixel event, along with an identical event_name (for example, Purchase). When Meta sees two events carrying the same event_id and event_name, it treats them as one conversion and keeps a single copy.

The word "identical" is doing all the work. If your Pixel comes from one app and your CAPI comes from another, the two systems generate their IDs independently, the IDs never match, and every purchase double-counts. This is the single most common cause of duplicates in the wild.

The fallback: fbp and external_id

If no shared event_id is present, Meta falls back to matching on event_name combined with the fbp browser cookie and, optionally, external_id. This is weaker — the server event is only discarded if the browser event arrives first — so treat it as a safety net, never the plan.

The dedup window and which copy survives

Two more rules matter for reconciliation. Meta only deduplicates events received within 48 hours of the first event carrying that event_id. And when it does collapse a pair, it keeps the event it received first, assuming the two copies don't differ materially in content. So if your server fires instantly and your Pixel arrives seconds later, the server copy usually wins — which is why rich, well-matched server payloads matter.

The one thing you must not hash

Hash your PII — email, phone, name — with SHA-256. But never hash fbp or fbc. Meta's Business Help guidance is explicit that hashing those cookies breaks matching and tanks your Event Match Quality (EMQ) score. Only set fbc when a real fbclid is present in the URL; fabricating one corrupts attribution.

The tell: Meta showing ~2x your Shopify orders

Here is the diagnostic the thin articles skip. A healthy redundant setup does not inflate your numbers — it keeps the count stable while recovering blocked events.

So watch the ratio. A normal, structural gap between Meta-reported purchases and Shopify orders sits around twenty to thirty-five percent on the default seven-day-click, one-day-view window, according to Vaizle and TrackBee. That gap is mostly view-through and modeled conversions — it is expected and it is not double-counting.

But if Meta shows roughly double your Shopify order count, that is not a windowing artifact. That is a dedup failure, plain and simple. Adding CAPI should never make your conversion count jump; if it did, your event_id values aren't matching. Understanding which mismatches are structural and which are broken is the heart of reconciling your ecommerce data across every tool you run.

A worked example: what a dedup bug costs you

Say you sell a print-on-demand mug. Product cost through your supplier is fourteen dollars, you sell it for forty dollars, and your Meta ad spend for the week is eight hundred dollars. You get one hundred real orders.

With deduplication working correctly, Meta reports somewhere near seventy-eight purchases (the honest gap: view-through buyers plus a few modeled conversions, minus refunds it never subtracts). Your reported ROAS is roughly 78 × $40 ÷ $800 = $3.90 return per dollar. Inflated versus reality by the structural gap, but stable and trustworthy as a trend line.

With deduplication broken, Meta double-counts and reports around two hundred purchases. Now your reported ROAS looks like 200 × $40 ÷ $800 = $10.00 return per dollar. You are elated. You scale the budget.

But your true per-order profit is $40 − $14 product − roughly $8 blended ad cost − about $1.46 in payment processing (Shopify Payments runs about 2.9% plus 30¢ on the Basic plan for US cards) = $16.54 real profit per order. The phantom ROAS told you every dollar returned ten; the real orders don't exist. You scale spend against sales you never made, your cost per real acquisition doubles, and the profit that looked healthy evaporates. The dedup bug didn't just distort a dashboard — it told you to burn money.

That is why this is a profit problem, not a reporting nitpick. The number you optimize against has to match the cash in the bank.

Fixing duplicates without breaking coverage

The goal is redundancy with deduplication — full coverage, single count. A practical checklist:

  • Use one source for both signals. The cleanest setups generate the Pixel and CAPI events from the same system so the event_id is guaranteed identical. Two separate apps injecting their own pixels is the classic way IDs drift apart.
  • Verify in Events Manager. Meta's "Test Events" and the event overlap breakdown will flag when Pixel and Server events are not being deduplicated. If it shows a low dedup rate, your IDs aren't matching.
  • Match on event_id, not the fallback. Don't lean on fbp. Send an explicit, identical event_id per order.
  • Keep the payload consistent. Same event_name, same currency and value conventions on both copies, so Meta doesn't treat them as "materially different" and refuse to merge.
  • Don't hash the wrong fields. SHA-256 on PII, raw fbp/fbc.

If you are weighing whether the server side is worth the setup effort at all, our breakdown of whether server-side tracking on Shopify is worth it walks through the tradeoffs for a POD store. And because CAPI recovers events but does nothing for channel attribution, pairing it with clean UTM tracking on your Shopify ads is what keeps your source reports readable.

What deduplication does NOT fix

This is the misconception every ranking article should lead with and most bury. Fixing duplicates makes your count honest. It does not make Meta and Shopify agree.

Even with flawless dedup, Meta still credits view-through conversions Shopify never sees, still reports modeled conversions for iOS opt-outs, still reports on the ad-click date rather than the purchase date, and still uses a windowed attribution model against Shopify's last-click. Those are methodology gaps, not tracking gaps — no dedup key closes them. Expect a stable twenty-percent-plus structural gap to remain, and stop trying to force the two to equal.

The durable fix is to stop treating any single platform's number as truth and instead reconcile them against your server-side order record. Building a reliable, store-side view — the kind that first-party attribution on Shopify is designed to give you — is what lets you trust a ROAS figure enough to act on it.

Where PodVector fits

PodVector connects Shopify, Meta Ads, Google Ads, Printify, and Printful, then computes your true per-order profit — so the number you scale against is the one that reconciles to your payout, not a platform's self-credited count. Victor, our AI employee, reads that live data warehouse, analyzes where your reported conversions and your real orders diverge, and proposes moves you approve. Victor reads your ad data but does not touch your ad account — the actions he executes are Shopify-side, and always with your sign-off. Victor is not a dashboard; he is an employee that surfaces the profit story your platform numbers hide.

If you also sell on other marketplaces, our guide to linking Etsy sales with your Shopify data is a good next step for a single source of truth.

Ready to stop optimizing against phantom conversions? Connect your store to PodVector and see your true per-order profit.

FAQs

Does adding CAPI increase my conversion count?

It should not. Correct redundant setup keeps your count stable while recovering events the browser Pixel lost to ad blockers and consent declines. If your count jumped after adding CAPI, that is a deduplication misconfiguration — your Pixel and server events aren't sharing a matching event_id — not extra sales.

What is the deduplication window for Pixel and CAPI events?

Meta only deduplicates events received within 48 hours of the first event carrying that event_id, per its developer documentation. Events that arrive outside that window are treated as separate conversions, so make sure both copies of each purchase fire close together.

Which event does Meta keep when it finds a duplicate?

Meta keeps the event it received first, assuming the two copies don't differ materially in content. In most server-fast setups that means the CAPI copy survives, which is why you want your server payload to carry rich, well-matched customer information.

Should I hash the fbp and fbc cookies?

No. Hash PII like email and phone with SHA-256, but never hash fbp or fbc. Meta's guidance is clear that hashing those cookies breaks matching and lowers your Event Match Quality score. Only set fbc when a genuine fbclid appears in the URL.

If I fix duplicates, will Meta finally match Shopify?

No — and that is the trap. Deduplication makes your count honest, but Meta still reports view-through and modeled conversions on the click date against a windowed model, while Shopify records only completed orders on a last-click basis. A structural gap of roughly twenty to thirty-five percent remains normal, according to Vaizle. Reconcile against your server-side order record instead of chasing equality.

How do I know if my duplicates are actually a problem?

Watch the ratio of Meta purchases to Shopify orders. A gap of twenty to thirty-five percent is expected structural inflation, per TrackBee. But Meta showing roughly double your Shopify order count is the signature of a dedup failure — real sales don't arrive in perfect 2x multiples, but double-counted events do.