WooCommerce条件化修改特定商品在单品页及购物车的价格
解决WooCommerce特定商品价格修改的两个问题
你遇到的两个核心问题:单品页代码触发500服务器错误,购物车价格显示异常(预期55美元却显示75美元),我来逐个帮你排查修复。
一、单品页500错误的原因及修复
你的单品页代码有3个明显问题:
- WooCommerce 3.0+已弃用
woocommerce_get_price钩子,继续使用会引发兼容错误; is_single('87')的判断逻辑不准确,无法覆盖商品的所有展示场景;- 未处理非目标商品的价格返回,会干扰其他商品的价格输出。
修正后的单品页代码(仅修改前端显示,不改动后台设置):
function wc_change_single_product_price($price, $product) { // 仅针对ID为87的商品 if ( $product->get_id() == 87 ) { $regular_price = (float)$product->get_regular_price(); $price = $regular_price + 10; } // 其他商品返回原价格 return $price; } // 用新版钩子确保兼容,优先级99保证覆盖默认值 add_filter('woocommerce_product_get_price', 'wc_change_single_product_price', 99, 2); add_filter('woocommerce_product_get_regular_price', 'wc_change_single_product_price', 99, 2);
二、购物车价格异常的原因及修复
你的购物车代码逻辑存在3个漏洞:
- 循环外直接调用
$cart_item变量,导致变量未定义; - 未添加价格重置逻辑,钩子多次触发时会重复加价(45+10+10+10=75,这就是你看到异常价格的原因);
- 商品分类检查用了已过时的
$product->id,且未遍历购物车项定位目标商品。
修正后的购物车代码:
function wc_cart_custom_price( $cart ) { if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return; // 防止钩子重复触发导致多次加价 if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) return; $cat_check = false; $target_category_slug = 'your-category'; // 替换成你的目标分类别名 $target_product_id = 87; // 先检查购物车是否包含目标分类商品 foreach ( $cart->get_cart() as $cart_item ) { if ( has_term( $target_category_slug, 'product_cat', $cart_item['product_id'] ) ) { $cat_check = true; break; } } // 遍历购物车,调整目标商品价格 foreach ( $cart->get_cart() as $cart_item ) { $product = $cart_item['data']; // 每次计算前先恢复原始价格,避免重复累加 $original_price = (float)$product->get_regular_price(); $product->set_price( $original_price ); // 无目标分类商品时,给目标商品加价10美元 if ( !$cat_check && $cart_item['product_id'] == $target_product_id ) { $product->set_price( $original_price + 10 ); } } } add_action( 'woocommerce_before_calculate_totals', 'wc_cart_custom_price', 99 );
关键修复点说明
- 增加
did_action判断,避免钩子重复触发导致价格重复累加; - 每次计算前强制重置商品为原始价格,确保价格逻辑准确;
- 拆分分类检查与价格修改的循环,让逻辑更清晰,避免变量未定义问题;
- 使用
$cart_item['product_id']检查分类,确保判断的是原始商品的分类属性。
最终完整可用代码
将以下代码添加到主题的functions.php文件,或通过自定义代码插件导入即可:
// 单品页修改目标商品显示价格(不改动后台设置) function wc_change_single_product_price($price, $product) { if ( $product->get_id() == 87 ) { $regular_price = (float)$product->get_regular_price(); $price = $regular_price + 10; } return $price; } add_filter('woocommerce_product_get_price', 'wc_change_single_product_price', 99, 2); add_filter('woocommerce_product_get_regular_price', 'wc_change_single_product_price', 99, 2); // 购物车中根据分类商品存在情况调整目标商品价格 function wc_cart_custom_price( $cart ) { if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return; if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) return; $cat_check = false; $target_category_slug = 'your-category'; // 替换为你的目标分类别名 $target_product_id = 87; foreach ( $cart->get_cart() as $cart_item ) { if ( has_term( $target_category_slug, 'product_cat', $cart_item['product_id'] ) ) { $cat_check = true; break; } } foreach ( $cart->get_cart() as $cart_item ) { $product = $cart_item['data']; $original_price = (float)$product->get_regular_price(); $product->set_price( $original_price ); if ( !$cat_check && $cart_item['product_id'] == $target_product_id ) { $product->set_price( $original_price + 10 ); } } } add_action( 'woocommerce_before_calculate_totals', 'wc_cart_custom_price', 99 );
记得把代码中的your-category替换为你实际的目标商品分类别名!
内容的提问来源于stack exchange,提问作者Thorned Rose
相关产品推荐
相关产品推荐

