Korant

What to do when Shopify, Meta, and GA4 disagree

What the numbers say

  1. 01

    On a modelled 1,000-order month, GA4 records 934 purchase events, a 6.6% client-side loss before any attribution logic runs.

    Modelled on stated assumptions: ad blockers, tracking prevention and sessions terminated before the purchase event fires.

  2. 02

    A modelled 210 of Meta's 640 reported conversions are view-through, recorded with no click at all.

    Modelled on stated assumptions using a 7-day click, 1-day view attribution setting.

  3. 03

    Restating Meta's conversions from ad-interaction date to order date moves a modelled 4.2% of them into a different calendar month.

    Modelled on stated assumptions: a 9-day median time to purchase against month boundaries.

  4. 04

    After reconciliation, the three systems agree on a modelled 812 of 1,000 orders, leaving 188 that only one system can see.

    Modelled on stated assumptions, worked through in the reconciliation section.

  5. 05

    Averaging the three reported totals gives 858 orders, a number 14% below the actual 1,000 and matching no system's definition.

    Derived from the modelled reported totals of 1,000, 934 and 640.

Three systems, three numbers, one month. Shopify says 1,000 orders. GA4 says 934 purchases. Meta says 640 conversions.

None of these is a data quality problem and none of them will converge by fixing a tag. They are three different measurements of three different events, and the reconciliation below is arithmetic rather than debugging.

What each system is counting

Shopify counts orders created. The event is server-side, fires on order creation, and is as close to unconditional as anything in this stack gets.

GA4 counts purchase events fired by a browser. That event depends on a script executing on a page the customer actually reached, in a session the analytics library still recognises.

Meta counts conversions attributed to an ad. The unit is neither an order nor a page view but a claim: this ad was interacted with, and within our window an order followed.

Three different units. Nobody should expect three different units to produce the same integer.

The three variables that cause every discrepancy

The event. Server-side order creation against a client-side pixel against an ad-platform conversion claim.

The timestamp. Shopify and GA4 record when the order happened. Meta credits the conversion back to the date of the ad interaction, which means a sale placed on the 2nd can land in the previous month’s ad report. On a modelled nine-day median time to purchase, 4.2% of conversions cross a month boundary this way.

The window. Meta at 7-day click and 1-day view, Google Ads commonly at 30-day click, GA4 on last non-direct click with its own lookback. An order is inside one window and outside another with no contradiction involved.

The reconciliation table

Modelled on a 1,000-order month at ₹1,450.

SystemCountsTimestamped byWindowModelled total
ShopifyOrders createdOrder creationNone1,000
GA4Purchase eventsSession timeLast non-direct click934
Meta Ads ManagerAttributed conversionsAd interaction7-day click, 1-day view640
Google AdsAttributed conversionsAd interaction30-day click310
KlaviyoAttributed conversionsEmail click5-day last click190

Read the fourth column before the fifth. Every number in the last column is only interpretable alongside the rule that produced it, and stripping the rule is how these get added together on a notepad.

GA4’s 934 against Shopify’s 1,000 is a 6.6% client-side loss: blocked scripts, tracking prevention, sessions that ended before the purchase event fired. That gap is not attribution at all, it is data capture, and it is the only line here that server-side tracking genuinely fixes.

Step 1: fix the denominator

Shopify’s order count is the denominator. Every other number becomes a share of it.

This is a policy decision, not a technical one, and it settles most arguments before they start. Shopify took the money, its record is server-side, and it is what the accounts reconcile against.

Once the denominator is fixed, the question changes from “which number is right” to “what share of these 1,000 orders does each system claim”, which is answerable.

Step 2: restate everything on order date

Export ad-platform conversions with the order date rather than the ad interaction date wherever the platform allows it, and where it does not, accept a known lag rather than pretending it is zero.

A modelled 4.2% of Meta conversions move calendar months under this restatement. That is small in a steady month and large in a month with a campaign that started on the 28th.

Do this before comparing anything month over month, or a launch date will produce a discrepancy that looks like a channel effect.

Step 3: separate view-through from click

Split Meta’s 640 into 430 click-based and a modelled 210 view-through. Keep them in separate columns permanently.

