Documentation Fundamentals

The refund Event in Google Analytics 4 (GA4)

The refund event in Google Analytics 4 (GA4) is used to track refunds—when a purchase is fully or partially reversed.

This is especially important if you’re using GA4 data (or conversions derived from it) to evaluate campaign performance: revenue is only a meaningful optimization target if it actually sticks. Without tracking refunds, some channels might look significantly better than they actually are.

Screenshot of a return/refund view in a shop backend
Refunds are typically not triggered by the user in the browser, but processed later in the shop backend (or ERP).

The refund event is one of the e-commerce events in GA4. You can (and should) enrich it—just like purchase—with parameters like transaction_id, value, and items to properly attribute refunds to the original order and affected products.

Implementation

The best place to trigger refund is usually not the browser, but your backend or shop system: refunds often happen days later, without the user being on your website. Server-side tagging is ideal here because you can send refunds reliably, completely, and without timing issues.

Screenshot of a return/refund form
Return forms or self-service return flows can also provide a signal—but what matters is that the refund event is only sent when the refund actually happens.

Required fields

For refund, transaction_id is critical: the ID must exactly match the original order (i.e., the purchase transaction_id).
If you send an amount (value), also set currency.

Full vs. partial refunds

  • Full refund: You submit the total refund amount as value and optionally all items.
  • Partial refund: You submit only the items actually refunded in items and set value to the sum of refunded line items (plus any prorated shipping/tax corrections if applicable).

The key point: transaction_id must match the original purchase transaction. Only then can the data be cleanly linked later.

One more detail from practice: value for refund is typically sent as a positive number (e.g., 29.90) because the event itself already carries the meaning “refund.” Negative values tend to cause confusion in many setups.

dataLayer

If you do need to track refunds browser-side or via an order confirmation/self-service page, the event can look like this:

javascript
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
    event: "refund",
    ecommerce: {
        currency: "EUR",
        value: 29.90,
        transaction_id: "T12345",
        items: [{
            item_id: "SKU12345",
            item_name: "Superfood Powder",
            item_category: "Superfoods",
            item_variant: "500g",
            item_brand: "MySupplements",
            price: 29.90,
            quantity: 1
        }]
    }
});
Show all code

Common pitfalls

  • Refund without transaction_id: Without it, you won’t be able to meaningfully attribute refunds later.
  • Partial refund without items: If you’re only refunding part of an order, the items array is especially important—otherwise it won’t be clear which products were affected.
  • Gross vs. net: Stay consistent with your purchase setup (e.g., net revenue in value with taxes separate). Mixed approaches quickly make analysis unusable.