WooCommerce 11.1 adds server-computed refund totals and a preview endpoint. Clients can send line IDs and quantities instead of reproducing tax and rounding logic. Stores below 11.1 can silently ignore the new flag, so a quantity-only request may create a zero-value refund if capability detection is skipped.
Use this for ERP returns, customer-service tools, marketplace integrations, headless dashboards, partial refunds, tax-inclusive stores, multicurrency plugins, gateway refunds, and any REST client that creates WooCommerce refunds.
Quick answer
Detect support with OPTIONS or the preview route before sending compute_totals. Build an order containing taxed products, shipping, discounts, mixed rates, decimal quantities where supported, and a prior partial refund. Preview one line and compare the response with a dry internal calculation, then create the refund once using a stable request key. Test duplicate line IDs, excessive quantity, negative or zero totals, prior refunds, rounding, gateway failure, timeout after commit, and a client pointed at a pre-11.1 store. Reconcile the created refund, order remaining amount, gateway record, stock, email, and accounting export.
Test scenarios to run
Run the same controlled fixture across these branches. Write down the expected result before testing so a surprising response is easy to identify.
| Scenario | Fixture | Expected result |
| Supported store | Preview then create | Same computed line totals |
| Old store | Quantity-only request | Blocked before zero refund |
| Prior refund | Remaining quantity | Cap enforced |
| Lost response | Same request key | No duplicate refund |
Diagnostic table
Use this table to connect the observed behavior to evidence and a verification step.
| Action | Evidence | Verification |
| Detect endpoint capability | Record WooCommerce version, endpoint schema, order currency, precision, tax display, tax rates, coupon allocation, shipping, gateway, HPOS state, existing refunds, and client request ID. | Preview and created refund totals match for product, tax, shipping, and discounts. |
| Preview the exact fixture | Call OPTIONS and the preview endpoint to prove compute_totals support before a quantity-only create request can run. | Pre-11.1 stores cannot receive unsafe quantity-only requests. |
| Validate remaining amounts | Compare preview and creation across full line, partial quantity, multiple tax rates, discount allocation, shipping refund, prior refund, and multicurrency fixtures. | Repeated or timed-out requests produce one business refund. |
| Create with replay protection | Inject duplicate line IDs, quantity above remaining, amount mismatch, provider failure, response timeout, and replay with the same request identity. | WooCommerce, gateway, stock, email, webhook, and accounting records reconcile. |
What to check first
- Record WooCommerce version, endpoint schema, order currency, precision, tax display, tax rates, coupon allocation, shipping, gateway, HPOS state, existing refunds, and client request ID.
- Call OPTIONS and the preview endpoint to prove compute_totals support before a quantity-only create request can run.
- Compare preview and creation across full line, partial quantity, multiple tax rates, discount allocation, shipping refund, prior refund, and multicurrency fixtures.
- Inject duplicate line IDs, quantity above remaining, amount mismatch, provider failure, response timeout, and replay with the same request identity.
- Reconcile refund rows, order totals, remaining refundable amount, gateway reference, stock action, email, webhook, analytics, and accounting output.
Field notes
- Write the pass condition before changing anything and keep one repeatable synthetic fixture for the full test window.
- Record exact versions and UTC timestamps because deployments, caches, retries, scheduled actions, and background jobs can change the evidence.
- Test the public path and the stored server-side result, not only an admin preview, isolated command, or API response.
- Repeat verification after the relevant cache, queue, cron, webhook, and observation window has completed.
Useful command or data shape
Adapt paths, IDs, and privacy handling to the site before running commands or storing data on production.
curl -sS -X OPTIONS https://example.com/wp-json/wc/v3/orders/723/refunds
curl -sS -X POST https://example.com/wp-json/wc/v3/orders/723/refunds/preview -H 'Content-Type: application/json' -d '{"line_items":[{"line_item_id":111,"quantity":1}]}'
Why this usually happens
- A client assumes the new field is enforced on every WooCommerce version.
- Tax-inclusive and tax-exclusive values are mixed in the same payload.
- A prior partial refund changes what remains refundable after a preview was cached.
- A provider accepts the money movement before the caller receives a response.
Decision rule
Ship the client only when unsupported stores are blocked, preview and creation agree, invalid quantities fail clearly, and an ambiguous retry cannot create a second refund.
Production verification checklist
- Preview and created refund totals match for product, tax, shipping, and discounts.
- Pre-11.1 stores cannot receive unsafe quantity-only requests.
- Repeated or timed-out requests produce one business refund.
- WooCommerce, gateway, stock, email, webhook, and accounting records reconcile.
Safe fix order
Use a sequence that makes each result easy to prove. Stop when new evidence changes the scope or owner of the problem.
- Detect endpoint capability
- Preview the exact fixture
- Validate remaining amounts
- Create with replay protection
- Reconcile money and records
Mistakes to avoid
- Changing production before recording exact plugin versions, UTC timestamps, a stable fixture, the expected result, and a tested rollback point.
- Treating one successful screen as proof while stored records, logs, queues, caches, emails, APIs, and downstream systems remain unchecked.
- Testing only as an administrator instead of using the role, device, locale, cache state, payment state, and failure branch that customers reach.
- Leaving temporary exclusions, debug output, test accounts, broad permissions, or one-off repair code active after verification.
Questions teams ask during testing
Can I run this directly in production?
Begin with read-only evidence and use staging for package, database, checkout, form, permission, or security changes. If a production canary is necessary, make it identifiable, reversible, monitored, and unable to expose personal data or charge a customer.
How do I avoid a false positive?
Repeat the same fixture with the same versions, role, URL, locale, cache state, and integrations. Compare browser, stored, API, and log evidence instead of relying on one screen.
What should the evidence packet contain?
Keep UTC time, exact versions, synthetic record ID, expected result, actual result, relevant log lines, change made, rollback point, owner, and final verification. Redact secrets and personal data.
When is the test complete?
Close the work when the primary path passes, failure branches are understood, stored and downstream records reconcile, temporary changes are removed, and monitoring covers the next update.
What to tell the client or owner
Give the owner a concise packet with the affected workflow, exact versions, UTC test time, fixture ID, expected result, actual result, key logs, change made, rollback point, final result, unresolved risks, owner, and next review date. Remove credentials and personal data before sharing it.
When HandL WP should help
Bring in help when this affects leads, checkout, search visibility, security, paid media reporting, or a client production site. HandL WP can trace the issue through WordPress, hosting, cache, tracking, and Search Console, then verify the workflow after the technical fix.
If this is active on a production site, have HandL WP test WooCommerce refund integrations.
Related HandL WP guides
Use these related guides when the same issue touches tracking, security, checkout, or crawler visibility.
Helpful references