Why Shopify and GA4 purchases don't match, and how to find the cause
Shopify says you took 120 orders last week. GA4 says 94. Your ad platforms are bidding on GA4's number, your reports quote it, and nobody can say which one is right. Here is how to work out where the missing purchases went, in the order that finds the answer fastest.
The short answer: Shopify is your record of what was sold. GA4 is a record of what one browser tag managed to report. They will never match exactly, and they are not supposed to.
The gap only matters when you cannot explain it. To explain it, do three things in order. Make sure you are comparing the same thing. Remove the orders GA4 was never going to see. Then look for the purchases GA4 should have recorded and lost. Whatever is left after the first two steps is your tracking problem.
Step 1: make sure you are comparing the same thing
A surprising share of "GA4 is wrong" turns out to be two reports measuring different things. Before you look at tracking at all, line these up:
| Check | Why it causes a false gap |
|---|---|
| Same dates, same time zone | Shopify reports in the store's time zone, GA4 in the property's. If they differ, late-evening orders land on different days. Check both in their settings. |
| Wait for GA4 to finish processing | Standard GA4 reports can take 24 to 48 hours to settle. Comparing yesterday is fine. Comparing this morning is not. |
| Count orders, not revenue, first | Revenue can differ for dull reasons: tax and shipping included in one and not the other, discounts, currency conversion, and refunds, which Shopify subtracts and GA4 does not unless you send refund events. Match the count before you worry about the value. |
| Use the right GA4 figure | Use Transactions or the purchase event count in Reports › Monetization › Ecommerce purchases. Other metrics, such as key events, can be counted differently. |
| Leave out test and cancelled orders | Test orders and orders cancelled straight away still show in Shopify but may or may not have reached GA4, depending on how they were placed. |
Step 2: remove the orders GA4 was never going to see
GA4 on a Shopify store learns about a sale from a tag running in the shopper's browser, on the online store checkout. Shopify's own documentation says its checkout_completed event is triggered once per checkout, typically on the Thank you page. An order that never passes through that page in a shopper's browser cannot produce a GA4 purchase. That includes:
- Point of sale orders from a shop, market stall or pop-up.
- Draft and manual orders created by your team in the admin, for phone orders, wholesale or replacements.
- Subscription renewals. The first order goes through checkout. Later renewals are charged in the background, with no browser involved.
- Other sales channels such as marketplaces or social shops, where the checkout happens somewhere else.
- B2B or wholesale orders placed through a separate flow.
How to check: in Shopify admin, open Orders, filter by Sales channel, and count only Online Store orders for your date range. Compare that number with GA4. For many stores this one step closes most of the gap, and it costs nothing to fix because nothing is broken.
Would you rather check your store than read a checklist? AuditTag reads your public pages and shows which tracking tags are actually installed, including duplicates and a stale Universal Analytics tag, in about a minute. Run a free audit →
Step 3: find the purchases GA4 should have seen and lost
Whatever gap is left after step 2 is made of online store orders that did go through checkout and still never reached GA4. These are the usual reasons, from most to least likely to be expected and harmless.
Shoppers who declined consent
If your consent banner, or Shopify's own privacy settings, hold analytics tags until the visitor agrees, a shopper who declines never sends a purchase to GA4. That is the banner doing its job.
Google can fill some of that gap with modelled data when consent mode is set up in its "advanced" form, but only above a size threshold. Google's requirements for behavioural modelling include at least 1,000 events a day from users who declined, and at least 1,000 daily users who accepted, over a sustained period. Most small stores are below that, so for them a declined consent is simply a missing purchase.
How to check: this gap should be roughly stable week to week, and bigger if more of your customers are in the UK or EU. If it suddenly jumps after a banner change, the banner is the suspect.
Ad blockers and browser privacy tools
Some shoppers block Google's tags entirely. Their purchases never reach GA4 however well your tracking is built. Like consent, this should be a fairly steady share of orders. You cannot fix it in the browser. Server-side tagging can recover some of it, at a real cost in setup and upkeep.
The thank-you page never loaded
Shopify says plainly that if the page where checkout_completed should fire fails to load, the event is not triggered at all. A shopper who pays and loses signal, or a payment method that sends people away and does not bring them back, can leave an order in Shopify with no purchase in GA4.
If you run a post-purchase upsell app, note that Shopify fires checkout_completed on the first upsell offer page instead of the Thank you page. If your tracking was built and tested against the Thank you page only, test the upsell path separately.
The purchase event is broken, or not connected to checkout
This is the one that is actually a fault, and it is common. The usual version on Shopify is a GA4 tag installed in the theme, which loads on your storefront but not reliably at the moment the sale completes. You see begin_checkout, then nothing. We cover the five causes and how to tell them apart in GA4 purchase event not firing on Shopify, and the theme version in detail in the theme.liquid trap.
The tell: consent, blockers and failed page loads lose a steady slice of purchases. A broken event loses almost all of them, or starts losing them on a specific date. Plot Online Store orders against GA4 purchases by day. A cliff or a step is a fault. A steady gap is usually not.
When GA4 shows more purchases than Shopify
This one is never harmless, because it inflates the number your ad spend is judged on. It almost always means the purchase is being sent twice. The typical cause is GA4 installed through Shopify's Google & YouTube channel and again through Google Tag Manager or a snippet in the theme.
GA4 can remove duplicates, but only in one situation. Google's own guidance on transaction IDs says it deduplicates purchases that arrive with the same transaction_id. Two installs sending different IDs, or one sending none, are counted separately. The same page carries a warning worth checking for: an empty transaction_id makes GA4 treat every purchase as the same one, which can make GA4 report far fewer purchases than you took.
How to check: place one test order with DebugView open. Two purchase events for one order is the fingerprint. Then pick one install and remove the others.
And why Meta shows a different number again
If you also compare Meta Ads Manager, expect a third number, and do not try to reconcile it with the other two in the same way. GA4 and Shopify both try to count orders. Meta counts purchases it attributes to your ads, using its own attribution window, which by default can include purchases made after someone only saw an ad. Meta can report more purchases than you took from paid traffic, and that is not by itself a tracking fault.
What is a fault is Meta counting the same purchase twice, from the browser pixel and the Conversions API, because the two events do not share an event_id. The Meta Pixel audit guide covers how to check that, and why Meta reports more purchases than Shopify walks through telling the two apart.
The reconciliation, on one page
| What you see | Most likely cause | How to confirm |
|---|---|---|
| GA4 lower, gap disappears when you count Online Store orders only | Orders from other channels | Filter Shopify orders by sales channel |
| GA4 lower by a steady share, higher for UK/EU customers | Declined consent and blockers | Gap stable week to week; test checkout without accepting the banner |
| GA4 lower, started on a specific day | A theme, app or banner change broke the event | Plot daily orders against GA4 purchases; match the date to your change log |
| GA4 shows almost no purchases, but checkout steps appear | Purchase not connected to Shopify's checkout | Test order in DebugView stops at begin_checkout |
| GA4 higher than Shopify | Purchase sent twice | Two purchase events for one test order |
| GA4 has purchases but £0 revenue | Missing value or currency | Open the purchase event in DebugView and read its parameters |
Presence first, then the purchase
Before you open DebugView, rule out the simplest problems: GA4 not installed where you think it is, installed twice, or an old Universal Analytics tag still loading in its place.
What AuditTag checks on your public pages
- GA4 detected
- Google Tag Manager detected
- Google Ads tag detected
- Meta Pixel detected
- Legacy Universal Analytics still present
What this doesn't prove
Finding GA4 on your public pages does not prove the purchase event fires at checkout, fires once, or carries the right transaction_id. Tags installed through Shopify's Customer events may not show in the page source at all. Presence is the first thing to rule out. Confirming the purchase means a test order, and keeping it right after every theme and app change is what Guardrails monitors.
See what's actually installed on your store
The free audit reads your public pages and tells you which tracking it can detect: GA4, Google Tag Manager, Google Ads and Meta Pixel. It flags gaps like a missing conversion pixel or a stale Universal Analytics tag. It takes about a minute. No account, no card, nothing installed, and it never touches your store.
Run a free audit →The audit confirms presence on your public pages. Watching the purchase event itself, and catching the day it breaks, is what Guardrails monitoring covers.