TRACKING SPECIALIST — BARIS ASA · LONDON
Synctag
Start the check → TRACKING SPECIALIST — BARIS ASA · LONDON

READING ROOM › SYMPTOM FILES › SYM-001

SYMPTOM FILE SYM-001 FILED 13 JUN 2026 · REVISED 01 NOV 2026

GA4 revenue higher than Shopify: which causes are normal and which are faults.

ALSO FILED AS
  • “why is GA4 revenue higher than Shopify”
  • “GA4 shows more revenue than Shopify”
  • “GA4 revenue double Shopify”
  • “GA4 purchases more than Shopify orders”
  • “GA4 duplicate purchase events on Shopify”

Baris Asa, tracking consultant, London · Last checked: November 2026

When GA4 revenue is higher than Shopify, count GA4 purchases against Shopify orders for the same week. More purchases than orders means GA4 is counting orders that don’t exist, usually because the purchase event fires twice. That is a fault. Matching counts and a gap close to your refund rate is normal: Shopify takes refunds off its sales, and GA4 doesn’t.

Use a closed week: a full week that ended at least two days ago. Take test and deleted orders out of both sides; Shopify already leaves them out of its sales reports. A handful of extra purchases can be time zones. More than that is the fault, and the fix is further down.

Why is GA4 revenue higher than Shopify?

Start with the direction. GA4 normally reads below Shopify. Some visitors refuse cookies or block scripts, and Shopify’s help says Google Analytics can’t record them. Point-of-sale orders, draft orders marked as paid in the admin, and subscription renewals never pass through a browser either.

So GA4 above Shopify means something is adding revenue on the GA4 side. Refunds and test orders lift GA4 against the Shopify figure. Dates and currency move it either way. None of those need a fix, only a fair comparison. Faults are different. GA4 records purchases that are not orders, or amounts that are not what was paid, and those need fixing at the tag.

What you seeLikely causeOn file
GA4 ahead by about your refund rateRefunds not sent to GA4: normalNone
More GA4 purchases than ordersPurchase fires twiceF-101
Counts match, revenue exactly 100xAmount sent in penceF-302
Counts match, revenue up by tax and shippingTag sends the order totalF-302
Too high on overseas orders onlyWrong currency labelF-302
Meta also above the storePixel and server events not deduplicatedF-102

Which causes are normal?

1. You are comparing different numbers

Google’s developer reference for the purchase event says value (the amount sent with the purchase) should be price times quantity for the items. Tax and shipping go in their own parameters.

Shopify’s sales reports have three figures. Gross sales is price times quantity. Net sales is gross sales minus discounts and sales reversals (refunds, cancellations, edits). Total sales adds tax, duties, shipping and fees.

A tag built to Google’s guidance matches Shopify’s net sales with the reversals added back. Many tags send the order total instead, tax and shipping included, and then total sales is the match. To see which yours does, place one order and read the value GA4 received for it. On the GA4 side, read Purchase revenue. Total revenue adds ad revenue on top.

2. Refunds come off Shopify, not GA4

Shopify records a sale on the order date. It records a reversal as a negative amount on the day it is processed. GA4 only subtracts a refund when it receives a refund event for that order. Its Purchase revenue is net of refunds it has been told about. Gross purchase revenue is not.

If nothing sends GA4 refunds, GA4 runs ahead of Shopify’s net sales by roughly your refund and cancellation rate. It’s the normal gap I see most, and it widens in the weeks after a sale.

3. Test orders count in GA4

Shopify’s sales reports leave out test and deleted orders, including orders placed while Shopify Payments was in test mode. GA4 counts any purchase the tag sent. A launch week with a run of staff test orders shows up as GA4 purchases the store never took. Take their order numbers out of GA4 before you compare counts.

4. Days and time zones differ

GA4 dates a purchase by when the event fired, in the property’s time zone. Shopify dates it by the order date, in the store’s time zone. If the two differ, late-evening orders land on different days, and a week’s counts can be a few orders apart. Compare closed weeks, not single days. GA4 processing can take 24 to 48 hours, which is why the week needs two days to settle.

