
15 Sept 2026
Every retail marketing team we meet has three numbers for last month's sales. Meta Ads Manager has one. GA4 has another. Finance has the order table, and it is lower than both. Somebody has usually built a spreadsheet to explain the gap, and the spreadsheet has usually stopped being updated.
The order table is the only one of the three that is money. The other two are estimates, produced by systems with their own incentives, and the question is not which is right. It is which parts of the gap are by design, which are mistakes, and what the mistakes are costing you.
Some of the difference is built in, and you should not try to remove it.
Attribution windows. Meta's default counts a purchase if the buyer clicked an ad in the previous seven days or saw one in the previous day. GA4 uses a different model with a different window. The order table has no window at all: a sale is a sale. Two systems with different rules for what counts will produce different totals, and that is expected.
Attribution models. A customer who clicked a Meta ad, then a Google ad, then typed your URL will be claimed in full by Meta, in full by Google, and once by the order table. Add the platform numbers together and you will exceed reality every time, because each platform is answering the question "did we touch this sale?" rather than "did we cause it?"
Timing. Ad platforms date a conversion by the event they received. The order table dates it by when the order was placed, or fulfilled, or invoiced, depending on who set it up. A month-end report pulled from each will disagree at the boundary.
None of that is a fault. It is three systems measuring three different things. The problem starts when the gap is bigger than those explanations cover, and it usually is.
Double counting. The most common bug we find in a Health Check is a purchase event firing twice: once from the browser pixel and once from the Conversions API, without the deduplication key that tells Meta they are the same sale. Meta counts both. Your reported conversions inflate, your cost per acquisition looks better than it is, and the algorithm optimises towards whatever produced the doubled signal.
Test and cancelled orders. Staff placing test orders, customers cancelling before dispatch, and payment failures that still fired a purchase event all sit in the ad platform total and not in the order table.
Returns. A sale returned three weeks later is still a conversion as far as Meta and Google are concerned. Nobody sent them the refund. In categories with high return rates the platforms are optimising towards customers who buy and send back, and they have no way of knowing.
Currency and tax. The order table holds net revenue in your reporting currency. The pixel often sends gross, including VAT, sometimes in the currency of the storefront the customer used. The counts can match while the revenue is wrong by a fifth.
Consent and blocking. A material share of your visitors reject non-essential cookies, run an ad blocker, or use a browser that limits tracking. Their purchases reach the order table and never reach the ad platform. This pushes the platform number down, not up, so it partly masks the inflation from the other faults. Two errors in opposite directions can look like accuracy.
The method is not complicated. It is tedious, which is why it does not get done.
Pick the source of truth. The order table, or the CRM if that is where the sale is finally confirmed. Everything else is measured against it.
Match on order ID. Make sure the purchase event carries the order ID, and that the ad platforms receive it. Without a join key you are comparing totals, which tells you there is a gap but never why.
Categorise every unmatched row. Duplicates, test orders, cancellations, refunds, currency, consent. Each has a different fix.
Agree a tolerance. Platform-reported conversions will never equal the order table, because of the attribution differences above. Decide what an acceptable gap looks like, in writing, before anyone starts fixing things.
Fix the accidents, keep the design. Deduplicate the pixel and API. Suppress test orders. Send refunds back as conversion adjustments. Send net revenue in one currency. Leave the attribution windows alone.
When that is done, the ad platforms are bidding on something close to what you sold, and the gap that remains is one you can explain to a finance director in a sentence.
The report is the least of it. Meta and Google spend your money according to the signal they receive. If purchases are doubled, the algorithm learns the wrong customers are profitable. If returns never come back, it learns that people who return things are your best buyers. If a slice of real sales never arrives at all, it learns that some of your best channels do not convert.
You are not just misreporting. You are training the thing that spends the budget on a distorted version of your business.
Reconciling one month of purchases against the order table is the first thing we do in a Stack Teardown, and it is the part that most often changes what the client thought was true. It takes a day with the right people in the room. If you would rather do it yourself, the five steps above are the whole method; what you need from us is only the experience of having seen where it goes wrong before.