What matters first: WooCommerce tracks whether stock was reduced, but custom code, imports, duplicated webhooks or manual status cycles can bypass or reset that protection.
What double stock reduction actually means
The order notes, metadata and inventory-system logs show each reduction event and actor.
Reconstruct every inventory adjustment
- Capture affected order IDs, line items and stock history.
- Inspect _order_stock_reduced and order status transitions.
- Review webhook retries, imports and custom inventory hooks.
- Compare WooCommerce with ERP or warehouse adjustment logs.
Where the second reduction usually comes from
- Duplicate callback: The same payment event triggers stock code repeatedly.
- Custom hook: A plugin reduces stock in addition to WooCommerce core.
- Status cycling: Orders move backward and forward through reducing states.
- External sync loop: WooCommerce and ERP each apply the other’s adjustment.
Make inventory writes idempotent
- Identify one authoritative inventory adjustment path.
- Add event/order idempotency to custom or external handlers.
- Correct historical quantities only after transaction-level reconciliation.
- Test payment, cancellation, refund and webhook replay.
Duplicate event or competing stock handler?
A duplicated callback leaves a repeated event trail; a competing plugin hook can reduce stock even when the payment event appears only once. Compare order notes, _order_stock_reduced, webhook IDs and the ERP or warehouse ledger before changing anything. The repair is either idempotency at the event boundary or removal of the second inventory writer.
If the second inventory write starts with duplicated commercial events, compare the trace with duplicate WooCommerce orders and duplicate payment retries. If neither reproduces, focus on inventory-specific hooks or ERP synchronisation instead of changing checkout behaviour.
Why resetting stock flags can make it worse
Do not reset _order_stock_reduced blindly. That flag protects against repeated core reduction and changing it can trigger another adjustment.
Replay the full order lifecycle
- Each order affects stock according to policy exactly once.
- Webhook replay and status edits do not duplicate inventory changes.
- External and WooCommerce stock ledgers reconcile.
Close the incident only after a normal payment, webhook replay, status edit and refund each leave one auditable inventory adjustment and WooCommerce still reconciles with the ERP or warehouse ledger.
WP REPAIR INCIDENT STANDARD
How to narrow the fault without guessing
The order notes, metadata and inventory-system logs show each reduction event and actor.
Capture affected order IDs, line items and stock history.
Inspect _order_stock_reduced and order status transitions.
Review webhook retries, imports and custom inventory hooks.
Compare WooCommerce with ERP or warehouse adjustment logs.
What must be verified
- Each order affects stock according to policy exactly once.
- Webhook replay and status edits do not duplicate inventory changes.
- External and WooCommerce stock ledgers reconcile.
Official technical sources
Continue the diagnosis
This guide explains the diagnosis. If the site is affected now, the intervention should preserve a rollback path and verify the real business journey.
See the emergency repair service →ABOUT THIS SYMPTOM
Frequently asked questions about this guide.
Is it safe to reset the _order_stock_reduced flag to fix this?+
No. That metadata flag exists specifically to stop WooCommerce core from reducing stock twice for the same order, so clearing it can trigger another reduction rather than correcting the one that already happened.
Can a webhook retry cause a double stock reduction even if the code is correct?+
Yes. If a payment gateway resends the same completion event and the handler is not idempotent, the same webhook can trigger the stock-reduction logic more than once for one order.
Does moving an order backward and forward between statuses affect stock?+
It can. Status cycling through reducing states (for example processing to on-hold and back) may cause stock to be reduced again if the code does not check whether it was already reduced for that order.
How do I tell whether WooCommerce or an external system is the source of the duplication?+
Compare the order notes and _order_stock_reduced history in WooCommerce against the ERP or warehouse adjustment log for the same order and timestamp. Whichever system shows an adjustment without a corresponding trigger on the other side is the one applying an extra change.