Woocommerce按用户角色设置折扣后多页面价格不一致问题求助
问题排查及修复方案
1. 「A non-numeric value encountered」报错原因及修复
- 核心原因1:传入的
$price参数在部分场景(后台初始化、商品未设置价格、钩子返回格式化字符串)下不是数值类型,直接做乘法运算触发类型错误 - 核心原因2:直接用
$product->ID获取产品ID的写法不兼容高版本WooCommerce,应该调用$product->get_id()方法获取,否则可能返回空值导致逻辑异常 - 修复方案:在函数最开头先把
$price强转为浮点型,替换ID获取方式
2. 价格不一致问题原因及修复
- 核心原因1:你使用的
woocommerce_get_price钩子已在WooCommerce 3.0+版本废弃,仅前端商品展示页的价格钩子生效,购物车、结账页的价格计算没有读取到折扣后的值 - 核心原因2:当前折扣逻辑的执行时机晚于税费计算,相当于先按原价算VAT再打折,和你预期的「先打折再算VAT」逻辑不符。你给出的异常数值刚好匹配该逻辑:原价10€ * 1.24VAT = 12.4€ * 0.9折扣 = 11.16€,和你实际显示的价格完全吻合
- 修复方案:新增购物车项目价格调整钩子,调整钩子优先级确保折扣在税费计算前执行,同时优化角色判断逻辑避免重复调用
修复后完整代码
替换你原主题functions.php里的相关代码即可:
// 商品页、归档页价格折扣钩子 add_filter('woocommerce_product_variation_get_price', 'custom_price', 10, 2); add_filter('woocommerce_product_get_price', 'custom_price', 10, 2); // 购物车项目价格折扣钩子,确保在税费计算前生效 add_action('woocommerce_before_calculate_totals', 'custom_cart_item_price', 10, 1); function custom_price($price, $product) { // 强转价格为浮点型,避免非数值报错 $price = (float) $price; if (!is_user_logged_in() || $price <= 0) return $price; $user = wp_get_current_user(); $user_roles = (array) $user->roles; $product_id = $product->get_id(); if (in_array('hintaluokka-5', $user_roles)) { $price *= 0.95; } elseif (in_array('hintaluokka-12', $user_roles)) { $price *= 0.88; } elseif (in_array('hintaluokka-15', $user_roles)) { $price *= 0.85; } elseif (in_array('hintaluokka-22', $user_roles)) { if (has_term('kastikkeet', 'product_cat', $product_id)) { $price *= 0.78; } else { $price *= 0.9; } } return $price; } function custom_cart_item_price($cart) { if (is_admin() && !defined('DOING_AJAX')) return; if (!is_user_logged_in()) return; $user = wp_get_current_user(); $user_roles = (array) $user->roles; foreach ($cart->get_cart() as $cart_item) { $product = $cart_item['data']; $original_price = (float) $product->get_regular_price(); $product_id = $product->get_id(); $discount_price = $original_price; if (in_array('hintaluokka-5', $user_roles)) { $discount_price *= 0.95; } elseif (in_array('hintaluokka-12', $user_roles)) { $discount_price *= 0.88; } elseif (in_array('hintaluokka-15', $user_roles)) { $discount_price *= 0.85; } elseif (in_array('hintaluokka-22', $user_roles)) { if (has_term('kastikkeet', 'product_cat', $product_id)) { $discount_price *= 0.78; } else { $discount_price *= 0.9; } } // 设置购物车商品价格为折扣后价格,税费将基于该价格计算 $cart_item['data']->set_price($discount_price); } }
替换后确认WooCommerce后台税费设置为「基于商品不含税价格计算」,即可实现预期的价格计算逻辑。
内容的提问来源于stack exchange,提问作者Samuli Välimäki
相关产品推荐
相关产品推荐

