You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

woocommerce_coupon_get_discount_amount返回值按商品重复应用问题咨询

问题描述

你当前使用woocommerce_coupon_get_discount_amount钩子计算针对特定属性商品的优惠券折扣,但返回的折扣金额会被应用到购物车每个商品行项,导致总折扣重复计算(比如返回100美元,4个商品时总折扣变成400美元)。需求是让折扣仅针对尺寸属性为'Low-Res'的商品生效,且作为单次折扣应用到整个购物车。

问题原因

你误用了钩子的工作逻辑:woocommerce_coupon_get_discount_amount会针对购物车中每个符合优惠券条件的商品行项触发一次,而你当前的代码在每次触发时都计算了所有符合条件商品的总折扣,导致每个行项都叠加了这个总金额,最终总折扣被重复计算。

优化方案

提供两种更合理的实现方式,可根据需求选择:

方式一:正确使用原生优惠券钩子

利用woocommerce_coupon_get_discount_amount的完整参数(共4个:折扣金额、待折扣价格、当前购物车项、优惠券对象),仅对当前符合属性条件的商品行项计算对应折扣,避免重复叠加总金额。

优化后的代码:

/* 仅对'Low-Res'商品应用'free download'优惠券 */
add_filter( 'woocommerce_coupon_get_discount_amount', 'filter_woocommerce_coupon_get_discount_amount', 10, 4 );
function filter_woocommerce_coupon_get_discount_amount( $discount_amount, $price_to_discount, $cart_item, $coupon ) {    
    $target_attribute_value = 'Low-Res';
    $target_coupon_code = 'free download';

    // 仅针对目标优惠券生效
    if ( $coupon->get_code() !== $target_coupon_code ) {
        return $discount_amount;
    }

    // 获取当前商品的尺寸属性
    $product = $cart_item['data'];
    $size_attribute = $product->get_attribute( 'pa_size' );

    // 对符合属性的商品应用全额折扣(实现免费)
    if ( $size_attribute === $target_attribute_value ) {
        return $price_to_discount;
    }

    // 不符合条件则返回原折扣金额
    return $discount_amount;
}

方式二:添加一次性购物车折扣

如果希望折扣作为单次总额展示在购物车底部,而非每个商品行项单独显示,可通过添加负费用的方式实现,确保折扣仅计算一次。

代码示例:

/* 为'Low-Res'商品添加一次性免费折扣 */
add_action( 'woocommerce_cart_calculate_fees', 'add_low_res_free_discount' );
function add_low_res_free_discount() {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;

    $target_attribute_value = 'Low-Res';
    $target_coupon_code = 'free download';
    $discount_total = 0;

    // 检查购物车是否使用了目标优惠券
    $cart = WC()->cart;
    if ( ! $cart->has_discount( $target_coupon_code ) ) {
        return;
    }

    // 计算所有符合属性商品的含税总价
    foreach ( $cart->get_cart() as $cart_item ) {
        $product = $cart_item['data'];
        if ( $product->get_attribute( 'pa_size' ) === $target_attribute_value ) {
            $discount_total += $cart_item['line_total'] + $cart_item['line_tax'];
        }
    }

    // 添加负费用作为折扣
    if ( $discount_total > 0 ) {
        $cart->add_fee( 'Low-Res 免费折扣', -$discount_total, true );
    }
}
方案说明
  • 方式一更贴合WooCommerce优惠券的原生逻辑,折扣会显示在对应商品行项上,符合用户对优惠券的常规认知。
  • 方式二将折扣作为一次性费用扣除,总折扣仅在购物车底部显示一次,适合需要统一展示折扣总额的场景。

内容的提问来源于stack exchange,提问作者Glen Turvey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 07:52:45