Skip to main content
Card class: HeroCategory: Ecommerce Platform
refund_total / revenue. The first canary on a quality issue or a deploy regression, pair with top_refunded_products.

At a glance

The dollar share of revenue refunded back to customers in the period. Sums refund objects (separate child posts) divided by gross revenue.
What it countsSUM(refund.total) / SUM(order.total) x 100 for orders in the window where the order status is completed, processing, or refunded. Refund totals come from /wp-json/wc/v3/orders/{id}/refunds (separate refund posts).
REST API endpointGET /wp-json/wc/v3/orders/{id}/refunds for refund objects, plus the orders endpoint for the denominator. Refund object field used: total (negative-signed string decimal).
VAT / tax treatmentCurrency-agnostic ratio. Numerator and denominator are both tax-inclusive total figures, so VAT cancels out in the ratio.
Status filterNumerator covers refunds attached to any order regardless of status. Denominator covers completed + processing + refunded orders so that fully-refunded orders are still in the denominator (they generated revenue, just got refunded).
ShippingRefunds may or may not include shipping back depending on merchant policy. WC stores both line-item and shipping refunds in the same refund object; this card sums all refunded amount.
DiscountsAlready reflected in order.total. Refunds reduce the realised cash figure regardless of discount path.
Refunds (this is the metric)Counts both full and partial refunds. WC creates a refund post per refund event; merchants sometimes issue 2-3 partial refunds against a single order, each adds to the numerator.
Cancelled / failed ordersExcluded from both numerator and denominator. Cancelled orders never got paid; failed orders never authorised.
CurrencyMulti-currency stores: ratio is currency-agnostic (rates dimensionless), but if currencies differ between numerator (refund) and denominator (order), the ratio loses meaning. Filter by currency for accurate per-currency rates.
Channels / sourcesNot filtered. Web, POS, marketplace, and B2B refunds all contribute.
Self-hosted vs managed-WooSame definition. On self-hosted Woo, refund-object polling can lag if the host is slow, refund spikes may show 1-2 days late.
Time window30D vsP
Alert trigger>5% rate, or +25% vsP, driven by sentiment_key: refund_rate
Rolesowner, operations, finance

Calculation

Calculated automatically from your WooCommerce data. See the At a glance summary above for what the metric tracks and the worked example below for a typical reading.

Worked example

A US homewares brand on managed-Woo with a heavy ceramics catalog and known fragility-in-transit issues. Period: 12 Mar 26 to 11 Apr 26 (30D), versus prior 30D.
Refund event typeCountSum of refund.totalNote
Full refunds (status flipped to refunded)64$9,420Damaged in transit, full money back
Partial refunds (replacement of one broken item in a multi-item order)218$14,860Order stays completed, refund posts attached
Multi-step refunds (2-3 refund posts per order)41 orders, 96 posts$5,200Customer disputes that escalated
Total refund value (numerator)378 refund posts$29,480
Denominator (gross revenue from completed + processing + refunded): $384,200.
Refund Rate  =  $29,480 / $384,200 x 100  =  7.67%
Versus prior 30D where the rate was 4.2% (16,180/16,180 / 385,300). The card flags a +3.47 ppt rise and trips the >5% sentiment alert. Five things to notice:
  1. WC’s separate refund objects matter for the count. A single order with 3 partial refunds shows as 3 refund posts in the API. Some merchant-side reports plugins double-count these and report 7-8% rates against this card’s 7.67%, that is plugin-counting noise, not real disagreement.
  2. The fragility pattern hides in partials. Most ceramics breaks generate a partial refund (replace one mug from a 4-pack), not a full refund. Refund-rate cards that count only fully-refunded orders (Shopify-style displayFinancialStatus = REFUNDED) would miss this entirely. The Woo rate captures it because it sums refund-object totals.
  3. Self-hosted server slowness can hide a refund spike. The merchant’s previous host had an 8-hour outage on 25 Mar 26, the indexer missed 14 refund events that day. They appeared in the index 9 hours later, on the wrong calendar day in the WP timezone. For a 30D window this is invisible; for daily granularity it can shift the spike date by a day. Managed-Woo (this brand’s current host) does not show the pattern.
  4. Refund-object accounting confuses the merchant. The brand owner expects 384,200(gross)minus384,200 (gross) minus 29,480 (refunds) = 354,720tolandintheirbank.Theyareright.ButtheWCAdmin"Salesbydate"reportshowsGrosssales=354,720 to land in their bank. They are right. But the WC Admin "Sales by date" report shows Gross sales = 384,200 and Net sales = $354,720; they often misread Gross as the “true” number. This card reads in dollar % to make the leakage visible.
  5. vsP is the diagnostic. A +3.47 ppt rise is the signal Vortex IQ catches. Drilling into Top Refunded Products typically shows 1-2 SKUs (a particular fragile mug, a sale-priced overstock) accounting for 40-60% of the spike.

Sibling cards merchants should reference together

