WooCommerce购物车页面交叉销售商品10%折扣实现问题
解决WooCommerce购物车交叉销售商品10%折扣失效问题
原代码核心问题
- 钩子选择错误:
woocommerce_cart_calculate_fees用于添加全局费用/折扣,不会修改商品本身的显示价格——折扣只会体现在订单总价的“费用”栏,而非单个商品行,这就是你看不到商品价格变化的原因。 - 逻辑不符合需求:原代码只要购物车存在指定商品就给全单折扣,而非仅针对交叉销售商品,也未关联“交叉商品与主商品相关”的触发条件。
- 冗余JS操作:强制提交购物车表单可能引发重复计算或页面异常,完全没必要。
修正后的解决方案
以下代码实现:当购物车中存在主商品时,对指定的交叉销售商品单独应用10%折扣,折扣会直接显示在商品行价格上,完全匹配你的需求设计。
add_action( 'woocommerce_before_calculate_totals', 'apply_cross_sell_product_discount', 10, 1 ); function apply_cross_sell_product_discount( $cart ) { // 避免钩子重复触发导致价格异常 if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) { return; } // 配置参数:替换为你的实际商品ID $main_product_ids = array( 123, 456 ); // 触发折扣的主商品ID $cross_sell_product_ids = array( 10, 20, 30 ); // 需要打折的交叉销售商品ID $discount_percent = 10; // 折扣比例 // 检查购物车是否存在主商品 $has_main_product = false; foreach ( $cart->get_cart() as $cart_item ) { if ( in_array( $cart_item['product_id'], $main_product_ids ) ) { $has_main_product = true; break; } } // 存在主商品时,给交叉销售商品单独打折扣 if ( $has_main_product ) { foreach ( $cart->get_cart() as $cart_item ) { $product = $cart_item['data']; if ( in_array( $product->get_id(), $cross_sell_product_ids ) ) { $original_price = $product->get_regular_price(); $discounted_price = $original_price * ( 1 - ( $discount_percent / 100 ) ); $product->set_price( $discounted_price ); } } } }
代码说明
- 正确钩子选择:使用
woocommerce_before_calculate_totals,这是修改购物车商品价格的标准钩子,能直接更新商品的显示价格。 - 逻辑匹配需求:先判断主商品是否存在,再对交叉销售商品单独打折,完全符合“交叉商品与主商品关联”的设计逻辑。
- 防重复计算:添加
did_action判断,避免钩子被多次触发导致价格循环修改。 - 直观折扣展示:直接修改商品的价格属性,折扣会清晰显示在购物车的商品行中,而非隐藏在总价折扣里。
可选简化版本
如果你的需求是只要交叉销售商品在购物车就打折(无需关联主商品),可以移除主商品判断部分,简化代码:
add_action( 'woocommerce_before_calculate_totals', 'apply_cross_sell_product_discount', 10, 1 ); function apply_cross_sell_product_discount( $cart ) { if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) { return; } $cross_sell_product_ids = array( 10, 20, 30 ); $discount_percent = 10; foreach ( $cart->get_cart() as $cart_item ) { $product = $cart_item['data']; if ( in_array( $product->get_id(), $cross_sell_product_ids ) ) { $original_price = $product->get_regular_price(); $discounted_price = $original_price * ( 1 - ( $discount_percent / 100 ) ); $product->set_price( $discounted_price ); } } }
内容的提问来源于stack exchange,提问作者Robert Sietsma
相关产品推荐
相关产品推荐

