WooCommerce CRO Technique
Why GA4 revenue doesn’t match WooCommerce orders
This technique is a structured reconciliation check between GA4 purchase data and WooCommerce order reporting. It helps when GA4 revenue, purchase count or both drift away from WooCommerce because of mismatched definitions, date settings, missing or duplicated tags, consent loss, or reporting artefacts rather than a real trading problem.
Summary
Bottom Line: GA4 will only line up with WooCommerce if you compare like with like: the same timezone, the same date basis, the same included order statuses, and the same revenue definition.
- Start with definitions, not tags. For most WooCommerce stores, GA4 purchase revenue should be compared to a WooCommerce comparable net item revenue view, not blindly to WooCommerce Total Sales, because Woo Total Sales adds taxes and shipping back in.
- In GA4, a valid purchase event needs transaction_id, value, currency and items, with item_id or item_name at item level. If any of those are wrong, revenue and purchase counts can go missing or misstate.
- Duplicate or blank transaction_id values distort the picture in opposite directions: reused IDs can cause undercounting through deduplication, while regenerated IDs on refresh or repeat hits can overcount.
- WooCommerce comparison settings matter. WooCommerce Analytics lets you choose excluded statuses and the Date Type used for Revenue and Order reports, so you can create a mismatch before you even open GTM.
- If you need order-level truth, use GA4 BigQuery export plus Woo order data, not a thresholded report or a sampled exploration. Google explicitly says BigQuery export is raw event and user-level data and can differ from the GA4 interface because the interface adds value on top.
How To Implement
Freeze the comparison rules before touching any tags
In GA4, confirm the property reporting timezone and currency. In WordPress, confirm Settings → General → Timezone. In WooCommerce, go to WooCommerce → Analytics → Settings and note the Date Type plus which order statuses are excluded. If you compare GA4 in one timezone and WooCommerce in another, or compare Woo “Date Paid” to GA4 event date without noticing, you will create a fake mismatch. Use a settled date range rather than judging same-day data.
Choose the correct WooCommerce comparison metric
In WooCommerce → Analytics → Revenue, note that WooCommerce defines Gross Sales as item sales before refunds, coupons, tax and shipping; Net Sales as gross minus returns and coupons; and Total Sales as gross minus returns and coupons plus taxes and shipping. GA4’s
purchase.valueshould be the sum of item prices times quantity and should not include shipping or tax, so as a working comparison GA4 purchase revenue is usually closer to WooCommerce Net Sales than to WooCommerce Total Sales. If you use discounts, confirm your GA4 implementation sends the discounted item price; Google says it does not subtractdiscountfrompriceautomatically.Check where the purchase event is supposed to fire in WooCommerce
Google’s setup guide shows the
purchaseevent firing on the purchase confirmation page. On classic WooCommerce templates, many implementations still rely on the legacy thank-you flow and thewoocommerce_thankyouhook. If your theme overrideswoocommerce/checkout/thankyou.phpor uses a custom thank-you plugin, verify that the hook or equivalent tracking output still runs. On block themes, the order confirmation surface lives at Appearance → Editor → Templates → WooCommerce → Order Confirmation. WooCommerce documents that inserting the Order Confirmation Block classic placeholder makes the site use the legacy template again, which is useful if your older tracking code only runs there.If the store uses Cart & Checkout Blocks, check the block path separately from the classic path
WooCommerce says Cart and Checkout Blocks are the default experience for stores started after WooCommerce 8.3, and the order confirmation page is now a dedicated template in the Site Editor. That means a legacy tracking method tied to classic templates can survive checkout but fail on confirmation after a redesign or a block-theme change. This is not a WooCommerce bug by itself; it is a tracking implementation dependency you need to verify.
Inspect the data layer on a real test order
Use GTM Preview / Tag Assistant and GA4 DebugView on a new test order. The page or custom event that signals purchase should expose a data layer payload with
transaction_id, numericvalue,currencyanditems, and each item should includeitem_idoritem_name. Google’s data layer documentation says GTM uses theeventkey to trigger tags, and Google’s ecommerce troubleshooting says the purchase setup must be correct both in the data layer and in the GA4 Event tag.Open the GTM purchase tag and verify the mapping
In Tag Manager → Workspace → Tags, open the GA4 Event tag used for purchase. Confirm the event name is exactly
purchase, the trigger is the intended order confirmation condition or custom event, and the event parameters are mapped from the data layer values rather than hard-coded or partially copied. Google’s Tag Manager help shows the GA4 Event tag path, how to create triggers, how to preview the container and how to publish it. If you use shared event settings variables, make sure they are not overwriting purchase-specific values likecurrency.Verify the four parameters that usually explain the mismatch
transaction_id: unique per order, never blank, and stable on refresh. Google says transaction IDs deduplicate duplicate web purchases and warns not to send an empty string.value: numeric, event-level, and equal to the sum of item revenue. It must exclude shipping and tax.currency: event-level ISO 4217 code. Without it, revenue metrics break.items: present, with valid item identifiers and correctly discounted prices where relevant. Google sayspriceshould already reflect the actual price paid per unit after discount allocation.
Test the two classic failure modes: duplicates and misses
Refresh the thank-you page, retry a failed payment, and run at least one external-gateway journey that returns to the store. If the page refresh sends a second hit with a different
transaction_id, you will overcount. If the same order keeps reusing a fixed or blank ID, you can undercount through deduplication. If your implementation only fires on the confirmation page and the customer never returns there, that client-side purchase event may never be observed. Google’s own setup places the purchase event on the confirmation page, so this return path matters.Don’t reconcile from the wrong GA4 surface
Avoid thresholded reports, sampled explorations and heavily modelled interpretations when you are doing a source-of-truth check. Google says thresholding can withhold data, sampling can appear in explorations above event limits, and behavioural modelling estimates behaviour for users who decline consent. For this job, use standard monetisation reporting for a quick check and BigQuery export for order-level truth.
Reconcile at order level in BigQuery when the variance is still unexplained
In GA4 Admin → Product Links → BigQuery Links, enable export if it is not already linked. Google’s export docs show that the dataset is named
analytics_<property_id>and that the export containsecommerce.transaction_id,ecommerce.purchase_revenue,ecommerce.shipping_value,ecommerce.tax_value, repeateditemsrecords,user_pseudo_id, and consent fields inprivacy_info. Pull the purchase rows, then join them to WooCommerce order data by order number or order key from a Woo export. WooCommerce Analytics tables can be downloaded as CSV from report tables, which is often enough for a first pass.SELECT event_date, ecommerce.transaction_id AS transaction_id, ecommerce.purchase_revenue AS purchase_revenue, ecommerce.shipping_value AS shipping_value, ecommerce.tax_value AS tax_value, user_pseudo_id, privacy_info.analytics_storage AS analytics_storage FROM `your_project.analytics_PROPERTY_ID.events_*` WHERE _TABLE_SUFFIX BETWEEN '20260601' AND '20260630' AND event_name = 'purchase';Write up the variance by cause, not as one lump
Separate the gap into: – definition differences: shipping, tax, discount allocation, refund timing; – capture loss: consent denial, blocked tags, opt-out tools, blocked tag loading; – reporting artefacts: thresholding, sampling, modelling; – implementation defects: missing items, wrong value type, duplicate firing, unpublished GTM changes. This is the step that turns “GA4 is wrong” into a fix list you can act on. Google explicitly documents all four categories somewhere in its GA4 and Tag Manager help.
How To Measure
Key KPI — GA4-vs-Woo revenue variance and GA4-vs-Woo order variance, tracked weekly on a fixed comparison basis. Use a formula such as (GA4 comparable revenue - Woo comparable revenue) / Woo comparable revenue and the same for purchase count versus included Woo orders. Success is a small, explained variance that stays stable over time, not perfect parity.
GA4 events / reports to use — Use the purchase event and the Ecommerce purchases or monetisation reporting surfaces for a first pass. Prefer Purchase revenue or purchase-based monetisation views over a broad “Total revenue” lens when you are reconciling store sales, because Google defines total revenue more broadly. For implementation checks, use Realtime and DebugView; Google says purchase data appears in reports after about 24 hours.
WooCommerce segment to read it in — Read WooCommerce from WooCommerce → Analytics → Revenue with the same date range, the same Date Type, and the same included statuses. Then break the variance down by day first, and only then by channel, device or campaign if the site volume supports it. WooCommerce’s report tables can be exported to CSV for the same date window.
What success looks like — Success is a narrow, explainable gap that you can account for from known causes such as shipping/tax definition differences, discount handling, refund timing, consent loss or blocked tags. If the remaining gap is still material after those are accounted for, move to order-level checking in BigQuery.
Guardrail metrics — RPV, conversion rate, checkout completion and AOV should not show unexplained jumps after you change tags or purchase-event logic. On the data-quality side, guard against duplicate purchase IDs, purchases missing currency or items, and any GA4 report showing thresholding or sampling warnings during validation.
Pitfalls
- Myth: GA4 should match WooCommerce to the penny. That is not how GA4 is documented to work on live traffic once consent loss, blocked tags, thresholding or modelling enter the picture. GA4 is a measurement layer; WooCommerce orders are your commercial ledger.
- Mistake: comparing GA4 to WooCommerce Total Sales. WooCommerce Total Sales includes taxes and shipping; GA4 value for purchase should exclude both. That comparison will overstate the “gap” before you inspect a single tag.
- Mistake: assuming Google subtracts discounts for you. Google says it does not automatically subtract discount from price; you must send the actual discounted item price. If a plugin sends pre-discount prices plus a discount value, GA4 revenue can run high.
- Mistake: validating from the wrong GA4 report. Thresholded reports can withhold data and explorations can sample; neither is the right place to decide whether the implementation is trustworthy.
- Mistake: forgetting the order confirmation template. In WooCommerce, a redesign from classic templates to block-based order confirmation can leave a legacy thank-you-page tracking method behind.
Examples
FAQs
Usually, compare GA4 purchase revenue with a WooCommerce net, item-only view first, not with Total Sales. WooCommerce Total Sales includes tax and shipping, while Google says purchase.value should exclude both; if discounts are implemented correctly in GA4, Net Sales is the closer like-for-like benchmark.
Not consistently on live traffic. Google documents missing observed data when users decline consent, modelling in some reports, thresholding in some views, and blocked tags during debugging, so a small explained gap is normal even when the implementation is healthy.
No, not by default, but they can expose a weak legacy implementation. WooCommerce moved newer stores towards block-based checkout and a block-based Order Confirmation template, so any purchase tag that only ran through classic thank-you template logic needs to be checked after a theme or template change.
No, fix the comparison logic and the tracking first. WooCommerce and GA4 are built on different revenue definitions, and Google explicitly expects purchase.value to be item value excluding shipping and tax, while WooCommerce intentionally reports multiple sales measures for different uses.
Sources & Further Reading
- Analytics and Sales Reports Documentation — WooCommerce – Core reference for WooCommerce Analytics definitions, CSV exports, excluded statuses and Date Type. Date: Published c. 2020; live doc opened June 2026.
- Revenue Report Documentation — WooCommerce – Explains the Revenue report and the revenue cards shown in WooCommerce Analytics. Date: Published c. late 2022.
- Set up a purchase event — Google Analytics for Developers – Official setup flow for purchase, including confirmation-page firing, DebugView and the 24-hour reporting delay. Date: Updated 9 October 2024.
- Recommended events — Google Analytics for Developers – Canonical parameter reference for purchase, including transaction_id, value, shipping, tax and items. Date: Updated 3 June 2026.
- Fix missing revenue data — Google Analytics Help – Troubleshooting guide for missing GA4 revenue, including required purchase parameters and GTM/data layer checks. Date: Undated help page; live June 2026.
- Apply a discount to an ecommerce event — Google Analytics for Developers – Critical for Woo stores using coupons; explains that price must already reflect the discounted unit price. Date: Updated 4 May 2026.
- Minimize duplicate key events with transaction IDs — Google Analytics Help – Explains GA4 purchase deduplication by transaction_id on web streams and warns against blank IDs. Date: Undated help page; surfaced in search June 2026.
- The data layer — Tag Platform – Official explanation of how GTM reads the data layer and uses the event key to trigger tags. Date: Last updated 1 June 2026 UTC.
- Set up Google Analytics in Tag Manager – Official GTM container, tag, preview and publish workflow. Date: Undated help page; live June 2026.
- Set up Google Analytics events in Tag Manager – GA4 Event tag and trigger setup inside GTM. Date: Undated help page; live June 2026.
- BigQuery Export schema — Analytics Help – Schema reference for analytics_<property_id>, ecommerce.transaction_id, revenue fields, items, user_pseudo_id and consent fields. Date: Undated help page; live June 2026.
- BigQuery Export — Analytics Help – Explains that BigQuery export is raw event/user-level data and may differ from the GA4 interface. Date: Undated help page; live June 2026.
Want us to implement this for you?
We run measured CRO consultancy for WooCommerce. If you want help prioritising, testing & implementing these improvements, tell us about your store.
Book PilotAbout This Page
- Written By: Eliot Webb – Founder & WooCommerce CRO Consultant
- Last Reviewed: 17 Jun 2026
- Last Updated: