# GA4 Purchase Event Not Firing in WooCommerce? The 7 Real Causes (and Fixes) > Revenue missing from GA4? Here are the seven causes behind almost every broken WooCommerce purchase event — with the exact fix for each. *Source: https://plugins.viglan.com/ga4-purchase-event-not-firing-woocommerce/* Your store takes orders all day, but GA4 shows a fraction of the revenue — or none at all. Missing purchase events are the single most common WooCommerce tracking failure, and in our experience nearly every case comes down to one of seven causes. Work through them in order; each takes a few minutes to check. ## 1. The thank-you page never loads The purchase event traditionally fires on the order-received (thank-you) page. Payment providers that redirect off-site (iDEAL, Bancontact, PayPal, Klarna) sometimes return customers to the homepage, or the customer closes the tab at the bank. If the thank-you page never renders, a purely client-side purchase event never fires. **Fix:** compare GA4 purchases against WooCommerce orders for the same period. If gateway orders are underrepresented, you need tracking that does not depend on the thank-you page rendering — either an order-status-based server-side event (Measurement Protocol) or at minimum a data layer that also fires when the customer visits their order confirmation later. ## 2. A consent banner is (correctly) blocking the tag With Consent Mode v2, GA4 tags wait for `analytics_storage` consent. If your banner never updates the consent state — a misconfigured CMP, a category mismatch, a banner that only writes its own cookie — the purchase tag stays blocked forever, even for customers who clicked “accept”. **Fix:** open GTM Preview mode, complete a test order, and watch the Consent tab. You should see a `consent default` (denied) followed by a `consent update` (granted) before the purchase tag fires. No update event = your CMP is not wired to Consent Mode. ## 3. Duplicate prevention gone wrong — or missing Two opposite failure modes. Some setups fire purchase on every thank-you page load, so a customer refreshing the page inflates revenue (and later, someone “fixes” this by blocking the event entirely). Others add a cookie-based guard that also blocks the *first*, legitimate event when the confirmation page redirects through an intermediate URL. **Fix:** deduplicate per *order*, not per pageview or session: record that order #1234 was tracked (order meta server-side, or a transaction-ID exclusion in GA4) and skip only that order in future. Refreshes then cannot double-count, and new orders always fire. ## 4. The Blocks checkout broke your classic hooks WooCommerce’s newer Cart and Checkout Blocks do not fire the classic PHP hooks that most tracking snippets rely on. If tracking worked until a theme or WooCommerce update and then silently stopped, this is the first thing to check. **Fix:** confirm whether your checkout uses Blocks (edit the Checkout page — do you see block components or a `[woocommerce_checkout]` shortcode?). Blocks checkouts need a JavaScript integration that subscribes to the Store API events instead of the classic hooks. ## 5. Wrong or unvalidated IDs A GTM container ID where a GA4 measurement ID belongs, a typo like `G-XXXXXXX0` vs `G-XXXXXX0X`, or a container that was never published. Everything looks configured, nothing arrives. **Fix:** in GA4, open Admin → DebugView, enable debug on your site, and send a test event. If DebugView shows nothing, the ID/stream is wrong or the tag never loads. Also confirm the GTM container version currently published actually contains your GA4 tags — Preview mode uses the draft. ## 6. An ad blocker (or the browser itself) ate the request 25–40% of customers block gtag/GTM requests outright, and Safari’s tracking prevention truncates what remains. Client-side tracking alone therefore *always* undercounts — the only question is by how much. **Fix:** you cannot fix the browser. You can add a server-side purchase event via the GA4 Measurement Protocol, deduplicated against the browser event by transaction ID, so blocked browsers still report revenue from your server. ## 7. The payload is malformed GA4 silently drops ecommerce events that break its schema: `value` as a string with a currency symbol, missing `currency`, items without `item_id`/`item_name`, or a purchase pushed before the previous `ecommerce` object was cleared. **Fix:** in GTM Preview, inspect the dataLayer at the moment of purchase. Compare field-by-field against Google’s official `purchase` reference. The classic mistake: forgetting `ecommerce: null` before each push, so old items leak into new events. ## The systematic way out Every fix above shares a theme: purchase tracking has to be *engineered* — order-level deduplication, Blocks support, consent integration, schema-perfect payloads, and a server-side fallback — not pasted in as a snippet. *TrackPilot handles everything in this guide automatically — a spec-compliant GA4 dataLayer for WooCommerce with Consent Mode v2, purchase deduplication and a built-in debugger. [See TrackPilot →](https://plugins.viglan.com/plugins/trackpilot-for-woocommerce-ga4-gtm-tracking-pro/)*