View-through is a real signal for some categories and close to noise for others, and the only way to ever find out which you are is to have kept the two apart. Folding them together is irreversible without a rebuild.

If you report a single Meta number to anyone who makes budget decisions, report the click number and footnote the view-through.

Step 4: deduplicate against the order list

Join every platform’s claimed orders to the actual Shopify order IDs and count distinct.

Claimed conversions across the four platforms sum to 1,260 against 1,000 real orders, so at minimum 260 orders are claimed twice. In the model, 812 orders are claimed by at least one system after deduplication, and 188 are claimed by none.

Deduplication requires an order-level join, which means order IDs have to be present in whatever you are comparing. Platforms that only report aggregates cannot participate in this step, and that limitation should itself be recorded in the report rather than worked around.

Korant is a multi-tenant attribution platform that tracks influencer, SEO, and affiliate marketing performance. Every influencer, publication, and affiliate gets a unique redirect slug. Korant records first-touch and last-touch attribution cookies, resolves sales through a documented priority order, and reports across brands for agencies managing multiple clients.

Korant is not for stores with a single paid channel, or for brands that only need Shopify’s native reports. With one channel there is no deduplication problem, because nothing is competing for the same order.

Step 5: report the residual

188 orders claimed by nobody. Publish that as its own line.

The residual is the most informative number in the reconciliation and the one most likely to be deleted before a report goes out. A large residual means either real dark demand, which is worth investigating, or broken tracking, which is worth fixing, and both are actionable in a way that a tidy 100% pie chart is not.

Track it monthly. A residual that grows steadily usually means a tracking regression somewhere, and it will show up here months before it shows up as a revenue problem. The mechanics of assembling this into a permanent report rather than a monthly scramble are in building a single source of truth for marketing spend.

Why averaging the three is the worst option available

Somebody will propose averaging. Shopify’s 1,000, GA4’s 934 and Meta’s 640 average to 858.

That number is 14% below actual revenue-generating orders and corresponds to no definition used by any system in the stack. It cannot be defended to a CFO, cannot be reproduced by anyone else, and quietly understates the business.

The honest output of this exercise is not one number. It is 1,000 orders, a stated share claimed by each channel under a stated rule, and a named residual. Anyone who wants a single figure is asking for a simpler business than the one you are running, and the reconciliation above is the shortest path to explaining why.

Two limits worth stating. This method makes the systems comparable and does not make any of them causal, so a channel that claims 300 orders may have caused far fewer. And the whole exercise assumes windows stay fixed, so changing an attribution setting mid-quarter invalidates the trend you were building, which is a good reason to set them once and leave them alone.

The tool for this · Attribution platform Korant Korant keeps first-touch and last-touch as separate numbers, which is the only way to see what opened the sale versus what closed it.

Questions people actually ask

Why do Shopify and GA4 show different order counts?

Shopify records an order when the order is created server-side, which is close to unconditional. GA4 records a purchase event fired by a browser, which fails when a script is blocked, a session ends early, or a customer completes payment in an app. The gap is structural and usually runs between 5% and 15%.

Which number should I trust as the real revenue figure?

Shopify, always. It is the system that took the money, its count is server-side, and it is what your accounts will reconcile against. Every other platform's number is a claim about influence expressed in units of orders, which is a different type of measurement wearing the same label.

Should I use Meta's reported conversions for budget decisions?

Use them for relative comparisons between Meta campaigns, where the measurement bias is at least consistent. Do not use them against other platforms or against Shopify, because Meta counts view-through, credits conversions to the ad date, and has no visibility into touches from any other channel.

Does server-side tracking fix the discrepancy?

It fixes the data loss portion, not the attribution portion. Sending order events from a webhook instead of a browser recovers most of the missing 6.6%, and Meta will still count view-through, still use its own window, and still not know about the Google click three days earlier.

How often should I run a reconciliation?

Monthly, on the same day, with the same window settings. The purpose is not a perfect answer but a stable method, because a consistent gap can be trended while a gap that changes shape every month tells you nothing about the business.

Written by Nayak — Builds checkout, referral and attribution tooling for Shopify D2C brands