WooCommerce更新后自定义产品无法添加购物车:is_purchasable返回false问题
解决WooCommerce更新后自定义产品add_to_cart报错“该产品无法购买”的问题
刚看到你碰到的这个问题——WooCommerce更新后,调用add_to_cart函数时触发“抱歉,该产品无法购买”的错误,根源是$product_data->is_purchasable()返回false,且问题出在get_price()函数上。结合新版本WooCommerce的特性,我给你梳理几个可行的解决思路:
先搞懂新版本的验证逻辑
WooCommerce最近的版本对产品可购买性的验证更严格了,is_purchasable()的判断不再只看产品是否发布、是否在库存,还会依赖get_price()返回的数值有效性:如果get_price()返回空字符串、非数值,或者不符合价格格式(比如负数,除非你特意设置免费产品),都会直接导致产品被判定为不可购买。
具体解决方案
1. 检查自定义产品的get_price()实现
如果你是自定义了产品类型,首先要确保你的产品类正确重写了get_price()方法,并且返回有效的数值:
- 避免返回空值,哪怕是免费产品,也要返回
'0'或者0(注意用wc_format_decimal处理格式) - 确保价格是合法的数值,比如从自定义字段获取后,要做数值验证和格式化
举个自定义产品类的示例:
class WC_Product_Custom extends WC_Product { public function __construct( $product ) { $this->product_type = 'custom'; parent::__construct( $product ); } // 重写get_price,确保返回有效价格 public function get_price( $context = 'view' ) { // 从自定义字段获取价格,可替换为你的业务逻辑 $custom_price = get_post_meta( $this->get_id(), '_custom_product_price', true ); // 处理空值或非数值情况,默认返回0 if ( empty( $custom_price ) || !is_numeric( $custom_price ) ) { return wc_format_decimal( 0 ); } // 格式化价格为WooCommerce认可的格式 return wc_format_decimal( $custom_price ); } // 按需重写is_purchasable,添加自定义判断 public function is_purchasable() { // 结合产品库存和价格有效性判断 $price = $this->get_price(); return $this->is_in_stock() && !empty( $price ) && is_numeric( $price ); } }
2. 使用钩子临时调整可购买性(不修改产品类时用)
如果不想修改自定义产品类的代码,可以通过woocommerce_is_purchasable钩子来强制调整特定产品的可购买状态:
add_filter( 'woocommerce_is_purchasable', 'fix_custom_product_purchasable', 10, 2 ); function fix_custom_product_purchasable( $purchasable, $product ) { // 只针对你的自定义产品类型生效 if ( 'custom' === $product->get_type() ) { // 手动验证价格有效性,符合条件就设为可购买 $price = $product->get_price(); $purchasable = !empty( $price ) && is_numeric( $price ) && $product->is_in_stock(); } return $purchasable; }
3. 调试get_price()的返回值
建议在调用add_to_cart前,先打印$product_data->get_price()的返回值,排查异常内容:
// 调试代码,放在add_to_cart执行前 var_dump( $product_data->get_price() ); die();
如果返回的是''、null或者非数值字符串(比如'abc'),那就是问题核心,针对性修复价格获取逻辑即可。
为什么更新后才出现问题?
WooCommerce新版本优化了产品数据的一致性验证,之前的版本可能对get_price()的异常返回容忍度更高,但现在会严格检查价格的有效性,确保只有符合条件的产品才能被加入购物车。
内容的提问来源于stack exchange,提问作者HOY
相关产品推荐
相关产品推荐

