Woocommerce购物车总价修改后结账时恢复问题求助
Woocommerce购物车总价修改后结账页失效的解决方案
问题描述
我编写了代码,想要遍历Woocommerce购物车,筛选出分类为“pizza”的商品中价格最高的单品,将其价格从购物车总价中扣除以更新总价。但进入结账页面后,订单总价会恢复为修改前的数值,不确定是否只是计算了价格而未真正设置,请问如何才能真正将修改后的价格设置为订单价格?
原代码
add_filter( 'woocommerce_cart_total', 'wc_modify_cart_price' ); add_filter( 'woocommerce_order_amount_total', 'wc_modify_cart_price' ); function wc_modify_cart_price( $price ) { $cart_ct = WC()->cart->get_cart_contents_count(); $tax = WC()->cart->get_taxes(); if($cart_ct > 1 ){ $product_prices = []; $fee = 0; $prices = array(); // Loop Through cart items - Collect product prices foreach ( WC()->cart->get_cart() as $cart_item ) { $_product = wc_get_product( $cart_item['product_id'] ); $terms = get_the_terms( $cart_item['product_id'], 'product_cat' ); #var_dump($terms[0]->name); if($terms[0]->name == "pizza"){ $prices[] = $cart_item['data']->get_price(); } } $sort_price = max($prices); $max_price = $sort_price; $cart_total = WC()->cart->cart_contents_total; $addition = $cart_total - $max_price; WC()->cart->total = $addition; $addition = $cart_total - $max_price + $tax[2]; }else{ echo $tax; $addition = WC()->cart->cart_contents_total + $tax[2]; } return $addition; } add_filter( 'woocommerce_calculated_total', 'wc_modify_cart_price', 10, 2 );
原代码问题分析
- 钩子使用不当:
woocommerce_cart_total仅负责前端显示总价,不会影响实际计算的订单金额;直接修改WC()->cart->total会被Woocommerce后续的重新计算覆盖,无法真正生效。 - 分类判断逻辑缺陷:只取商品的第一个分类
$terms[0],若商品属于多个分类,可能错过“pizza”分类的判断。 - 税收处理不严谨:硬编码
$tax[2]获取税额,税收索引可能随配置变化,导致税额计算错误。 - 无错误防护:当购物车没有“pizza”商品时,调用
max($prices)会触发PHP错误。
修复后的代码
add_filter( 'woocommerce_calculated_total', 'wc_modify_cart_price', 10, 2 ); function wc_modify_cart_price( $total, $cart ) { // 获取购物车商品总数 $cart_count = $cart->get_cart_contents_count(); // 仅当商品数大于1时执行优惠逻辑 if ( $cart_count > 1 ) { $pizza_prices = []; // 遍历购物车所有商品 foreach ( $cart->get_cart() as $cart_item ) { $product_id = $cart_item['product_id']; $terms = get_the_terms( $product_id, 'product_cat' ); // 确保分类获取成功,无错误 if ( $terms && ! is_wp_error( $terms ) ) { // 检查商品是否属于pizza分类(忽略大小写) foreach ( $terms as $term ) { if ( strtolower( $term->name ) === 'pizza' ) { // 获取商品当前生效的单价(支持促销价、会员价等) $product_price = $cart_item['data']->get_price(); $pizza_prices[] = $product_price; break; // 找到目标分类后跳出循环,避免重复添加 } } } } // 如果存在pizza商品,扣除最高单价 if ( ! empty( $pizza_prices ) ) { $max_pizza_price = max( $pizza_prices ); $total -= $max_pizza_price; // 确保总价不会出现负数 $total = max( $total, 0 ); } } return $total; }
关键修复点说明
- 使用正确的钩子:
woocommerce_calculated_total是Woocommerce计算总价的核心钩子,返回值会直接作为购物车、结账页及最终订单的实际金额,彻底解决结账页总价恢复的问题。 - 优化分类判断:遍历商品所有分类,同时用
strtolower避免大小写匹配问题,确保不会漏判。 - 错误防护:添加
$terms有效性检查,以及$pizza_prices非空判断,避免PHP警告和错误。 - 税收自动处理:
$total参数已包含税额,直接调整该值即可,无需手动计算税额,适配不同的税收配置。 - 避免直接修改购物车对象:通过钩子返回值修改总价,符合Woocommerce的钩子机制,不会被后续计算覆盖。
内容的提问来源于stack exchange,提问作者isaac gomez
相关产品推荐
相关产品推荐

