Shopify gives you several ways to send the Conversions API, and they don't all send the same data. Before you trust the numbers, it's worth knowing what actually leaves the store.
The three common paths
- The native Facebook & Instagram channel, which wires the pixel and CAPI for you with almost no control over the payload.
- A Custom Pixel, where you run your own pixel and event code inside Shopify's sandbox.
- Server-side GTM or a third-party app, which gives you the most control and the most setup.
Each sends a different amount of user and event data, and that's what decides match quality.
What the native channel actually sends
The native integration is the easy button. It fires the pixel and a matching CAPI event, and it passes basic customer data Shopify already holds.
What you don't get is fine control. You can't easily add custom parameters, reshape the event, or guarantee the event_id used for deduplication, so you take what Shopify decides to send.
Why checkout changed the game
With checkout extensibility, the old habit of editing checkout.liquid is gone. Custom Pixels run in a sandbox with limited access to the page, so anything relying on scraping the DOM at checkout quietly breaks.
That sandbox is a feature, not a bug, but it means your event code has to use Shopify's pixel events, not the page.
How to control what gets sent
- Decide the source of truth: native for simple stores, Custom Pixel or sGTM when you need real control.
- Subscribe to Shopify's standard events, like checkout_completed, rather than reading the DOM.
- Set a stable event_id, usually the order id, and use it for both pixel and CAPI so they dedupe.
- Pass hashed email and phone from the order, plus fbp and fbc, to lift match quality.
Where it goes wrong
- Two integrations run at once, native plus a Custom Pixel, and every purchase is counted twice.
- The event_id differs between browser and server, so nothing dedupes.
- Post-purchase upsells fire a second Purchase with the same order id, inflating revenue.
Pick your source of truth first
The single biggest decision is which integration owns the Purchase event, and it should be exactly one. Native is fine for a simple store that just needs conversions to fire. The moment you want custom parameters, reliable deduplication, or server-side control, move to a Custom Pixel or sGTM and turn the native CAPI off.
Write the choice down where the next person will see it, because Shopify makes it trivially easy to switch on a second integration and forget.
Value, refunds, and the numbers that drift
Decide once whether value includes tax and shipping, and match whatever your finance reports use, or Meta and your books will never agree. Send refunds back too, because a store that only ever sends purchases slowly reports more revenue than it made.
Subscriptions and post-purchase upsells are the other trap. Each can fire a second Purchase, so make sure recurring charges and upsells use their own event or their own id.
What good looks like
One Purchase per order, received from both browser and server, deduplicated, with a value that ties out to the order and a healthy match score. See that on a real test order and the store is sending what you meant. It's a five-minute check that saves a quarter of confused reporting.
Shopify makes the Conversions API easy to turn on and hard to see into. Pick one source of truth, pin the event_id to the order, and check the Test Events tab, so what actually gets sent is what you meant to send.
Want a stronger data analyst role or a raise? Grab the FREE Product Analyst Playbook and get the exact roadmap to your next offer.
