Woocommerce结账页自定义日期字段变更时重算订单小计
WooCommerce结账页自定义日期字段触发小计重计算解决方案
核心问题分析
你当前的问题是:自定义日期字段的值未被传递到AJAX结账更新请求中,导致$_POST['date1']无法读取;同时需要根据两个日期字段的选择状态动态调整订单小计。
步骤1:确保自定义日期字段被包含到AJAX请求
WooCommerce结账页的AJAX更新默认不会自动携带自定义字段,需要通过JS将字段数据追加到请求参数:
jQuery(document).ready(function($) { // 监听两个日期字段的变化事件 $('input[name="date1"], input[name="date2"]').on('change', function() { $(document.body).trigger('update_checkout'); }); // 把自定义字段值追加到结账AJAX请求里 $(document.body).on('update_checkout', function() { $.ajaxSetup({ data: { 'date1': $('input[name="date1"]').val(), 'date2': $('input[name="date2"]').val() } }); }); });
步骤2:完善自定义日期字段添加代码
修正字段添加函数,加入第二个日期字段,并确保get_value参数与字段name一致:
function my_custom_checkout_field( $checkout ) { echo '<div id="my_custom_checkout_field"><h3>'.__('自定义日期选项').'</h3>'; // 第一个日期字段 woocommerce_form_field( 'date1', array( 'type' => 'date', 'class' => array('my-field-class form-row-wide'), 'label' => __('选择日期1'), 'required' => true, 'placeholder' => __('输入日期'), ), $checkout->get_value( 'date1' )); // 第二个日期字段 woocommerce_form_field( 'date2', array( 'type' => 'date', 'class' => array('my-field-class form-row-wide'), 'label' => __('选择日期2'), 'required' => false, 'placeholder' => __('输入日期'), ), $checkout->get_value( 'date2' )); echo '</div>'; } add_action('woocommerce_after_order_notes','my_custom_checkout_field');
步骤3:正确获取字段值并动态调整小计
用WC()->session存储字段值(避免AJAX请求中$_POST的生命周期问题),再在价格计算钩子中根据字段状态调整小计:
// 把日期字段值存储到Session function save_custom_checkout_fields_to_session() { if ( isset( $_POST['date1'] ) ) { WC()->session->set( 'date1', sanitize_text_field( $_POST['date1'] ) ); } if ( isset( $_POST['date2'] ) ) { WC()->session->set( 'date2', sanitize_text_field( $_POST['date2'] ) ); } } add_action( 'woocommerce_checkout_update_order_review', 'save_custom_checkout_fields_to_session' ); // 动态计算订单小计 function add_custom_price( $cart ) { if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return; if ( ! is_checkout() ) return; // 防止重复触发计算 if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) return; $date1 = WC()->session->get( 'date1' ); $date2 = WC()->session->get( 'date2' ); // 按需求设置价格系数:默认1,选date1加1(10€→20€),选date2再加1(20€→30€) $price_multiplier = 1; if ( ! empty( $date1 ) ) $price_multiplier += 1; if ( ! empty( $date2 ) ) $price_multiplier += 1; foreach ( $cart->get_cart() as $cart_item ) { // 取商品原始价格,避免多次更新时价格重复叠加 $original_price = $cart_item['data']->get_regular_price(); $new_price = $original_price * $price_multiplier; $cart_item['data']->set_price( $new_price ); } } add_action( 'woocommerce_before_calculate_totals', 'add_custom_price', 10, 1 );
关键注意事项
- 用
woocommerce_checkout_update_order_review钩子存储字段值到Session,确保AJAX请求中能稳定获取数据 - 计算价格时调用
get_regular_price()获取原始价格,避免多次触发更新导致价格无限叠加 - JS部分要确保字段变更时触发结账更新,并将字段值传递到AJAX请求
内容的提问来源于stack exchange,提问作者Γαβρογιάννης Βασίλης
相关产品推荐
相关产品推荐

