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

如何为通过URL自动生成的WooCommerce优惠券添加免费商品

问题排查与修复方案

你现有代码的核心问题集中在变量作用域、逻辑分支判断错误两个部分,以下是具体问题点和修复后的完整代码:

存在的问题

  • $regular_price 仅在购物车已存在免费商品的场景下会被赋值,首次触发添加免费商品逻辑时调用该变量会触发PHP未定义变量报错
  • $cart_count 定义在购物车遍历循环内部,若购物车无免费商品时调用该变量也会出现未定义报错
  • 你已经将优惠券配置为仅对ID为74的商品生效、折扣比例100%,无需额外将商品价格设置为0,重复逻辑会导致WooCommerce折扣计算冲突
  • 调用add_discount添加优惠券后没有更新本地存储的已应用优惠券列表,会导致后续逻辑判断出错
  • 移除优惠券的分支逻辑写反:当前判断条件为「优惠券未应用」时执行移除操作,逻辑完全不成立

修复后的完整代码

function coupon_exists( $coupon_code ) {
    global $wpdb;
    $sql = $wpdb->prepare( "SELECT post_name FROM $wpdb->posts WHERE post_type = 'shop_coupon' AND post_name = '%s'", $coupon_code );
    $coupon_codes = $wpdb->get_results($sql);

    return count( $coupon_codes ) > 0;
}
// 生成优惠券
function generate_coupon($coupon_generated) {
    
    // 设置优惠券默认参数
    $date_expires     = date('Y-m-d H:i:s', strtotime('+24 hours'));
    $discount_type    = 'percent';
    $coupon_amount    = '100';

    $coupon = new WC_Coupon();
    $coupon->set_code($coupon_generated);
    $coupon->set_discount_type($discount_type);
    $coupon->set_amount($coupon_amount);
    $coupon->set_date_expires($date_expires);
    $coupon->set_individual_use(true);
    $coupon->set_product_ids (array(74)); 
    $coupon->set_usage_limit(1);    
    $coupon->set_limit_usage_to_x_items(1);
    $coupon->set_usage_limit_per_user(1);
    $coupon->set_exclude_sale_items(true);
    $coupon->set_minimum_amount('100');
    $coupon->set_maximum_amount('150');

    $coupon->save();

    return $coupon_generated;
}

// 添加优惠券和免费商品到购物车
function generate_coupon_add_product_to_cart ( $cart ) {
    
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;
    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;
    
    $coupon_code = ( isset( $_GET['coupon-code'] ) && $_GET['coupon-code'] != '' ) ? $_GET['coupon-code'] : '' ;

    if( $coupon_code == '' ){
        return;
    }

    $applied_coupons = $cart->get_applied_coupons();
    $free_product_id  = 74;
    $free_product_in_cart = false;
    $free_product_key = '';
    $regular_price = wc_get_product($free_product_id)->get_regular_price();
    $cart_count = $cart->get_cart_contents_count();

    if( empty( $applied_coupons ) || ! in_array( $coupon_code, $applied_coupons ) ){
        if ( !coupon_exists( $coupon_code ) ) {
            generate_coupon( $coupon_code );
        } 
    } 
    
    // 遍历购物车判断免费商品是否存在
    foreach( $cart->get_cart() as $cart_item_key => $cart_item ) {
        $product = $cart_item['data'];
        if ( $product->get_id() == $free_product_id ) {
            $free_product_key = $cart_item_key; 
            $free_product_in_cart = true;  
        } 
    }

    // 优惠券未应用且免费商品不在购物车:添加商品+应用优惠券
    if ( !in_array($coupon_code, $applied_coupons) && !$free_product_in_cart ){
        $cart->add_to_cart( $free_product_id, 1 );
        $cart->add_discount( $coupon_code );
        // 刷新已应用优惠券列表
        $applied_coupons = $cart->get_applied_coupons();
        wc_add_notice( sprintf(__('<strong>免费</strong> 商品已添加到您的购物车,价值 %s', 'woocommerce'),'<strong>' . get_woocommerce_currency_symbol() . $regular_price . '</strong>'), 'notice');
    }
    // 优惠券未应用但免费商品在购物车:移除免费商品
    elseif( !in_array($coupon_code, $applied_coupons) && $free_product_in_cart ){
        $cart->remove_cart_item( $free_product_key );
        wc_add_notice( __("优惠券已失效,免费商品已移除", 'woocommerce'), 'notice' );
    }
    // 购物车仅剩免费商品:移除商品和优惠券
    elseif ( $free_product_in_cart && $cart_count <= 1 ){
        $cart->remove_cart_item( $free_product_key );
        $cart->remove_coupon( $coupon_code );
        wc_add_notice( __("免费商品已移除", 'woocommerce'), 'notice' );
    }
}
add_action('woocommerce_before_calculate_totals', 'generate_coupon_add_product_to_cart');

优化说明

  • 提前初始化所有需要用到的变量,避免未定义报错
  • 移除了重复的商品价格设0逻辑,完全靠优惠券规则实现免费
  • 修正了优惠券移除、商品移除的逻辑分支,确保对应场景下操作正常执行
  • 添加优惠券后主动刷新已应用优惠券列表,避免逻辑判断误差

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 12:45:01