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

WooCommerce应用指定优惠券时无法移除免费商品问题排查

问题:WooCommerce应用指定优惠券时无法移除自动添加的免费商品

在WooCommerce中,我用两段代码实现功能:第一段能在购物车满40欧元时自动添加0元的“winter”商品(ID为90),功能正常;第二段想要在应用“summer”优惠券时移除该免费商品,但无法生效,具体代码如下:

第一段可用代码

// Add free gifted product for specific cart subtotal
add_action( 'woocommerce_before_calculate_totals', 'check_free_gifted_product' );
function check_free_gifted_product( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    // Settings
    $free_product_id   = 90;
    $targeted_subtotal = 20;

    $cart_subtotal     = 0; // Initializing

    // Loop through cart items (first loop)
    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ){
        // When free product is is cart
        if ( $free_product_id == $cart_item['product_id'] ) {
            $free_key = $cart_item_key;
            $free_qty = $cart_item['quantity'];
            $cart_item['data']->set_price(0); // Optionally set the price to zero
        } else {
            $cart_subtotal += $cart_item['line_total'] + $cart_item['line_tax'];
        }
    }

    // If subtotal match and free product is not already in cart, add it
    if ( ! isset($free_key) && $cart_subtotal >= $targeted_subtotal ) {
        $cart->add_to_cart( $free_product_id );
    }

}

// Display free gifted product price to zero on minicart
add_filter( 'woocommerce_cart_item_price', 'change_minicart_free_gifted_item_price', 10, 3 );
function change_minicart_free_gifted_item_price( $price_html, $cart_item, $cart_item_key ) {
    $free_product_id   = 90;
    
    if( $cart_item['product_id'] == $free_product_id ) {
        return wc_price( 0 );
    }
    return $price_html;
}

第二段无效代码

function remove_free_product($cart) {
    /**
     * This function removes a free product "winter" from the cart if a coupon "summer" is applied.
     * 
     * Parameters:
     * $cart (array): An array containing the cart items and their details
     * 
     * Returns:
     * array: The updated cart array
     */
    try {
        // Check if the cart is empty
        if (empty($cart)) {
            throw new Exception("Cart is empty");
        }
        
        // Check if the coupon "summer" is applied
        $coupon_applied = false;
        foreach ($cart as $item) {
            if ($item['coupon'] == 'summer') {
                $coupon_applied = true;
                break;
            }
        }
        
        // Remove the free product "winter" if the coupon "summer" is applied
        if ($coupon_applied) {
            foreach ($cart as $key => $item) {
                if ($item['product'] == 'winter' && $item['price'] == 20) {
                    unset($cart[$key]);
                    break;
                }
            }
        }
        
        // Return the updated cart
        return $cart;
    } catch (Exception $e) {
        // Log the error
        error_log("Error: " . $e->getMessage());
        return array();
    }
}

问题原因分析

无效代码存在3个核心问题:

  • 未挂载到WooCommerce钩子:仅定义了函数,但没有通过add_action关联到购物车处理的钩子,导致代码永远不会被执行。
  • 优惠券与商品检查逻辑错误:
    • 直接遍历$cart找优惠券是错误的,WooCommerce购物车对象需要用$cart->get_applied_coupons()获取已应用优惠券列表。
    • 用$item['product'] == 'winter'判断商品不准确,应该用商品ID(90);且你设置该商品价格为0,代码里却判断$item['price'] == 20,逻辑矛盾。
  • 购物车修改方式错误:直接unset($cart[$key])不符合WooCommerce规范,应该用官方提供的$cart->remove_cart_item()方法操作购物车。

修复后的代码

将以下代码替换原无效代码,确保和第一段代码一样挂载到购物车计算钩子,且优先级更高(先执行移除,再执行添加):

add_action( 'woocommerce_before_calculate_totals', 'remove_free_product_on_coupon', 9 );
function remove_free_product_on_coupon( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    // 配置项
    $free_product_id = 90;
    $target_coupon   = 'summer';

    // 检查是否应用了目标优惠券
    if ( in_array( $target_coupon, $cart->get_applied_coupons() ) ) {
        // 遍历购物车移除目标商品
        foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
            if ( $cart_item['product_id'] == $free_product_id ) {
                $cart->remove_cart_item( $cart_item_key );
                break; // 找到后退出循环,避免重复操作
            }
        }
    }
}

关键说明

  • 钩子优先级设为9,比第一段代码的默认优先级10高,确保移除逻辑先执行,防止刚移除的商品被重新添加。
  • 使用$cart->get_applied_coupons()正确获取已应用优惠券,避免错误遍历。
  • 通过商品ID(90)精准识别目标商品,和第一段代码的配置保持一致。
  • 用WooCommerce官方方法修改购物车,确保操作符合插件规范。

内容的提问来源于stack exchange,提问作者eros casula

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 21:07:21