WooCommerce 5.5.2版本自定义产品价格无法更新问题求助
核心问题原因
- 价格更新逻辑的触发条件错误:
$_POST['invoice_id']仅在用户提交加购表单时存在,后续购物车刷新、进入结算页等场景无POST数据,判断条件不触发,价格会自动还原为产品默认价 - 自定义字段取值逻辑错误:你已经将
invoice_amount存入购物车项自定义数据中,不需要从POST取值,直接从购物车项提取即可 - 数值类型错误:
number_format()返回的是带格式的字符串,WooCommerce的set_price()方法要求传入浮点型数值,字符串会导致类型转换异常,价格设置失效 - 自定义产品类型注册不完整:仅定义了产品类,没有挂载到WooCommerce的产品类型注册钩子,也没有将该类型加入WooCommerce可识别的产品类型列表
- 购物车自定义数据存储逻辑隐患:你直接重置了
$cart_item_data为空白数组,会覆盖其他插件写入的购物车自定义数据
修复后的完整代码
1. 修复购物车自定义数据存储逻辑
function invoice_save_price( $cart_item_data, $product_id ) { if( isset( $_POST['invoice_id'], $_POST['invoice_number'], $_POST['invoice_amount'] ) ) { // 不要直接覆盖原有cart_item_data,避免丢失其他插件数据 $cart_item_data[ "invoice_number" ] = sanitize_text_field( $_POST['invoice_number'] ); // 提前转为浮点型存储 $cart_item_data[ "invoice_amount" ] = floatval( $_POST['invoice_amount'] ); // 加唯一标识避免相同产品被合并 $cart_item_data['_invoice_unique_key'] = md5( microtime() . rand() ); } return $cart_item_data; } add_filter( 'woocommerce_add_cart_item_data', 'invoice_save_price', 99, 2 );
2. 修复自定义产品类型注册逻辑
add_action( 'init', 'wcpt_register_invoice_type' ); function wcpt_register_invoice_type () { // 明确继承简单产品类 class WC_Product_Invoice extends WC_Product_Simple { public function __construct( $product ) { $this->product_type = 'invoice'; parent::__construct( $product ); } // 明确声明产品类型支持价格 public function supports( $feature ) { $supports = [ 'prices' ]; if ( in_array( $feature, $supports ) ) { return true; } return parent::supports( $feature ); } } } // 将自定义产品类型加入WooCommerce可识别列表 add_filter( 'woocommerce_product_class', 'wcpt_register_invoice_product_class', 10, 2 ); function wcpt_register_invoice_product_class( $classname, $product_type ) { if ( $product_type === 'invoice' ) { $classname = 'WC_Product_Invoice'; } return $classname; } // 后台产品类型下拉选项新增发票产品 add_filter( 'product_type_selector', 'wcpt_add_invoice_product_type' ); function wcpt_add_invoice_product_type( $types ) { $types[ 'invoice' ] = '发票产品'; return $types; }
3. 修复价格更新逻辑
add_action( 'woocommerce_before_calculate_totals', 'invoice_add_custom_price', 99 ); function invoice_add_custom_price($cart_object) { // 避免后台非AJAX场景触发计算 if ( is_admin() && ! defined( 'DOING_AJAX' ) ) { return; } foreach ( $cart_object->get_cart() as $cart_item ) { // 仅针对发票产品且存在自定义金额的购物车项修改价格 if ( $cart_item['data']->get_type() === 'invoice' && isset( $cart_item['invoice_amount'] ) ) { $cart_item['data']->set_price( floatval( $cart_item['invoice_amount'] ) ); } } }
补充说明
原设置的1美元默认价格可以保留,不会影响自定义价格的覆盖逻辑。如果需要在购物车、结算页显示发票编号,可通过woocommerce_get_item_data钩子输出购物车项的invoice_number字段。
内容的提问来源于stack exchange,提问作者Ryan Holm
相关产品推荐
相关产品推荐

