Ecommerce measurement
Why GA4 and Shopify revenue never match exactly
10 August 20267 min readKriov
One of the most common escalations we receive starts the same way: the finance team has Shopify reporting one monthly figure, GA4 reports another, Google Ads reports a third, and nobody can reconcile them. The instinct is to assume something is broken. Sometimes it is. Often, several structural reasons explain why these numbers will never match exactly.
What Shopify counts
Shopify reports orders as they exist in the store: gross sales minus refunds, discounts, shipping and tax depending on the report you are reading. It is a financial system of record. Every order exists, regardless of whether the customer consented to analytics or whether their browser allowed any tracking script to run at all.
What GA4 counts
GA4 only knows what it was told. A purchase reaches GA4 because an ecommerce event was pushed to the data layer, captured by a tag, and sent successfully. That chain can fail silently at every step. Beyond that, GA4 applies its own adjustments:
- Consent Mode modelling fills gaps left by declined or uncollected consent with modelled conversions.
- Attribution windows differ from Shopify's concept of an order — GA4 assigns credit within its own lookback rules.
- Currency conversion uses GA4's exchange rates at processing time, not your store's accounting rates.
- Refunds only appear if refund events are actively implemented — they rarely are.
A worked example
Shopify net revenue (month) £100,000
Orders without analytics consent -£6,000
Consent Mode modelled conversions +£2,400
Refunds not implemented +£3,100
Session-attributed vs order-based ±£1-3k
─────────────────────────────────────────────
Expected GA4 range £90-96kIf GA4 lands inside that band, nothing is broken. If GA4 reports £40,000 against £100,000 of Shopify revenue, something genuinely is — most commonly duplicate purchase triggers, missing checkout events, or a checkout customisation that never fires the data layer push at all.
The audit that settles it
- Verify purchase events fire exactly once per order, including on page refreshes and back-button returns.
- Confirm transaction_id consistency so platforms can deduplicate.
- Compare item arrays against real orders — value mismatches usually live here.
- Check what consent configuration does to collection before assuming loss.
- Reconcile a sample of ten individual orders end to end rather than comparing monthly totals.