When GA4 revenue does not match Shopify, compare the same orders under the same revenue definition before changing attribution settings. A total difference can combine missing purchase events, duplicate collection, incompatible filters and different treatment of tax or returns. Each needs a different response.
This guide uses fictional orders to show a reconciliation you can reproduce. It does not assume that any fixed percentage difference is normal.
1. Define the comparison before exporting
Write down the reporting dates, time zone, currency, sales channels, order status and revenue definition. Choose whether refunds belong to their processing period or are allocated back to the original order for your comparison. Apply the same choice to both datasets.
A Shopify sales report, an order export and a payment report are different views. Shopify documents differences between its own sales reports and exports, including how test orders and certain refunds are handled. Do not treat a downloaded order total as automatically identical to the dashboard total.
Start with all eligible web orders. A report filtered to Google Ads or Meta is a later attribution question. It cannot establish whether the site collected purchases correctly overall.
2. Match transaction identifiers, not just daily totals
Export a bounded period of eligible orders with order identifier, time, currency, revenue components and refund information. Obtain comparable transaction-level GA4 data where available. Keep a consistent mapping between the Shopify identifier and the value your implementation sends as transaction_id.
Before joining, check uniqueness. An order export can contain multiple item rows. Sum line items to one order only after removing repeated order-level totals. Likewise, distinguish multiple item records from multiple purchase events in GA4. Summing a repeated order total over line-item rows creates a false discrepancy.
Retain unmatched records from both sides. Assign every record one initial category: matched value, Shopify only, GA4 only, repeated identifier or value mismatch. Investigate the reason before treating a category as a confirmed tracking defect.
3. Work through this six-order example
All figures below are fictional USD amounts. The intended comparison is online order revenue excluding tax. The GA4 column represents a transaction-level extract before the discrepancies have been resolved.
| Order | Shopify comparison amount | GA4 extract amount | Investigation finding in this example |
|---|---|---|---|
| A1001 | 80 | 80 | Matching web order |
| A1002 | 120 | 0 | No matching purchase in the extract |
| A1003 | 90 | 180 | One order sent twice with two different transaction IDs, then mapped to one order |
| A1004 | 100 | 110 | GA4 value includes 10 of tax in this implementation |
| A1005 | 70 | 0 | POS order outside the web comparison |
| A1006 | 60 | 60 | Matching web order |
| Raw total | 520 | 430 | Raw difference: 90 |
The raw difference is 90, but that is not the value of missing web purchases. First remove the 70 POS order from the Shopify scope: eligible revenue is 450. Then remove the duplicate 90 and the extra 10 tax from the GA4 comparison: harmonized observed revenue is 330. The remaining gap is 120, corresponding to A1002.
This is a reconciliation of extracts, not an instruction to rewrite historical analytics data. Record the evidence for every adjustment and fix the collection issue at its source. Do not label A1002 a tag failure until you have checked consent, timing, filters and the event implementation.
4. Inspect purchase and refund collection
Google's ecommerce implementation guide specifies purchase events, transaction identifiers, currency and item data. It shows revenue value separately from tax and shipping. Validate the fields your integration actually sends instead of assuming the app configuration is correct.
Run a controlled order through your actual checkout. Check the event name, identifier, value and currency in the debugging tools. Test a repeat visit to the confirmation page and the relevant refund flow. A stable identifier matters: sending the same order under different identifiers can defeat purchase deduplication. Consult Google's ecommerce validation guide when checking events.
Also inventory every source that can send a purchase: an app, a custom pixel, a tag manager and a server integration may overlap. Establish which integration owns the event. Avoid disabling production tracking until you have identified the duplicate path and tested the intended setup.
5. Separate missing observation from broken tracking
Shopify notes that browser extensions, privacy choices and time zones can create differences. GA4 reporting may also contain modeled results depending on settings and eligibility; an event-level export is not necessarily identical to every report.
Compare transaction data with transaction data, then document which aggregate views contain additional processing. Do not manufacture missing purchase events or bypass consent to force two dashboards to match. If observation is incomplete, describe its scope and use your order system for the corresponding business totals.
6. Reconcile attribution only after collection
Once purchase collection and revenue definitions are understood, investigate channel allocation: session versus event scope, attribution model, lookback windows and cross-domain handling. See the attribution setup and QA checklist and GA4 limitations.
A reconciled revenue total still does not establish how much a campaign caused. For that question, use an appropriate experiment and the incremental ROAS calculation. The free test-plan workbook helps document the design and business threshold before the results are known.