如何在WordPress中实现商品前3件免费、超出部分按原价计费?
实现WooCommerce前3件Widget商品免费、超出部分按原价计费
环境说明
- WordPress 6.2
- WooCommerce 7.4
- Underscore Theme
需求背景
当客户选择特定套餐(ID为15或16)时,系统会自动添加3件Widget商品(ID:21、24、26、704)到购物车。目前已通过functions.php代码将这些Widget的价格设为0,但现在需要调整逻辑:前3件Widget免费,超出部分按原价(10美元)计费。例如添加5件时,购物车显示“Widgets(5)”,总价为20美元(超出的2件×10美元)。
修改后的代码
替换原有add_custom_price函数,将以下代码添加到主题的functions.php文件中:
add_action( 'woocommerce_before_calculate_totals', 'custom_widget_pricing', 10, 1 ); function custom_widget_pricing( $cart ) { // 后台非AJAX请求直接返回,避免冲突 if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return; // 防止重复触发计算逻辑 if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) return; $target_product_ids = array(21,24,26,704); // 目标Widget商品ID集合 $free_qty = 3; // 免费额度数量 $original_price = 10; // 商品原价(美元) $total_widget_qty = 0; // 第一步:统计购物车内所有目标Widget的总数量 foreach ( $cart->get_cart() as $cart_item ) { if ( in_array( $cart_item['product_id'], $target_product_ids ) ) { $total_widget_qty += $cart_item['quantity']; } } // 仅当用户选择了指定套餐时生效 if ( $package_chosen != 15 && $package_chosen != 16 ) return; // 第二步:根据总数量调整商品单价,实现前N件免费逻辑 foreach ( $cart->get_cart() as $cart_item ) { if ( in_array( $cart_item['product_id'], $target_product_ids ) ) { if ( $total_widget_qty <= $free_qty ) { // 总数量未超过免费额度,全部免费 $cart_item['data']->set_price( 0 ); } else { // 计算付费数量与总付费金额,用加权平均单价保证总价正确 $paid_qty = $total_widget_qty - $free_qty; $total_paid_amount = $paid_qty * $original_price; $adjusted_price = $total_paid_amount / $total_widget_qty; $cart_item['data']->set_price( $adjusted_price ); } } } }
代码逻辑说明
- 统计总数量:遍历购物车统计所有目标Widget的总件数,覆盖系统自动添加和客户手动添加的商品。
- 套餐校验:仅在用户选择ID为15或16的特定套餐时,触发该定价规则。
- 单价调整:
- 总数量≤3时,直接将单价设为0,全部商品免费。
- 总数量>3时,计算需付费的商品数量(总数量-3),通过加权平均单价的方式设置商品价格,既保证购物车显示总数量(如5件),也能让总价等于超出部分的费用(20美元)。
- 冲突防护:加入后台判断和重复触发限制,避免在WooCommerce后台操作时出现异常。
内容的提问来源于stack exchange,提问作者cx3700
相关产品推荐
相关产品推荐

