Woocommerce如何根据订购产品自动为订单分配对应自定义状态
可行实现方案
你之前尝试的方案未生效是因为没有用到WooCommerce Subscriptions插件专属的订单触发钩子,通用的WooCommerce订单状态钩子无法覆盖订阅续订场景的订单生成逻辑,以下是可直接落地的实现方案:
前置确认
先确认你通过WooCommerce Order Status Manager创建的「DO NOT SHIP」自定义状态的slug,通常格式为wc-do-not-ship,如果你的自定义slug不同,需要替换代码中对应位置的参数。
代码实现
将以下代码添加到站点子主题的functions.php文件中,或通过自定义代码片段插件导入即可:
// 1. 新订单(含首次订阅订单)匹配指定产品自动设置DO NOT SHIP状态 add_action( 'woocommerce_checkout_order_processed', 'auto_set_do_not_ship_status_for_specified_product', 20, 1 ); function auto_set_do_not_ship_status_for_specified_product( $order_id ) { if ( ! $order_id ) return; $order = wc_get_order( $order_id ); // 此处填写指定产品ID,示例为8386,多个产品可修改为数组 [8386, xxx] $target_product_ids = [8386]; $has_target_product = false; // 遍历订单商品校验是否包含目标产品 foreach( $order->get_items() as $item ) { if ( in_array( $item->get_product_id(), $target_product_ids ) ) { $has_target_product = true; break; } } if ( $has_target_product ) { // 替换为你实际的DO NOT SHIP状态slug $order->update_status( 'wc-do-not-ship' ); $order->save(); } } // 2. 续订订单自动继承父订阅订单状态/兜底校验产品 add_action( 'woocommerce_subscription_renewal_order_created', 'inherit_do_not_ship_status_for_renewal_orders', 20, 2 ); function inherit_do_not_ship_status_for_renewal_orders( $renewal_order, $subscription ) { // 逻辑1:直接继承关联订阅的初始订单状态 $parent_order = $subscription->get_parent(); if ( $parent_order && $parent_order->has_status( 'wc-do-not-ship' ) ) { $renewal_order->update_status( 'wc-do-not-ship' ); $renewal_order->save(); return; } // 逻辑2:兜底校验,避免父订单漏设状态的情况 $target_product_ids = [8386]; foreach( $renewal_order->get_items() as $item ) { if ( in_array( $item->get_product_id(), $target_product_ids ) ) { $renewal_order->update_status( 'wc-do-not-ship' ); $renewal_order->save(); break; } } }
注意事项
- 代码上线前请先在测试环境验证,确认订单状态流转、支付触发逻辑无冲突
- 若你的站点有其他自定义订单状态流转规则,可调整代码中钩子的优先级数值(数值越大执行越晚),避免规则冲突
- 如果需要添加更多目标产品,直接修改
$target_product_ids数组的参数即可
内容的提问来源于stack exchange,提问作者Luca
相关产品推荐
相关产品推荐