CardWhy pair it with Refund Rate
WC Refund Value TrendThe dollar-amount view. Catches when refund value rises but rate stays flat (denominator growing too).
WC Top Refunded ProductsShows which SKUs drive refunds. 80% from 20% of SKUs is the usual pattern.
WC Total RevenueGross of refunds. Pair to see headline + leakage together.
WC Failed Order RateCousin metric. Failures happen pre-payment; refunds happen post-payment. Different fixes.
BC Refund RateSame separate-refund-object pattern as Woo. Useful peer for agencies.
Shopify Refund RateSaaS-platform peer. Definition differs slightly (status-driven vs object-sum).
Stripe Refund RateCross-check against payment processor for stores using WC Stripe Gateway.

Reconciling against the vendor’s own dashboard

Where to look in WooCommerce Admin: WP Admin → WooCommerce → Reports → Orders → Refunds shows the refund total and count by date. Divide by Sales by date gross sales to compute the rate. WC 4.0+ also exposes Analytics → Revenue with a Refunds column. Other WP Admin views that look like the same number but are not:
  • Stats overview widget: today only, in WP-site timezone.
  • Orders → Filter “Refunded”: shows orders where the parent post status is refunded. Misses partial refunds (the parent stays completed).
Why our number may legitimately differ from WooCommerce Admin:
ReasonDirection of divergence
Time-zone. WC reports run on WP-site timezone (wp_timezone_string()); Vortex IQ on UTC. Refunds processed near midnight on boundary days fall on different sides.+/- 1 day at the boundary
Self-hosted server uptime. Indexer cannot poll during host outage; refund events appear late.Ours temporarily lower; self-resolves
Plugin-version compatibility. Some refund-automation plugins bypass the standard refund post type and store custom meta. The Vortex IQ engine reads shop_order_refund posts only.Either; investigate per-merchant
Refund-object aggregation. WC counts each refund post separately. Some merchant-side plugins collapse multiple refunds into one event.Plugins lower than this card
Currency plugin behaviour. Multi-currency stores: refund posts inherit order currency. If order is converted via FX plugin and refund is in original currency, the ratio breaks. Filter by currency.Material for international stores
Cross-connector reconciliation against Stripe: When the WooCommerce Stripe Gateway is in use, Stripe sees Stripe-routed refunds.
CardExpected relationshipWhat causes legitimate divergence
stripe.stripe_refund_rateStripe rate ~= WC rate for Stripe-only Woo storesStripe sees only Stripe-routed refunds. PayPal refunds, BACS reversals, gift-card returns, manual cash refunds are invisible to Stripe.
paypal.pp_refund_valueSubset, PayPal refunds onlyPayPal-checkout subset by definition.

Known limitations / merchant FAQs

Hosted-vs-self-hosted, does it affect the rate? The number is the same. Self-hosted Woo on flaky hosting may show daily-granularity refund spikes a day late. Status-filter selection, why this set? Numerator: all refund posts attached to orders in the window. Denominator: completed + processing + refunded orders, fully refunded orders are still revenue that got refunded, so they belong in the denominator. Excluding them would understate the rate. Refund-object accounting, what should I expect to see? Each refund event is a separate WC post. A multi-step refund (e.g. customer returns 1 item, then returns another 2 weeks later) is two refund posts. Both contribute to the numerator. The parent order’s status flips to refunded only when refunded amount = order total. Plugin-induced data shape variance, how is this card protected? The Vortex IQ Woo engine reads only the canonical shop_order_refund post type. Plugins that store refund-like activity in custom meta without creating refund posts (rare but exists) are invisible. If you spot a refund in WC Admin that does not appear here, contact support. Multi-currency configuration, how does it affect the rate? Currency-agnostic ratio. But if your store sells in mixed currencies, ensure refund posts inherit their parent order’s currency, multi-currency plugins occasionally store the refund in shop base currency while the order is in customer currency, which makes the ratio meaningless. Filter by currency for accuracy. Why does WooCommerce and Stripe disagree? Stripe sees only WC Stripe Gateway refunds. PayPal refunds, manual cash refunds, gift-card returns, and BACS reversals are invisible to Stripe. Stripe rate <= Woo rate, always. A Stripe rate that matches Woo exactly suggests near-100% Stripe payment mix. Today is jumpy, why? Refund-rate is a ratio of small samples on a daily view. A single 500refundona500 refund on a 5,000-revenue day spikes the rate to 10% on its own. Use rolling 7D / 30D for stable reads. Sync-lag from self-hosted server slowness, how do I detect it? If a refund spike appears 1-2 days late and your host page reported an outage, that is the cause. Self-resolves at the next clean poll. Persistent lag (multi-day) suggests REST API key issues or IP block, contact support. My WP Admin shows a different rate, debug playbook:
  1. Match date range exactly.
  2. Match status filter for the denominator (completed + processing + refunded).
  3. WC’s Refunds report counts refund posts; verify your plugin is not collapsing them.
  4. Multi-currency: filter both views to a single currency.
  5. If gap > 2% after all four checks, contact support.

Tracked live in Vortex IQ Nerve Centre

Refund Rate is one of hundreds of KPI pulses Vortex IQ tracks across WooCommerce and 70+ other ecommerce connectors. Nerve Centre runs the detection layer; Vortex Mind investigates the cause when something moves; Ask Viq lets you interrogate any number in plain English. Start for free or book a demo to see this metric running on your own data.