WooCommerce优惠券折扣应用于订单总计的自定义代码求助
WooCommerce 优惠券应用到订单总计的修正方案
原代码问题分析
- 钩子时机冲突:
woocommerce_applied_coupon执行后调用calculate_totals(),会触发WooCommerce默认的优惠券计算逻辑,直接覆盖手动设置的discount_total。 - 总计值不准确:在
woocommerce_applied_coupon阶段,购物车的总计还未完成最终计算,get_total('edit')获取的值可能存在误差。 - 未拦截默认逻辑:没有阻止优惠券的默认折扣计算,导致自定义折扣被覆盖或叠加。
修正后的代码
// 移除默认的优惠券折扣计算逻辑 add_action('woocommerce_before_calculate_totals', function($cart) { if (is_admin() && !defined('DOING_AJAX')) return; // 移除WC_Coupon类默认的折扣添加钩子 remove_action('woocommerce_cart_calculate_fees', 'WC_Coupon::add_discount', 10); }, 9); // 自定义优惠券折扣,基于订单总计计算 add_action('woocommerce_cart_calculate_fees', function($cart) { if (is_admin() && !defined('DOING_AJAX')) return; if (empty($cart->get_applied_coupons())) return; // 获取包含税费、运费的订单总计(编辑模式下的原始值) $grand_total = floatval($cart->get_total('edit')); $total_discount = 0; foreach ($cart->get_applied_coupons() as $coupon_code) { $coupon = new WC_Coupon($coupon_code); // 跳过无效优惠券 if (!$coupon->is_valid()) continue; if ($coupon->is_type('percent')) { // 百分比折扣:订单总计 × 折扣比例 $discount = ($coupon->get_amount() / 100) * $grand_total; $total_discount += $discount; } elseif ($coupon->is_type('fixed_cart')) { // 固定金额折扣:不超过订单总计 $discount = min($coupon->get_amount(), $grand_total); $total_discount += $discount; } } if ($total_discount > 0) { // 添加自定义折扣(负数表示减少总金额) $cart->add_fee(__('优惠券折扣', 'woocommerce'), -$total_discount); // 将折扣值存储到会话,供后续场景调用 WC()->session->set('custom_coupon_discount', $total_discount); } }, 10);
代码说明
- 移除默认逻辑:在购物车计算前,通过
woocommerce_before_calculate_totals钩子移除WooCommerce自带的优惠券折扣计算,避免默认逻辑干扰自定义规则。 - 基于总计计算折扣:在
woocommerce_cart_calculate_fees阶段(购物车费用计算环节),使用订单总计(含税费、运费)重新计算折扣,确保数值准确。 - 兼容多优惠券:遍历所有已应用的优惠券,分别计算折扣后累加,支持百分比和固定金额两种类型。
- 避免负总价:固定金额折扣设置了上限,确保折扣不超过订单总计。
注意事项
- 测试前请清空购物车缓存,或切换浏览器隐私模式验证效果。
- 若店铺税费设置特殊,可根据实际需求调整
$grand_total的获取方式(比如使用$cart->get_cart_contents_total() + $cart->get_shipping_total() + $cart->get_taxes_total()手动计算)。
内容的提问来源于stack exchange,提问作者Greg
相关产品推荐
相关产品推荐

