WooCommerce结账页按支付方式加折扣:chosen_payment_method获取失败
解决WooCommerce支票支付方式折扣不生效问题
问题根源
WC()->session->get('chosen_payment_method')返回NULL的核心原因:默认情况下WooCommerce仅在提交订单时才会将选中的支付方式存入会话,而你在woocommerce_cart_calculate_fees钩子中尝试获取时,会话内还未同步该值;同时原代码的JS仅触发结账更新,未完成支付方式到会话的同步操作。
修复后的完整代码
// 保存选中的支付方式到会话(兼容登录/未登录用户) add_action('wp_ajax_save_chosen_payment_method', 'save_chosen_payment_method_to_session'); add_action('wp_ajax_nopriv_save_chosen_payment_method', 'save_chosen_payment_method_to_session'); function save_chosen_payment_method_to_session() { if (isset($_POST['payment_method'])) { WC()->session->set('chosen_payment_method', sanitize_text_field($_POST['payment_method'])); wp_send_json_success(); } wp_send_json_error(); } // 根据支付方式计算并添加折扣 add_filter('woocommerce_cart_calculate_fees', 'discount_based_on_payment_method', 10, 1); function discount_based_on_payment_method($cart) { // 避免后台执行折扣计算 if (is_admin() && !defined('DOING_AJAX')) return; $targeted_payment_method = 'cheque'; $chosen_payment_method = WC()->session->get('chosen_payment_method'); if ($chosen_payment_method === $targeted_payment_method) { $discount = $cart->subtotal * 0.10; $cart->add_fee('支票支付折扣', -$discount); } } // 加载结账页面专属JS,处理支付方式变更逻辑 add_action('wp_footer', 'checkout_payment_method_change_js'); function checkout_payment_method_change_js() { // 仅在结账页面加载JS if (!is_checkout()) return; ?> <script type="text/javascript"> (function($){ // 支付方式变更时同步到会话并刷新结账 $('form.checkout').on('change', 'input[name="payment_method"]', function() { var payment_method = $(this).val(); $.ajax({ type: 'POST', url: wc_checkout_params.ajax_url, data: { action: 'save_chosen_payment_method', payment_method: payment_method }, success: function() { $(document.body).trigger('update_checkout'); } }); }); // 页面初始化时,同步已选中的支付方式到会话 var initial_payment_method = $('input[name="payment_method"]:checked').val(); if (initial_payment_method) { $.ajax({ type: 'POST', url: wc_checkout_params.ajax_url, data: { action: 'save_chosen_payment_method', payment_method: initial_payment_method } }); } })(jQuery); </script> <?php }
代码说明
- AJAX会话同步:新增两个AJAX动作,确保登录和未登录用户选中支付方式后,该值能实时存入WooCommerce会话,让折扣计算钩子可以获取到有效数据。
- 折扣逻辑优化:加入后台环境判断,避免不必要的计算;严格匹配支付方式ID,确保逻辑精准。
- JS代码重构:将JS移至
wp_footer钩子,仅在结账页面加载;新增页面初始化同步逻辑,解决页面刷新后会话值丢失的问题;先同步支付方式再刷新结账,保证折扣实时显示。
注意事项
- 确认你的支票支付方式ID确实为
cheque:可在WooCommerce设置→支付方式中,鼠标悬停在支付方式标题上,查看URL中section=wc-settings_gateway_cheque里的标识。 - 测试前清空浏览器缓存,避免旧代码干扰。
内容的提问来源于stack exchange,提问作者josephhartman82
相关产品推荐
相关产品推荐

