
本文介绍如何通过代码精准控制 woocommerce 订阅插件(woocommerce subscriptions)中“手动续订”功能的启用范围,仅对指定变体(如一次性付款变体)开启手动续订,而保留其他变体(如月付)的自动续订能力。
在 WooCommerce 中使用 WooCommerce Subscriptions 插件时,默认的「手动续订」设置(woocommerce_subscriptions_accept_manual_renewals)是全局生效的——一旦启用,所有订阅产品均支持手动续订;若关闭,则全部禁用。但实际业务中,常需差异化处理:例如一个可变订阅产品包含「月付」与「一次性付费(24个月有效期)」两个变体,前者应保持自动续订(按月扣款),后者本质上无周期性,理应禁用自动续订、仅允许手动触发(如对接离线支付或银行转账等手动网关)。
要实现按变体粒度控制手动续订开关,不能依赖后台设置,而需钩挂 pre_option_woocommerce_subscriptions_accept_manual_renewals 过滤器,在关键上下文(如结账流程)中动态返回 'yes' 或原始值。以下为推荐实现方案:
add_filter( 'pre_option_woocommerce_subscriptions_accept_manual_renewals', 'conditionally_enable_manual_renewal_for_variations', 10, 3 );
function conditionally_enable_manual_renewal_for_variations( $pre, $option, $default ) {
// 仅在结账页面执行判断(避免前台/管理页误触发)
if ( ! is_checkout() || ! class_exists( 'WC_Subscriptions_Cart' ) ) {
return $pre;
}
// 定义需要启用手动续订的变体 ID(务必替换为你的实际变体ID)
$target_variation_ids = array( 1631818389, 1631818390 );
// 遍历购物车商品
foreach ( WC()->cart->get_cart() as $cart_item ) {
$product_id = $cart_item['data']->get_id();
// 若当前商品是目标变体之一,则强制启用手动续订
if ( in_array( $product_id, $target_variation_ids, true ) ) {
return 'yes';
}
}
// 其他情况:保持默认行为(即遵循后台设置)
return $pre;
}✅ 关键说明与注意事项:
- ✅ ID 必须是变体 ID(variation ID),而非父级可变产品 ID。你可在 WordPress 后台 → 产品 → 编辑该可变产品 → 切换到「变体」选项卡,鼠标悬停在对应变体的「编辑」链接上,URL 中 post= 后的数字即为变体 ID。
- ✅ 此逻辑仅在 is_checkout() 时生效,确保不影响订单管理、用户账户页等其他场景;同时检查 WC_Subscriptions_Cart 类是否存在,增强插件兼容性。
- ⚠️ 若用户同时加入月付变体和一次性变体,本方案会因匹配到任一目标变体而启用手动续订——这可能导致月付订单也失去自动续订。如需更精细控制(例如「仅当购物车中仅有一次性变体时才启用」),可改为统计匹配数量并结合 WC_Subscriptions_Cart::cart_contains_subscription() 进行复合判断。
- ? 最终效果:匹配变体生成的订阅将显示「手动续订」按钮(在 My Account → Subscriptions 页面),且仅支持手动网关(如 Bank Transfer、Cheque);未匹配变体仍走标准自动续订流程。
将上述代码添加至子主题的 functions.php 文件,或通过 Code Snippets 插件安全部署。部署后,请务必在结账流程中创建测试订单并验证订阅状态与续订选项是否符合预期。










