如何在Woocommerce中实现COD与卡支付对应不同配送方式且可正常切换?
解决WooCommerce支付方式切换后无法更改配送方式的问题
你的问题核心在于两点:一是支付方式切换时未触发配送费率的重新计算,二是原代码未处理「未选择支付方式」的初始状态,导致配送方式被强制隐藏后无法恢复。
修复后的完整代码
// 根据支付方式显示/隐藏对应配送方式 add_action( 'woocommerce_package_rates', 'show_hide_shipping_methods_based_on_payment', 20, 2 ); function show_hide_shipping_methods_based_on_payment( $rates, $package ) { // 仅在结账页面执行逻辑 if ( ! is_checkout() || is_wc_endpoint_url() ) { return $rates; } // 获取当前选中的支付方式(兼容未选择的初始状态) $chosen_payment = WC()->session->get('chosen_payment_method') ?? ''; // 卡支付对应的支付方式ID集合 $card_payment_ids = array('monri', 'bacs'); // 需要隐藏的COD对应配送方式ID $cod_shipping_id = 'flexible_shipping_single:10'; // 选中卡支付时,隐藏COD配送方式;其他情况保留所有配送方式 if ( in_array( $chosen_payment, $card_payment_ids ) && isset( $rates[$cod_shipping_id] ) ) { unset( $rates[$cod_shipping_id] ); } return $rates; } // 支付方式切换时触发配送方式重新计算 add_action( 'woocommerce_review_order_before_payment', 'trigger_shipping_recalculation_on_payment_switch' ); function trigger_shipping_recalculation_on_payment_switch() { ?> <script type="text/javascript"> jQuery(function($){ $('form.checkout').on('change', 'input[name="payment_method"]', function(){ // 触发WooCommerce内置的结账更新事件,强制刷新配送方式 $(document.body).trigger('update_checkout'); }); }); </script> <?php } // 确保选中的支付方式实时同步到会话 add_action( 'woocommerce_checkout_update_order_review', 'update_chosen_payment_method_session' ); function update_chosen_payment_method_session( $posted_data ) { parse_str( $posted_data, $output ); if ( isset( $output['payment_method'] ) ) { WC()->session->set('chosen_payment_method', $output['payment_method']); } }
代码关键调整说明
- 配送逻辑优化:提升钩子优先级到20(确保晚于其他配送规则执行),增加结账页面判断,用
in_array简化支付方式匹配,同时添加isset检查避免报错。 - 实时刷新触发:通过JS监听支付方式切换事件,调用
update_checkout强制WooCommerce重新计算配送费率,实现配送方式的实时切换。 - 会话同步:通过
woocommerce_checkout_update_order_review钩子,确保用户选中的支付方式实时存入会话,避免获取到旧的支付方式值。
使用注意事项
- 替换
flexible_shipping_single:10为你实际的COD配送方式ID(可通过浏览器开发者工具查看结账页面的配送选项ID)。 - 确认
monri和bacs是你卡支付对应的正确支付方式ID(可在WooCommerce后台支付方式设置页查看)。 - 添加代码后,进入WooCommerce → 设置 → 配送,点击「清除配送缓存」按钮生效。
内容的提问来源于stack exchange,提问作者Josip Bogdan
相关产品推荐
相关产品推荐

