WooCommerce超时订单自动补货问题:非管理员取消订单不生效
Hey there! The issue you're facing is super common with custom restock code—it usually happens because the original snippet only targets the admin-initiated order cancellation flow, not the full range of scenarios where an order gets cancelled (like customer self-service cancellations, failed payments, expired pending orders, etc.).
Let's break down how to fix this by using a more robust set of WooCommerce hooks that cover all order cancellation paths, regardless of who or what triggered the status change.
Here's the Updated Code
/** * Restock inventory when an order is cancelled (works for all cancellation scenarios) */ add_action('woocommerce_order_status_cancelled', 'auto_restock_cancelled_order_items', 10, 1); add_action('woocommerce_order_status_failed', 'auto_restock_cancelled_order_items', 10, 1); // Optional: For failed payments that auto-cancel function auto_restock_cancelled_order_items($order_id) { // Get the order object $order = wc_get_order($order_id); // Check if order exists if (!$order) return; // Loop through each order item foreach ($order->get_items() as $item_id => $item) { $product = $item->get_product(); // Skip if it's not a purchasable product or has no stock management if (!$product || !$product->managing_stock()) continue; $quantity = $item->get_quantity(); $product_id = $item->get_product_id(); $variation_id = $item->get_variation_id(); // Restock the product wc_update_product_stock($product, $quantity, 'increase'); // Optional: Add a note to the order for tracking $order->add_order_note(sprintf(__('Restocked %s units of %s due to order cancellation.', 'woocommerce'), $quantity, $product->get_name())); } }
Key Improvements Over Your Original Code
- Covers all cancellation triggers: The
woocommerce_order_status_cancelledhook fires whenever an order's status changes to "Cancelled"—whether it's done by an admin, the customer via their account, or automatically by WooCommerce (like for expired pending orders). - Optional failed payment support: Added
woocommerce_order_status_failedhook to restock if a payment fails and the order moves to "Failed" status (adjust this if your store handles failed payments differently). - Stock management checks: Ensures we only restock products that actually track inventory, avoiding errors for digital/downloadable products or items without stock enabled.
- Order notes: Adds a clear note to the order so you can see when restocking happened, which is helpful for debugging and record-keeping.
Why Your Original Code Didn't Work
Most likely, your initial snippet was using a hook that only fires when an admin cancels an order directly in the backend (like a custom admin action hook, or it wasn't accounting for non-admin status transitions). By switching to the core WooCommerce order status hooks, we ensure every cancellation scenario triggers the restock.
Just replace your existing code with this snippet, test out a few scenarios (customer cancellation, failed payment, admin cancellation) to confirm it works, and you're good to go!
内容的提问来源于stack exchange,提问作者Daniel Romagnoli

