WooCommerce按购物车金额赠礼功能故障求助
WooCommerce 购物车满额赠礼功能修复方案
原代码核心问题分析
- 礼品ID未正确赋值:使用未定义变量而非实际产品ID
- 赠礼识别逻辑错误:通过不存在的数组键名判断礼品,而非产品ID
- 价格设置对象错误:未指向购物车项的产品数据对象
- 无赠礼身份标记:每次刷新购物车重复添加礼品,导致数量递增
- 满额逻辑错误:金额超过120时错误移除礼品1
- 小计计算偏差:未排除赠礼金额,导致满额判断不准确
修复后的完整代码
function custom_add_free_gifts_based_on_cart_total( $cart ) { if ( is_admin() && ! defined( 'DOING_AJAX' ) ) { return; } if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) { return; } // 配置区:替换为实际的礼品ID和满额阈值 $free_product_ids = [ 'gift1' => 6215, // 礼品1的产品ID 'gift2' => 7912 // 礼品2的产品ID ]; $thresholds = [ 'min_gift1' => 80, 'min_both_gifts' => 120 ]; // 初始化变量 $cart_subtotal = 0; $existing_gifts = [ 'gift1' => false, 'gift2' => false ]; $gift_keys = [ 'gift1' => '', 'gift2' => '' ]; // 遍历购物车,计算有效小计并识别赠礼 foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) { $product_id = $cart_item['product_id']; $is_free_gift = isset( $cart_item['is_free_gift'] ) && $cart_item['is_free_gift']; // 标记赠礼并强制价格为0 if ( $product_id === $free_product_ids['gift1'] && $is_free_gift ) { $existing_gifts['gift1'] = true; $gift_keys['gift1'] = $cart_item_key; $cart_item['data']->set_price( 0 ); $cart_item['line_total'] = 0; $cart_item['line_tax'] = 0; } elseif ( $product_id === $free_product_ids['gift2'] && $is_free_gift ) { $existing_gifts['gift2'] = true; $gift_keys['gift2'] = $cart_item_key; $cart_item['data']->set_price( 0 ); $cart_item['line_total'] = 0; $cart_item['line_tax'] = 0; } else { // 仅累加非赠礼的金额到有效小计 $cart_subtotal += $cart_item['line_total'] + $cart_item['line_tax']; } } // 执行赠礼逻辑 // 1. 金额低于80:移除所有赠礼 if ( $cart_subtotal < $thresholds['min_gift1'] ) { $existing_gifts['gift1'] && $cart->remove_cart_item( $gift_keys['gift1'] ); $existing_gifts['gift2'] && $cart->remove_cart_item( $gift_keys['gift2'] ); } // 2. 金额80-120:保留礼品1,移除礼品2 elseif ( $cart_subtotal >= $thresholds['min_gift1'] && $cart_subtotal < $thresholds['min_both_gifts'] ) { !$existing_gifts['gift1'] && $cart->add_to_cart( $free_product_ids['gift1'], 1, 0, [], [ 'is_free_gift' => true ] ); $existing_gifts['gift2'] && $cart->remove_cart_item( $gift_keys['gift2'] ); $existing_gifts['gift1'] && $cart->set_quantity( $gift_keys['gift1'], 1 ); } // 3. 金额≥120:保留礼品1和礼品2 elseif ( $cart_subtotal >= $thresholds['min_both_gifts'] ) { !$existing_gifts['gift1'] && $cart->add_to_cart( $free_product_ids['gift1'], 1, 0, [], [ 'is_free_gift' => true ] ); !$existing_gifts['gift2'] && $cart->add_to_cart( $free_product_ids['gift2'], 1, 0, [], [ 'is_free_gift' => true ] ); $existing_gifts['gift1'] && $cart->set_quantity( $gift_keys['gift1'], 1 ); $existing_gifts['gift2'] && $cart->set_quantity( $gift_keys['gift2'], 1 ); } } add_action( 'woocommerce_before_calculate_totals', 'custom_add_free_gifts_based_on_cart_total', 10, 1 );
关键修复说明
- 赠礼身份标记:添加礼品时传入
'is_free_gift' => true元数据,准确区分系统赠礼和用户自行添加的产品,避免重复添加 - 强制价格为0:同时设置产品价格、行总计、行税费为0,确保购物车页面显示的subtotal为0
- 有效小计计算:仅累加非赠礼的金额,避免赠礼干扰满额判断逻辑
- 数量控制:在对应逻辑分支中强制礼品数量为1,防止刷新时数量递增
- 修复满额逻辑:修正原代码中超过120时移除礼品1的错误,改为同时保留两款礼品
内容的提问来源于stack exchange,提问作者Giam
相关产品推荐
相关产品推荐