5. Currency is converted differently

GA4 converts each order into the property’s currency at the previous day’s exchange rate. Shopify reports in the store currency. On overseas orders the two drift apart slightly, in either direction. That is not a fault, as long as the currency code sent with each order is right.

How do I compare GA4 and Shopify like for like?

Put GA4 purchase revenue next to Shopify net sales first, then add refunds back, then count orders. Four checks, in order, on one closed week:

  1. Same report. In Shopify, open Analytics, Reports, set the Category filter to Sales, and open Total sales over time. Note net sales, sales reversals and orders. If you also sell in person, use Total sales by sales channel and read the Online Store row. In GA4, open Reports, Monetization, Transactions. If it’s not there, someone with edit access can add it from the report Library. What it shows you: the two numbers most people compare first.
  2. Refunds out of the way. Add Shopify’s sales reversals for the week back to its net sales. What it shows you: the gap without refunds, which GA4 usually never hears about.
  3. Count orders, not money. Compare GA4’s Ecommerce purchases with Shopify’s orders, test orders out of both. What it shows you: whether GA4 has extra purchases (fires twice) or the right purchases at the wrong amount (built wrongly).
  4. Order by order. In the Transactions report, sort by Transaction ID (the order number sent with the purchase). Look for (not set), IDs that don’t look like your order numbers, and any order with two purchases. What it shows you: the extra purchases themselves.
CHECKGA4SHOPIFYGAP
1. Purchase revenue vs net sales£44,100£38,400GA4 +15%
2. Reversals added back£44,100£40,000GA4 +10%
3. Purchases vs orders441400+41
4. (not set) removed£40,000£40,000none
ONE WEEK, FOUR CHECKS · purchases and revenue · worked example, illustrative figures, not a client account

At check 1, GA4 is 15% ahead. Adding back £1,600 of refunds explains 5 points, and that part is normal. The count then shows 41 more purchases in GA4 than orders in the store, and the Transactions report has 41 purchases with no transaction ID. That is the purchase firing twice, the second copy sent without an ID. Take those out and the two agree.

If check 3 shows extra purchases and you don’t run the tags yourself, stop there. Send the week’s figures to whoever does, or to me (details at the end).

Which gaps are faults?

A fault leaves a shape the normal causes don’t. It usually starts on a date: an app install, a new pixel, a tag added in GTM. Each is on file with the test that confirms it.

F-101 · The purchase fires twice: how to fix it

The purchase fires twice because two things send it for one order, and their transaction_ids don’t match, so GA4 keeps both. In plain terms: two of your apps or tags both report the sale. The extra can be a few per cent of orders or a full double, depending on how many orders the second sender catches.

To fix it:

  1. Confirm it. Place a test order with GA4 DebugView (a live view of one test session’s events) or GTM Preview open. Count the purchase events and note what sent each one.
  2. List every sender. The Google & YouTube app, custom pixels (Settings, Customer events), GTM, any app with its own tracking, and any Create event rule in GA4 Admin, Events, that outputs a second purchase. Note the transaction_id each one sends.
  3. Keep one. Remove the purchase from every other sender.
  4. Send a stable, unique transaction_id on the one that stays. Never an empty string: GA4 then treats every empty-ID purchase as one order, and an overcount becomes an undercount.

Fixed at the source, the gap closes from that day. Revenue already inflated in GA4 stays in its reports. Not sure which apps send a purchase? Ask whoever installed them, or send me the week’s figures. The sender-by-sender hunt, on any platform, is in GA4 purchase event fires twice.

Shape: GA4 purchases run above Shopify’s orders, test orders excluded, by a steady share from a date you can name.

Why two senders. On Shopify, checkout_completed, the event most tracking hangs on, fires once per checkout: on the Thank you page, or on the first upsell page if the store runs post-purchase offers. So the double most often comes from two senders, usually the Google & YouTube app plus a GA4 tag in a custom pixel or GTM (Google Tag Manager). Inside GTM, look for a second trigger on the purchase tag, or the container loaded twice.

