WooCommerce可变产品添加自定义价格字段并实现点击更新
解决WooCommerce可变产品自定义变体价格不更新问题
问题根源
现有代码存在以下关键问题:
- 保存字段的函数参数不匹配钩子要求,且未做安全校验,可能导致数据保存失败
- 初始价格显示逻辑错误,会输出所有变体的自定义价格而非默认的单个/范围价格
- 缺少前端JavaScript逻辑,无法监听变体选择事件并更新自定义价格
- 未将自定义价格注入到WooCommerce前端的变体数据集合中,导致JS无法获取到自定义价格值
完整修复代码
1. 添加变体自定义价格字段(优化原逻辑)
// Add custom price field for variations with description function custom_variation_price_field( $loop, $variation_data, $variation ) { $custom_price = get_post_meta( $variation->ID, '_custom_price', true ); ?> <p class="form-row form-row-full"> <label for="_custom_price[<?php echo esc_attr( $variation->ID ); ?>]"> <?php esc_html_e('自定义价格', 'woocommerce'); ?> (<?php echo get_woocommerce_currency_symbol(); ?>) </label> <input type="text" class="short wc_input_price" name="_custom_price[<?php echo esc_attr( $variation->ID ); ?>]" id="_custom_price[<?php echo esc_attr( $variation->ID ); ?>]" value="<?php echo esc_attr( wc_format_localized_price( $custom_price ) ); ?>" data_type="price" /> <span class="description"> <?php esc_html_e('输入该变体的自定义价格。', 'woocommerce'); ?> </span> </p> <?php } add_action('woocommerce_variation_options_pricing', 'custom_variation_price_field', 10, 3);
2. 修复自定义价格保存逻辑
// Save custom price field value function save_custom_variation_price_field( $variation_id, $i ) { // 检查POST数据是否存在,避免报错 if ( isset( $_POST['_custom_price'][ $variation_id ] ) ) { $custom_price = wc_clean( $_POST['_custom_price'][ $variation_id ] ); // 转换为标准价格格式(处理千分位、逗号等) $custom_price = wc_format_decimal( $custom_price ); update_post_meta( $variation_id, '_custom_price', $custom_price ); } } add_action('woocommerce_save_product_variation', 'save_custom_variation_price_field', 10, 2);
3. 将自定义价格注入前端变体数据
// Inject custom price into variation frontend data function add_custom_price_to_variation_data( $variation_data, $product, $variation ) { $custom_price = get_post_meta( $variation->get_id(), '_custom_price', true ); if ( ! empty( $custom_price ) ) { $variation_data['custom_price'] = wc_price( $custom_price ); // 同时传递原始数值,方便JS处理 $variation_data['custom_price_raw'] = (float) $custom_price; } else { // 如果未设置自定义价格, fallback到变体默认价格 $variation_data['custom_price'] = $variation->get_price_html(); $variation_data['custom_price_raw'] = (float) $variation->get_price(); } return $variation_data; } add_filter( 'woocommerce_available_variation', 'add_custom_price_to_variation_data', 10, 3 );
4. 修改初始价格显示逻辑(显示自定义价格范围)
// Display initial custom price for variable product function display_custom_variable_price( $price, $product ) { if ( $product->is_type('variable') ) { $custom_prices = array(); foreach ( $product->get_available_variations() as $variation ) { $custom_price = get_post_meta( $variation['variation_id'], '_custom_price', true ); if ( ! empty( $custom_price ) ) { $custom_prices[] = (float) $custom_price; } else { // 未设置自定义价格则用默认价格 $custom_prices[] = (float) $variation['display_price']; } } if ( ! empty( $custom_prices ) ) { $min_price = min( $custom_prices ); $max_price = max( $custom_prices ); // 统一显示价格范围,和WooCommerce默认逻辑一致 $price = wc_format_price_range( $min_price, $max_price ); } } return $price; } add_filter('woocommerce_variable_price_html', 'display_custom_variable_price', 10, 2);
5. 添加前端JS实现变体选择后更新价格
// Enqueue JS to update custom price on variation selection function enqueue_custom_variation_price_js() { global $product; if ( is_product() && $product->is_type('variable') ) { wc_enqueue_js( " jQuery(document).ready(function($) { // 监听变体选择完成事件 $('form.variations_form').on('show_variation', function(event, variation) { // 更新变体区域价格 if ( variation.custom_price ) { $('.woocommerce-variation-price .price').html( variation.custom_price ); // 更新产品主价格显示 $('.single-product .product_price .price').html( variation.custom_price ); } }); // 重置选择时恢复初始价格 $('form.variations_form').on('hide_variation', function() { var initialPrice = $('.woocommerce-variable-price .price').html(); $('.single-product .product_price .price').html( initialPrice ); }); }); " ); } } add_action( 'woocommerce_single_product_summary', 'enqueue_custom_variation_price_js', 20 );
代码说明
- 保存逻辑:修正钩子参数匹配问题,添加数据清洗和价格格式化,确保数据正确存储
- 前端数据注入:将自定义价格加入到WooCommerce的变体JSON数据中,让JS可以直接获取
- 初始价格:改为显示所有变体的自定义价格范围(未设置则用默认价格),符合WooCommerce默认交互逻辑
- JS逻辑:监听WooCommerce内置的变体选择/重置事件,动态更新页面上的价格显示
内容的提问来源于stack exchange,提问作者user22774038
相关产品推荐
相关产品推荐

