Take a worked example. Monday’s report shows a 4x return on ad spend. Return on ad spend, or ROAS, is the revenue a platform credits to your ads divided by what you paid for them. Everyone relaxes.
Month end arrives. The Shopify admin and the bank statement land about 20% below what Meta claimed for the same 30 days. Nobody lied. Three systems counted three different things, and nobody wrote down which one the business acts on.
Here is the short version, before the detail.
The short answer. Your ad platform and your bank account disagree because they count different events over different windows. Meta counts conversions it can attribute. Shopify counts orders it can trace. Fix the double counts first, then the missing events, then compare one week of orders against one week of platform purchases.
Autonomous Technologies builds and runs the systems behind Shopify stores. We work for founders and operators who are accountable for the store after launch. An inflated purchase count moves real budget to the wrong campaign every week it stands. That is why this sits inside our attribution work. Every platform claim below links to the vendor’s own current documentation, checked 21 September 2026.
The callout below names who this is for, and who it will not help.
Who this is for. You run a Shopify or Shopify Plus store. You spend your own money on ads. Your reported return does not survive contact with your admin or your accountant. Who this is not for. Stores with no paid spend. Anyone looking for a single tool that makes the numbers match. No such tool exists, because the mismatch is definitional before it is technical.
Five systems count your revenue, and none of them agree by design
Attribution is the rule a system uses to decide which channel gets credit for an order. Each system runs its own rule. That is the first half of your gap.
Shopify is plain about this. Its marketing reports default to a last click model, which credits the final channel a shopper used before buying. In Shopify’s words, last click gives “100% of attribution credit to the last channel that the customer interacts with, including direct visits”.
The lookback window is how far back a system searches to find that channel. Shopify sets it at 30 days, and it states that “if a visitor doesn’t buy anything within 30 days of a session, then the first interaction referrer is reset”. It also warns that its own figures “can differ from sales figures in other reports”.
GA4 is Google’s analytics tool, and it runs a different set. Its attribution settings offer three models: data-driven, paid and organic last click, and Google paid channels last click. Google notes that “conversions can be reattributed for up to 7 days after the conversion”. So the credit can move to another channel after the fact. A GA4 number you export on Monday can change by Friday.
Write those two windows down before anything else. Shopify looks back 30 calendar days. GA4 can still move a conversion for 7 days after it happened. The table below puts both next to three other sources, with the rule each one runs.
| Where the number comes from | What it counts | Default rule |
|---|---|---|
| Shopify marketing reports | Orders it can trace to a channel | Last click, 30 day lookback. |
| Meta Ads Manager | Conversions it can match to an ad | The windows you set per campaign. |
| GA4 | Key events, credited by model | 3 models, 7 day reattribution. |
| Your bank statement | Money that actually settled | The settlement date. |
| Your accounts | Revenue after refunds | Your monthly close. |
Read down the last column of that table. No two rows share a rule, so no two rows will ever share a number.
Bad tracking fails in two opposite directions, and one of them is worse
The second half of the gap is tracking that is simply wrong. It breaks in two shapes.
Over-reporting is the loud one. A purchase tag, a snippet of tracking code, runs twice on one order. The pixel is the small script that reports shopper activity from the browser to Meta. Meta then shows more sales than you shipped. You scale the campaign and the money is not there.
Meta’s deduplication rules exist to stop this. Deduplication means matching two copies of one event and counting them once. The server copy is the same event sent from your store’s back end instead of the shopper’s browser. The pixel’s eventID must match the server’s event_id, and the pixel’s event must match the event_name.
Meta merges them only “if they are received within 48 hours of when we receive the first event with a given event_id”. Past that 48 hour window, one order becomes two sales in the report.
Under-reporting is the quiet one, and it costs more. The browser blocks the tracking signal, so real sales never reach Meta. The dashboard says the campaign is failing. You switch off your best performer.
Apple’s WebKit team set the main cause out on 24 March 2020. Safari deletes “all of a website’s script-writable storage after seven days of Safari use without user interaction on the site”. That includes the cookie your pixel wrote, a small file that lets a site recognise a returning visitor. So 7 quiet days are enough to lose the shopper.
The callout below is the one number we will not hand you.
Do not quote a signal loss percentage you did not measure. An earlier version of this guide claimed 15% to 30% of conversions never arrive, in iOS-heavy markets. No vendor publishes that figure and it carried no period. Measure your own gap over a stated week instead. That number is the one your ad budget depends on.
Reconcile one week before you change anything
Guessing is faster, and it is why this argument repeats every month. Do this instead. It takes about an hour.
- Pick one closed week. Use the same seven calendar days everywhere.
- Export Shopify orders for those dates. Count orders and net revenue, which is what is left after refunds.
- Export platform-reported purchases for the same dates. Do not use a different attribution window in each platform.
- Write both numbers down with the dates attached. State the gap as a count and a percentage.
- Repeat for the week before. One week is an anecdote. Two weeks is a trend.
A stable gap is a definition problem. You can live with it, once it is written down. A gap that swings week to week is a tracking problem, and that one you fix.
Three checks explain most of the swing
Check one: duplicates. Run a test purchase. Watch the purchase event fire. If it fires twice from one action, your reported return is inflated. Confirm the pixel and server copies share an event id.
Check two: match quality. Open Meta Events Manager, the tool that shows what your pixel and server send, and read your Event Match Quality score. That score is Meta’s own read on how well it can tie a sale to a person. Meta scores it out of 10 and rates it Poor, OK, Good or Great. An earlier version of this guide called anything below 6.0 broken. Meta publishes no pass mark, so that threshold was invented. Track your own score across consecutive weeks instead.
Check three: thresholds and consent. Consent is the shopper’s recorded yes or no to tracking. GA4 applies data thresholds, a rule that hides rows with too few people behind them, “to prevent anyone viewing a report or exploration from inferring the identity or sensitive information of individual users”. A number that looks missing may simply be hidden.
When the plumbing is right, a measured change stands up. We moved the share of Google visitors who started a chat from 17.3% to 21.5%, across the 37 days to 23 July 2026 and the 39 days after it, and we published how. Those two figures only mean something because both windows were counted the same way.
What breaks, and who owns it
The objection is that this is analyst work and the store needs sales. Fair. The problem is that you cannot judge a campaign on a number you cannot reproduce.
These failures repeat across the stores we open. The table below lists five of them, the figure to check for each one, and the owner. Start with row one and Meta’s 48 hour merge window.
| What breaks | The figure to check | Who owns it |
|---|---|---|
| Purchase tag fires twice on one order | Orders doubled inside 48 hours | Whoever publishes the pixel. |
| Old tags left by past vendors | 1 conversion claimed by 3 scripts | Whoever holds the tag container. |
| Windows set differently per platform | 30 day Shopify against your ad window | You, in writing. |
| Refunds never removed from reported revenue | Net revenue after refunds, per week | Your finance owner. |
| Consent declined, event sent anyway | 0 consent checks before the send | You, with your privacy counsel. |
Row two deserves a line of its own. A tag container is the one place that holds all your tracking snippets, and most are junk drawers. They hold scripts from vendors who left years ago. Those tags still run and still claim credit. That failure has its own guide in ghost tags inflating your cost per acquisition.
Fix the send before you rebuild the stack
Sending events from your own server, not just the browser, is the usual next move, and it does help. Meta’s Conversions API (CAPI) is a link from your own server to Meta, carrying the same events the browser sends. Meta’s own guidance is to run it in addition to the pixel and share the same events through both.
Be honest about what that buys. It recovers events the browser dropped. It raises how well Meta matches a sale to a person. It does not line up two attribution models, and it does not reconcile anything with your bank.
The build detail sits in the server-side tagging guide, and the audience effect sits in signal loss in Facebook retargeting.
Your next step is one week of numbers, written down, with the dates attached. Pull last week’s yourself, before the next budget call, and put your name on the sheet.
Common questions
Why is my Meta revenue higher than my Shopify revenue?
Usually two causes stacked. Your purchase event fires twice, so Meta counts one order more than once. And Meta credits conversions on the windows you set, while Shopify uses last click with a 30 day lookback by default. Check for duplicates first, then compare the windows.
How big should the gap between the two be?
There is no published benchmark, so ignore anyone who quotes one. What matters is stability. Measure the gap on two consecutive closed weeks with the same dates. A steady gap is a definition difference you can document. A gap that swings is a tracking fault.
Does the Conversions API make the numbers match?
No. It recovers events the browser blocked and improves how well Meta matches a sale to a person. Meta’s own guidance is to run it in addition to the pixel, sharing the same event name and event id. Attribution models and windows stay different afterwards.
My GA4 number changed after I exported it. Is that a bug?
Probably not. Google states that conversions can be reattributed for up to 7 days after the conversion. GA4 also applies data thresholds that withhold rows to protect individual identity. Export the same dates after the window closes, and note the model you used.
What number should I actually report to the business?
Report orders and net revenue from your Shopify admin, after refunds, for a fixed set of dates. Report platform figures next to it as a separate column, with the attribution window named. One number is the truth for the bank. The other is the platform’s best guess at credit.
Sources, all checked 21 September 2026. Shopify: marketing reports and attribution models and customer events. Meta: the Conversions API, its deduplication guidance, its best practices and Event Match Quality. Google: GA4 attribution settings and data thresholds. WebKit: full third-party cookie blocking.



