Meta shows fewer purchases than Shopify: why the browser pixel misses paid orders and how server-side fixes it
This is one of the most common tracking complaints in e-commerce, and it's the offline conversion problem in a different costume. Shopify says you had 100 orders. Meta says 68. Somebody is wrong, and it's usually not Shopify.
Here's why. A purchase reported by a browser pixel depends on the shopper's browser doing its job. It has to load the pixel, keep the page open long enough, and not be blocked. A lot of things can stop that. An ad blocker stops the pixel. The shopper pays with an express checkout and never reaches the page that fires the event. The browser closes before the thank-you page loads. Every one of those is a paid order the pixel never heard about.
That's what makes it "offline" in the sense that matters: the sale happened somewhere the browser script couldn't see. And the fix is the same principle as everywhere else. Report the sale from the source that knows it happened, not from the browser.
For Shopify, that source is the order itself. When an order is paid, Shopify's own server fires a webhook, however the shopper checked out, including Shop Pay, Apple Pay and other express checkouts. Sending the sale from that event doesn't depend on the browser at all.
A few practical points.
Does Shopify have a built-in Conversions API? Yes, for Meta. The Facebook and Instagram app sends events through the Conversions API when data sharing is set to Maximum. It covers Meta only. If you also advertise on Google Ads, TikTok or LinkedIn, you need the same idea for each.
Will your purchases be counted twice? They shouldn't be. When both a pixel and the order webhook report the same purchase, they should carry the same order ID, so each platform counts the order once. If they don't, you'll see the opposite problem: numbers that look better than your real orders.
What about refunds? A refunded order stays counted on Meta and TikTok in our setup. So if refunds are a big part of your business, judge the platform's numbers against net revenue.
A made-up example of the gap. 100 paid orders. 12 used an express checkout and never reached the page. 10 came from shoppers with an ad blocker. 10 closed the browser too early. That leaves about 68 that the pixel saw. Server-side from the order webhook sends all 100.
There's a bonus for stores that also take orders outside the website, like phone orders or draft orders: anything that reaches a paid order can be sent from the same source, with the customer's email or phone, and matched to the click if you have it.
Stores that also take orders outside the browser should think about those too. Phone orders, draft orders created by staff, and wholesale or B2B orders don't go through the storefront checkout, so a pixel never sees them. If they reach a paid order in Shopify, they can be sent from the same order source, with the customer's email or phone.
A short check for your store. Compare paid orders and purchases in Events Manager for one day. Then look at which orders are missing: are they express checkouts, mobile browsers, ad-blocked visitors, or manual orders? The pattern points at the cause.
And remember Klaviyo and similar tools: if your abandoned cart flows depend on browser events, the same blocking that hides purchases can hide the people who should be getting the flow.
Does your Meta number match your Shopify orders? What's the gap?
More on this: Shopify orders to your ads, and the complete guide to offline conversion tracking.