在WooCommerce购物车页添加折扣勾选框实现全局金额同步
WooCommerce购物车页自定义折扣勾选框实现方案
以下所有代码可添加到当前主题functions.php文件,或自定义功能插件的主文件中,操作前请先做好站点备份。
1. 在购物车页添加勾选框元素
使用WooCommerce原生钩子将勾选框插入到购物车总额模块上方,同时读取用户session已保存的勾选状态:
// 购物车页添加折扣勾选框 add_action( 'woocommerce_before_cart_totals', 'add_custom_discount_checkbox' ); function add_custom_discount_checkbox() { wp_nonce_field( 'custom_discount_nonce', 'custom_discount_nonce' ); $checked = WC()->session->get( 'custom_discount_applied' ) === 'yes' ? 'checked' : ''; echo '<div class="custom-discount-checkbox" style="margin-bottom:15px;"> <label><input type="checkbox" id="custom_fixed_discount" name="custom_fixed_discount" value="yes" '. $checked .'> 申请固定金额折扣</label> </div>'; }
2. AJAX同步勾选状态并刷新购物车
用户勾选/取消勾选时自动触发请求,将状态保存到用户session,同时刷新购物车、迷你购物车数据:
服务端AJAX处理代码
// 保存折扣勾选状态 add_action( 'wp_ajax_save_custom_discount_status', 'save_custom_discount_status' ); add_action( 'wp_ajax_nopriv_save_custom_discount_status', 'save_custom_discount_status' ); function save_custom_discount_status() { if ( !isset($_POST['nonce']) || !wp_verify_nonce( $_POST['nonce'], 'custom_discount_nonce' ) ) { wp_send_json_error('非法请求'); } $status = isset($_POST['status']) ? sanitize_text_field($_POST['status']) : 'no'; WC()->session->set( 'custom_discount_applied', $status ); wp_send_json_success('状态已更新'); }
前端交互JS代码
// 注入前端交互脚本 add_action( 'wp_footer', 'custom_discount_js_script' ); function custom_discount_js_script() { if ( is_cart() || is_checkout() ) : ?> <script> jQuery(function($){ $('#custom_fixed_discount').on('change', function(){ let status = $(this).is(':checked') ? 'yes' : 'no'; $.ajax({ url: '<?php echo admin_url('admin-ajax.php'); ?>', type: 'POST', data: { action: 'save_custom_discount_status', nonce: $('#custom_discount_nonce').val(), status: status }, success: function(res) { // 刷新所有关联金额模块 $(document.body).trigger('wc_update_cart'); $(document.body).trigger('wc_fragment_refresh'); if ( $('body').hasClass('woocommerce-checkout') ) { $(document.body).trigger('update_checkout'); } } }); }); }); </script> <?php endif; }
3. 全局应用固定折扣
使用WooCommerce全局费用计算钩子,确保折扣在购物车、迷你购物车、结算页所有场景同步生效:
// 全局应用折扣规则 add_action( 'woocommerce_cart_calculate_fees', 'apply_custom_fixed_discount', 20, 1 ); function apply_custom_fixed_discount( $cart ) { if ( is_admin() && !defined('DOING_AJAX') ) return; if ( WC()->session->get('custom_discount_applied') === 'yes' ) { $discount_amount = -10; // 可修改为需要的固定折扣金额,负数代表扣减 $cart->add_fee( '固定专属折扣', $discount_amount, false ); // 第三个参数改为true代表折扣含税 } }
4. 订单提交与数据持久化
提交订单时将折扣状态保存到订单元数据,同时清空用户session避免下次下单重复应用折扣:
// 保存折扣状态到订单元数据 add_action( 'woocommerce_checkout_create_order', 'save_discount_status_to_order', 10, 2 ); function save_discount_status_to_order( $order, $data ) { if ( WC()->session->get('custom_discount_applied') === 'yes' ) { $order->update_meta_data( '_custom_discount_applied', 'yes' ); } WC()->session->set( 'custom_discount_applied', 'no' ); }
5. 后台订单手动修改支持
无需额外开发:通过上述方法添加的折扣会以费用项的形式自动展示在后台订单详情的金额明细中,运营人员可以直接编辑、删除该折扣项,保存订单后系统会自动重新计算总金额,修改结果会同步到后续发送的邮件通知中。
6. 多场景兼容说明
- 订单通知邮件:WooCommerce原生会自动加载费用项明细到所有邮件模板,无需额外修改
- 结算页适配:如需在结算页也显示同款勾选框,可复用上述添加勾选框的代码,将钩子改为
woocommerce_before_checkout_form即可
常见问题排查
- 折扣不生效:检查WooCommerce session是否正常开启,未登录用户可添加
WC()->session->set_customer_session_cookie(true);强制生成session cookie - 迷你购物车不同步:确保AJAX成功回调中触发了
wc_fragment_refresh事件刷新片段缓存 - 金额计算错误:不要直接修改订单总金额,仅编辑对应折扣费用项即可,系统会自动重算总金额
内容的提问来源于stack exchange,提问作者user10273978
相关产品推荐
相关产品推荐

