如何在woocommerce_order_status_changed钩子中强制清空购物车
问题:WooCommerce触发
woocommerce_order_status_changed钩子时无法清空购物车 - 需求:在
woocommerce_order_status_changed钩子内强制清空购物车,尝试多段代码无效且无报错 - 疑问:是否遗漏关键步骤?是否需要获取并使用当前用户ID?
- 更新:仅在折扣规则导致实付金额为0欧元的订单中出现此问题,推测是WooCommerce未自动触发购物车清空逻辑的原因
尝试过的代码
代码1
add_action('woocommerce_order_status_changed', 'so_status_completed', 10, 3); function so_status_completed($order_id, $old_status, $new_status){ if($new_status == 'processing' || $new_status == 'on-hold'){ global $woocommerce; $woocommerce->cart->empty_cart(); WC()->cart->empty_cart(true); WC()->session->set('cart', array()); } }
代码2(添加在主题functions.php中)
add_action('woocommerce_new_order','clear_the_cart'); function clear_the_cart() { global $woocommerce; $woocommerce->cart->empty_cart(); WC()->cart->empty_cart(); }
解决方案
核心原因
- 实付金额为0的订单,WooCommerce默认流程会跳过部分购物车清空逻辑
woocommerce_order_status_changed钩子可能在后台/异步环境触发,直接调用WC()->cart无法正确关联当前前端用户的会话,导致清空操作不生效
修正后的代码
add_action('woocommerce_order_status_changed', 'clear_cart_on_order_status_change', 20, 4); function clear_cart_on_order_status_change($order_id, $old_status, $new_status, $order) { // 仅在目标状态触发 if (!in_array($new_status, ['processing', 'on-hold'])) { return; } // 获取订单关联用户ID $user_id = $order->get_user_id(); // 处理游客用户会话 if ($user_id === 0) { $session_id = $order->get_customer_id(); if (empty($session_id)) return; WC()->session->set_customer_session_cookie(true); WC()->session->init_session($session_id); } // 处理登录用户购物车 else { WC()->cart->set_customer_id($user_id); WC()->cart->load_cart(); } // 强制清空并同步会话数据 WC()->cart->empty_cart(true); WC()->session->set('cart', []); WC()->session->save_data(); }
关键说明
- 优先级设为
20,确保在WooCommerce默认操作后执行,避免被覆盖 - 同时兼容登录用户和游客用户的会话场景
empty_cart(true)参数会同时移除购物车中的优惠券、附加费用,实现完全清空
内容的提问来源于stack exchange,提问作者JPashs
相关产品推荐
相关产品推荐

