GA4 showing less revenue than Shopify is the most common analytics complaint we hear. Some shortfall is normal. Visitors who reject analytics cookies and people using ad blockers won't be fully measured. But "some" can hide a real problem, like checkout tracking that silently stopped or revenue sent without its currency.
This is a diagnosis routine for the lower-only case. If GA4 is higher than Shopify, you have duplicates: see our duplicate purchase guide. For background on why the two never match exactly, read why GA4 revenue doesn't match Shopify orders. Work through these steps in order and stop when you find the cause.
Step 1: Make sure you're comparing like with like
Before diagnosing anything, rule out a measurement mismatch:
- Same date range, same time zone. Check GA4 Admin › Property details against your Shopify store's time zone, and use complete days ending at least two days ago (GA4 can take time to process).
- Online Store only. Filter Shopify to the Online Store sales channel. POS, draft orders and other channels never trigger a website purchase.
- Same revenue definition. Note whether your GA4 purchase value includes VAT, shipping and discounts, and compare with the matching Shopify figure. Shopify's net sales subtract refunds; GA4's purchase revenue doesn't unless refund events are sent.
If the gap shrinks to something steady once you compare properly, you may be done.
Step 2: Split it into orders vs order value
Compare order count (GA4 Transactions vs Shopify Online Store orders) and average order value separately.
| What you see | Where to go |
|---|---|
| Order counts close, revenue far apart | A value problem: go to step 3 |
| Order counts far apart, average order values similar | A missing orders problem: go to step 4 |
| Both far apart | Do step 3, then step 4 |
Step 3: Diagnose a value problem
Place a test order with consent accepted and inspect the purchase event in GA4 DebugView:
- Currency missing? GA4 needs
currencyalongsidevalueto record revenue properly. - Value in the wrong unit? For example pence instead of pounds, or a subtotal instead of a total.
- Tax or shipping excluded when you're comparing against a figure that includes them?
- Multi-currency store? Check that orders in other currencies are sent with their own currency code.
Fix the value at its source (app settings or custom pixel code), then re-check average order value after a few days.
Not sure what your store fires before consent?
Send us your URL and we'll run a free homepage pre-consent scan: which trackers and cookies load before a shopper chooses. No obligation.
Get my free scan Use the free checklistStep 4: Find out which orders are missing
Missing orders usually have something in common. Export your Shopify orders for the period and a GA4 exploration with the Transaction ID dimension, then match them. Make sure both use the same ID format. Shopify's order name (#1001), order number and internal ID differ.
Look at the orders that are in Shopify but not in GA4, and check whether they cluster by:
- Date: did they start on a specific day? Go to step 5.
- Payment method: some payment flows leave the site and may not return the shopper to the thank-you page in the same way.
- Device or browser: a cluster on one browser can point to tracking protection or a script error.
- New vs returning customers, or logged-in customers: can point to consent-state or script-loading differences.
- Country: can point to banner region settings, which affect who is asked and what the default is.
If the missing orders are spread evenly across everything, that's consistent with consent loss. Go to step 6.
Step 5: If it started on a specific date
A sudden drop almost always follows a change. Check that date against:
- theme publishes or theme code edits
- apps installed, updated or removed, especially consent, tracking and checkout apps
- checkout changes, such as tracking that lived in the old order-status "Additional scripts" and needed to move to app or custom pixels
- changes to Settings › Customer events (custom pixel permissions) or customer privacy settings
Our guide to GA4 not tracking Shopify purchases has the repair steps for checkout tracking.
Step 6: Test the consent chain
Run three tests in fresh private windows: no click, "Reject all" and "Accept all". With "Accept all", a purchase should be recorded and Google hits should show gcs=G111. If purchases fail even with consent accepted, the problem isn't consent loss. It's a block that affects everyone, such as a consent default stuck on denied or a custom pixel requiring a category your banner never grants. See Shopify Consent Mode v2 not working.
Step 7: Decide: normal or broken?
| Looks normal | Looks broken |
|---|---|
| Gap appeared when the consent banner went live and has stayed broadly steady since | Gap appeared on a date with no consent change |
| Missing orders spread across payment methods, devices and dates | Missing orders cluster on one payment method, device, country or date |
| Accepted test orders are always recorded | Accepted test orders sometimes or always go missing |
| Average order values are similar in GA4 and Shopify | Average order values differ noticeably |
As a rough rule of thumb, if GA4 is missing more than about 40% of Online Store orders, investigate the tagging before putting it down to consent. That's a prompt to check, not a benchmark. Your own steady baseline after a working banner is the best reference.
Keep a baseline
Once things are healthy, note your capture rate (GA4 transactions ÷ Shopify Online Store orders) each month. A change in that number is the fastest early warning that something has broken again.
Want it checked properly?
The TrackCheck Health Check is a fixed-price review for UK Shopify and WooCommerce stores: a full consent test (before choice, after "Reject all", after "Accept all", including Consent Mode v2 signals), a GA4-vs-orders reconciliation, a prioritised fix list and a recorded walkthrough, delivered in 5 working days.
See Health Check pricing Start with a free scanThis article is technical guidance, not legal advice. Platform menus change; check the vendor's current documentation if a setting has moved.