WooCommerce手动续订订单无法自动完成,寻求代码修复方案
问题分析与解决方案
一、原代码失效原因
woocommerce_thankyou钩子:仅在用户完成结账跳转至感谢页面时触发,但100%折扣的手动续订订单可能不走常规结账流程,订单创建后直接处于pending状态,不会触发该钩子。woocommerce_subscription_payment_complete钩子:仅在订阅支付完成时触发,而100%折扣订单无实际支付动作,因此不会触发这个钩子。- 未针对Manual Renewal类型订单做判断,也未检查订单是否为0金额(100%折扣)的核心条件。
二、修正后的代码方案
以下代码会在订单创建时,自动检测符合条件的订单并标记为completed:
add_action( 'woocommerce_new_order', 'auto_complete_manual_renewal_zero_orders', 20, 2 ); function auto_complete_manual_renewal_zero_orders( $order_id, $order ) { // 跳过已完成订单 if ( $order->get_status() === 'completed' ) { return; } // 检查是否为订阅相关订单(父订单或续订订单) $is_subscription_order = wcs_order_contains_subscription( $order_id ) || wcs_is_subscription( $order_id ); if ( ! $is_subscription_order ) { return; } // 检查是否为Manual Renewal类型订阅 $subscription = wcs_get_subscription_for_order( $order_id ); if ( ! $subscription || $subscription->get_payment_method() !== 'manual' ) { return; } // 检查订单总金额是否为0(100%折扣) if ( $order->get_total() > 0 ) { return; } // 更新订单状态为completed,触发相关系统动作 $order->update_status( 'completed', '自动完成100%折扣的手动续订订单', true ); // 若为续订订单,同步更新订阅状态为active if ( wcs_is_renewal_order( $order_id ) ) { $subscription->update_status( 'active', '续订订单完成,恢复订阅激活状态', true ); } }
代码说明:
- 选用
woocommerce_new_order钩子:在订单创建完成后立即触发,覆盖所有订单创建场景。 - 多层条件判断:确保只处理订阅相关订单、Manual Renewal支付方式、0金额订单,避免影响正常付费订单流程。
- 同步订阅状态:续订订单完成后自动将订阅恢复为
active,避免订阅处于on-hold状态。
三、取消Manual Renewal订单自动生成的方案
如果希望Manual Renewal类型的订阅不再自动生成续订订单,可通过以下两种方式实现:
方式1:设置订阅为永久激活
针对已有的Manual Renewal订阅,直接设置为永久激活,取消后续续订计划:
add_action( 'woocommerce_subscription_status_updated', 'set_manual_subscriptions_to_permanent', 10, 3 ); function set_manual_subscriptions_to_permanent( $subscription_id, $old_status, $new_status ) { $subscription = wcs_get_subscription( $subscription_id ); // 仅处理Manual Renewal类型订阅 if ( $subscription->get_payment_method() !== 'manual' ) { return; } // 清除订阅结束日期,设置为永久激活 $subscription->set_date( 'end', null ); $subscription->update_status( 'active', '设置为永久激活,取消自动续订', true ); $subscription->save(); }
方式2:拦截续订订单创建
通过钩子直接禁止生成Manual Renewal类型的续订订单:
add_filter( 'woocommerce_subscription_should_generate_renewal_order', 'disable_manual_renewal_orders', 10, 2 ); function disable_manual_renewal_orders( $should_generate, $subscription ) { // 若为Manual Renewal支付方式,返回false禁止生成续订订单 if ( $subscription->get_payment_method() === 'manual' ) { return false; } return $should_generate; }
注意事项:
- 方式1适合需要保留订阅但无需后续续订的场景,方式2适合完全禁止生成续订订单的场景。
- 操作前建议备份网站数据,避免影响正常订阅流程。
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

