TL;DR
Most "our tracking is broken" investigations start in the wrong place, because they start with a symptom instead of a pair. Shopify documents this across four pages: a discrepancies hub, a sales-discrepancies page, a customer-and-session page, and a page on accounting for discrepancies in legacy Analytics data [1][2][3][4]. Read them together and a pattern shows up. A large share of what merchants report as broken tracking is two systems counting different things on purpose: a session that ends at midnight UTC, a return that is not a refund, a report grouped by hour instead of by day. Those cases need a definition, not a fix. The remainder, the genuine delivery failures, are narrower than they look, and they have their own checks. This article is the routing layer. Find your pair in the table, read the bucket that owns it, then follow the link into the deep-dive that covers it properly.
Which Two Numbers Actually Disagree?
Write both down before you open anything else. "GA4 is wrong" is not a pair. Take an illustrative pair: Shopify shows 412 orders yesterday and GA4 shows 366 purchases. That is a pair, and it already rules out two of the three buckets.
| The two numbers that disagree | Family | First check |
|---|---|---|
| Shopify sessions vs GA4 sessions | Shopify vs third party | Session definitions and reporting time zones, before anything else [1][3] |
| Shopify orders vs GA4 purchases | Shopify vs third party | Consent state, blocking extensions, JavaScript and cookie availability [1] |
| Shopify orders vs ad platform conversions | Shopify vs third party | Attribution window and model first, then deduplication |
| Sales report vs orders export | Shopify vs Shopify | Test orders and custom-amount refunds without restock [2] |
| Sales report vs Payments finance report | Shopify vs Shopify | Returns and refunds are separate items [2] |
| One custom report, different totals | Shopify vs Shopify | Grouping dimension, for example Day against Hour [2] |
| Sessions converted vs total orders | Shopify vs Shopify | Multiple orders in one session, last click, converting session [3] |
| A number that moved with no change on your side | Incomplete or missing data | Look for the alert icon Shopify displays on affected reports and metrics [1], then the legacy Analytics data page if the report is a legacy one [4] |
| A metric dropped after a cleanup | Incomplete or missing data | Deleting an order, customer, product, or variant removes its data from reports [1] |
The table is the whole method. Everything below explains why a row lands where it does.
Family One: Shopify Against a Third-Party Tool
This is the bucket everyone assumes they are in, and often they are. Shopify's hub page lists six causes for a Shopify-versus-Google-Analytics gap, and they are worth reading in full [1].
Page reloads and unique visitors get counted differently. Google counts every page reload, but a browser doesn't count reloads of cached pages [1]. Session definitions differ between platforms, and Shopify notes that some software counts search bots as visitors. Google Analytics "can only count visitors with JavaScript and cookies activated." Then: browser extensions that block Google Analytics outright, reporting time zones that do not match, and the plain fact that each platform uses its own proprietary tracking mechanisms that are not identical [1].
Notice what is missing from that list. None of the six is "your pixel is misconfigured." Shopify is describing a floor of structural difference that exists on a perfectly healthy store. The number that matters is not whether the two tools match, it is whether the gap is stable. A stable gap is a definition. A gap that appeared last Tuesday is an incident. Our Shopify Analytics against GA4 breakdown walks the revenue side of this in detail, and the blocking-extension cause has its own piece on what ad blockers do to conversion tracking.
Ad platforms are a different animal inside the same bucket. When Shopify says 412 orders and Google Ads says 318 conversions, the gap is usually the attribution window and the counting rule, not delivery. Google counts a conversion against the date of the ad click, Shopify counts an order against the date of the order, and those two dates are frequently not the same day. Start with attribution windows and reporting delays, then with why Google Ads reports fewer conversions than Shopify. Google itself moved on this in January 2026, shipping per-conversion attribution settings and describing the goal as eliminating a common cause of conversion reporting discrepancies against Google Ads [5].
Consent belongs in this bucket too. Shopify states plainly that in regions where a consent banner is required, data is collected only after the visitor consents [3]. Every visitor who declines is a visitor neither platform will count the same way, and no amount of tag debugging changes that.
Why Don't Sessions and Orders Line Up?
Because a Shopify session is a specific object with two endings, and almost nobody knows the second one.
Shopify's session is cookie-based. It ends after 30 minutes of inactivity, and it also ends at midnight UTC [3]. That second rule is the one that quietly reshapes reports. A shopper browsing at 01:30 in Sydney is mid-session at midnight UTC and gets cut into two sessions. A shopper in Los Angeles who starts at 16:00 and buys at 17:30 stays in one. Your session counts therefore carry a shape that has nothing to do with your store and everything to do with where your buyers sleep. If you have ever compared a European day against a North American day and wondered why sessions per order look different, that is this.
Two more things on that page do real damage when they are unknown. Visitors and customers are approximations, and a column total of unique people may be higher or lower than the sum of its rows [3]. And sessions converted is normally lower than order count, for reasons that are all definitional: one session can produce several orders, attribution is last click, the credit lands on the converting session, and a buyer who returns directly to place the order shows up as Direct [3].
That last mechanism is the single most common source of "our paid traffic stopped converting" panic. It is covered properly in why Shopify marks logged-in and cross-device orders as direct. The report layer that renders it is explained in how the channel performance report attributes.
One small trap for anyone testing their own store: only opening it with the View store button avoids a session. Any other method of viewing your online store on desktop counts as a session in your reports [3].
Family Two: Two Shopify Reports, One Store, Different Answers
Nothing external is involved here, which is why this bucket is the fastest to resolve once you know it exists. Shopify's sales-discrepancies page is essentially a list of places where two internal reports answer slightly different questions [2].
Returns and refunds are separate items. Sales reports show returns; the Payments finance report shows refunds. A refund that is still pending stays positive until it completes. Restock an item without refunding it and the tax might display as a return amount. Each of those is correct behavior in both reports, and each produces a mismatch when you assume the two words mean the same thing [2].
The Sales report and the orders export diverge in two documented places. A refund entered as a custom amount with no restock appears only in the export. Test orders are excluded from Sales reports but included in the orders export [2]. If you have ever exported orders to prove a report wrong and found the export had more rows, that pair is where to look first.
Then the vocabulary. Gross sales, net quantity, and ordered quantity are three different measures, and a report that mixes them will not reconcile against one that does not [2]. Custom reports add their own effect: the same data grouped by Day and by Hour can produce different totals. Shopify's own fixes are to add the Order ID dimension, and, in ShopifyQL, to filter with WHERE rather than HAVING [2].
Subscriptions and post-purchase upsells sit at the edge of this bucket, because both create orders whose value changes after creation.
Family Three: The Data Itself Is Incomplete
The third bucket is neither a tracking failure nor a report-definition question. Shopify's data can be temporarily incomplete or delayed, and when it is, an alert icon displays on the affected reports and metrics [1]. That icon is the first check. If it is there, the number is not final, and nothing on your side needs fixing.
Deleting things has a permanent version of the same effect. Deleting an order, a customer, a product, or a variant removes its data from your reports [1]. A metric that dropped right after a catalog cleanup is usually this, not tracking.
Legacy reports have their own accounting. Shopify's page titled "Accounting for discrepancies in legacy Analytics data" covers how legacy Analytics data reads following the October 2024 reporting framework update [4]. If the number you are comparing comes from a legacy report, read that page before you compare anything else.
It earns a bucket of its own because it fails every other diagnostic. Your tags are fine, your reports agree with each other, your ad platform gap is stable, and the number still does not behave. Nothing in your store caused it, and no amount of tag debugging will find it.
So When Is It Actually a Tracking Problem?
Work the three buckets first, and what is left is the genuine tracking work. It is a short list.
Double counting is the visible one, and it happens when a browser event and a server event describe the same purchase without a shared identifier. That is what deduplication solves, and how event_id prevents double counting covers the mechanism. Under-matching is the quieter one: events that arrive but carry too little customer information for the platform to attribute them. And a value gap on a multi-currency store is usually denomination, not delivery, which multi-currency conversion values explains.
WeltPixel Conversion Tracking records each order's server-side purchase as sent, so webhook retries and concurrent deliveries do not resend it, and browser events respect Shopify's Customer Privacy API signals [6]. That removes two causes from the residual list. It does not remove the other three buckets, and no app can, because those are definitions rather than defects.
Key Takeaways
- Name the pair of numbers first. The pair tells you which of the three buckets you are in, and each bucket has a different first check.
- Shopify lists six causes for a Shopify-versus-Google-Analytics gap, and none of them is a misconfigured pixel: reload counting, session definitions, JavaScript and cookie availability, blocking extensions, time zones, and non-identical tracking mechanisms [1].
- A Shopify session ends after 30 minutes of inactivity and also at midnight UTC, so session shape depends on where your buyers are [3].
- Returns are not refunds, test orders are in the orders export but not in Sales reports, and Day and Hour groupings of one custom report can total differently [2].
- Sessions converted is expected to be lower than order count: one session can hold several orders, credit goes to the converting session under last click, and a direct return reads as Direct [3].
- If a number moved and nothing on your side changed, look for the alert icon Shopify shows when data is incomplete or delayed, check whether something was deleted, and read the legacy Analytics data page if the report is a legacy one [1][4].
FAQ
Why does GA4 show fewer orders than Shopify?
Usually because the two tools count different populations. Shopify lists visitors without JavaScript or cookies, blocking browser extensions, differing session definitions, mismatched reporting time zones, and non-identical tracking mechanisms as causes [1]. In consent-banner regions, data is collected only after consent, so declining visitors are counted differently by each system [3]. A stable gap is a definition. A gap that appeared on a specific date is an incident worth investigating.
Do Shopify sessions and GA4 sessions measure the same thing?
No. Shopify's session is cookie-based, ends after 30 minutes of inactivity, and also ends at midnight UTC [3]. Other platforms apply their own rules, and Shopify notes that some software counts search bots as visitors [1]. Compare trends between the two rather than absolute counts.
Why does my Sales report total differ from my orders export?
Two documented reasons. Refunds entered as a custom amount without a restock appear only in the export, and test orders are excluded from Sales reports while the orders export includes them [2]. Check both before assuming a data loss.
Why is sessions converted lower than my order count?
By design. A single session can produce more than one order, attribution is last click, credit is assigned to the converting session, and a buyer who leaves and comes back directly to order is recorded as Direct [3].
How do I know a discrepancy is a real tracking problem?
Rule out the other two buckets first. If both numbers come from Shopify, it is a report-definition question. If the report carries an alert icon, or the underlying record was deleted, the data is incomplete rather than untracked [1]. What survives both is delivery, and that is where deduplication, event matching, and currency checks belong.
If you want server-side conversion delivery across GA4, Meta, TikTok, Google Ads, Reddit, Pinterest, Snapchat, and OpenAI (ChatGPT) ads, install WeltPixel Conversion Tracking.
Sources
- Shopify Help Center, "Analytics discrepancies", help.shopify.com/en/manual/reports-and-analytics/discrepancies, accessed August 24, 2026
- Shopify Help Center, "Sales discrepancies in Shopify Analytics", help.shopify.com/en/manual/reports-and-analytics/discrepancies/sales-discrepancies, accessed August 24, 2026
- Shopify Help Center, "Customer and session discrepancies in Shopify Analytics", help.shopify.com/en/manual/reports-and-analytics/discrepancies/customer-discrepancies, accessed August 24, 2026
- Shopify Help Center, "Accounting for discrepancies in legacy Analytics data", help.shopify.com/en/manual/reports-and-analytics/discrepancies/analytics-updates, accessed August 24, 2026
- Google, "What's new in Analytics", January 16, 2026 entry on per-conversion attribution settings, support.google.com/analytics/answer/9164320, accessed August 24, 2026
- WeltPixel Conversion Tracking, Shopify App Store listing, apps.shopify.com/weltpixel-conversion-tracking, accessed August 24, 2026