Why GA4 keeps it. Google’s help says GA4 deduplicates purchases with the same transaction_id on web streams, with no published time window. So two senders with the same order number don’t inflate GA4. In the accounts I’ve checked, the copy that gets through is the one with no ID or a different one. A reload of the order page that resends the same ID is dropped by GA4, though Meta and Google Ads have their own rules.

TIMEEVENTTRANSACTION_IDVALUE
12:40:31begin_checkout
12:41:07purchaseT-88412£96.00
12:41:09purchase(not sent)£96.00
EVENT LOG · checkout, one order · worked example, illustrative, not a client account

One order, two purchases two seconds apart. The second has no transaction_id parameter, and it shows in the Transactions report as (not set). Full write-up, with the test that separates each sender: F-101 .

F-302 · Counts match, revenue doesn’t: the amount is built wrongly

Shape: GA4 purchases match Shopify’s orders, but revenue is too high by a fixed ratio or a fixed part of each order.

The tag sends the right purchase with the wrong amount. Three versions turn up:

  • Exactly 100 times too high. The amount went out in pence: 9600 instead of 96.00. It comes from a custom data layer (the page code that hands order details to the tags) reading a raw money field without formatting it.
  • Too high by tax and shipping. The value is the order total and you are comparing it with net sales. Compare with total sales, or change the tag to send tax and shipping in their own parameters.
  • Too high on overseas orders only. A store selling in several currencies sends the amount the customer paid, say 115 euros, labelled as GBP. GA4 reports £115. Send the currency the order was charged in, and GA4 converts it.

The test is the same for all three. Pick five orders, read the value and currency GA4 received for each, and set them next to the order in Shopify. Full write-up: F-302 .

F-102 · Meta is above the store too

If Meta Ads also reports more purchases than the store took, that is a separate fault with the same look. The Meta Pixel and the Conversions API both send the purchase. Meta drops the copy when both share the same event name and event_id, its recommended method. Fixing GA4 doesn’t fix Meta. Full write-up: F-102 .

Which number should I trust?

Shopify, for revenue. It is the record of what was charged and what was refunded. GA4 is for how people found and moved through the store. Its revenue is fine once it sits a little below Shopify, or above it by your refund rate, week after week.

Comparing GA4 with Google Ads rather than Shopify is a different job: GA4 and Google Ads numbers don’t match. Google Ads conversion value against Shopify’s sales has its own checks: Google Ads conversion value doesn’t match actual revenue. If the checks point at more than one fault, or none, that is a reconciliation: order by order, every remaining gap named. Email [email protected] with one closed week of GA4 purchases and purchase revenue, next to Shopify’s orders and net sales. I’ll say whether it’s a fault, a reconciliation, or nothing to fix.

Common questions

How big a gap between GA4 and Shopify revenue is normal?

GA4 normally sits below Shopify, because buyers who refuse cookies or block scripts never reach it. Above Shopify by about your refund rate is normal. Three things are faults: more GA4 purchases than orders by more than a handful, once test and deleted orders are out; revenue at an exact multiple such as 100x; or a jump from a date you can name.

Which Shopify number should I compare with GA4 purchase revenue?

Start with GA4 purchase revenue against Shopify net sales, Online Store only, then add Shopify’s sales reversals back. Google’s guidance is that the purchase value excludes tax and shipping. If your tag sends the order total with tax and shipping, compare with total sales instead.

Is a purchase firing twice the reason GA4 is above Shopify?

It is when GA4 shows more purchases than Shopify shows orders for the same closed week. Matching counts point elsewhere: refunds, tax and shipping, or currency. The sender-by-sender fix is in GA4 purchase event fires twice.

Does GA4 remove duplicate purchases?

On web streams, yes. GA4 deduplicates purchase events that share the same transaction_id, with no published time window. Not on app streams. An empty string makes GA4 treat every empty-ID purchase as one, so you undercount.

Sources

Read on 1 November 2026:

← back to the reading room