GA4 Refund Tracking for WooCommerce: The Missing Half of Revenue Accuracy

July 7, 2026

Ask a store owner if their GA4 tracks purchases and you’ll get a confident yes. Ask about refunds and you’ll usually get silence. The result is systematic: GA4 revenue drifts upward relative to reality, month after month, and every ROAS decision made on it is slightly wrong in the expensive direction.

Why refunds matter more than they look

Typical WooCommerce refund rates run 2–8% (far higher in apparel). If you spend on ads with a target ROAS, an 8% overstatement of revenue is an 8% overstatement of every campaign’s performance — enough to keep a losing campaign alive for quarters. Refund tracking is not bookkeeping pedantry; it is what makes your ad optimization honest.

How GA4’s refund event actually works

GA4 has a first-class refund event with two modes:

The one hard requirement: the transaction_id must exactly match the original purchase’s. If your purchase used the order number and your refund uses the order ID (not always the same in WooCommerce!), GA4 records an orphan refund that reverses nothing.

Why almost nobody sends it

Refunds happen in wp-admin, not in the customer’s browser. There is no thank-you page, no GTM container running, no dataLayer — the entire client-side tracking stack is absent at the moment the refund exists. So the event must originate server-side: hook WooCommerce’s refund creation, build the payload from the refund object, and send it via the Measurement Protocol. Snippet-based setups structurally cannot do this, which is why the refund event is the clearest dividing line between pasted-in tracking and engineered tracking.

Wiring it correctly (the checklist)

  1. Hook the right event: WooCommerce’s refund hook fires for both full and partial refunds — inspect the refund object rather than assuming full.
  2. Reuse the purchase’s transaction_id source. Whatever produced the purchase ID (order number, usually) must produce the refund’s. Centralize it in one function.
  3. Send refunded items for partials with per-line quantities from the refund object, and the refund’s value with the same tax basis as your purchases.
  4. Mind the API secret: Measurement Protocol needs your GA4 API secret server-side. Keep it out of the browser and out of git.
  5. Verify in DebugView: refund a €1 test order and watch the event arrive with matching transaction_id. Then check the Monetization report a day later — the revenue should visibly step down.

The compounding payoff

Once refunds flow, three things quietly improve: ROAS becomes truthful, LTV cohorts stop overcounting serial refunders, and finance stops asking why GA4 and the bank disagree. It is one of the highest leverage/effort ratios in the whole analytics stack.

TrackPilot wires the whole pipeline for you — spec-compliant GA4 events for WooCommerce including one-per-order purchases and refunds, with Consent Mode v2. See TrackPilot →

Liked this? The plugins do the heavy lifting.

Browse the plugins