
本教程详细指导如何在woocommerce结账页面集成xdsoft datetimepicker,并根据用户选择的配送日期(当天或次日)动态添加附加费用。文章涵盖了自定义日期字段的创建、前端日期选择器的配置、后端条件费用计算逻辑、结账页面动态更新,以及将配送日期保存并显示在订单详情和邮件中的完整实现步骤,旨在提升店铺配送的灵活性和自动化管理能力。
在WooCommerce商店中,为特定配送日期(例如当日或次日达)提供附加费用是一种常见的业务需求。这不仅能为客户提供更灵活的配送选项,也能为商家带来额外的收入。本教程将引导您完成在WooCommerce结账页面添加一个自定义配送日期选择器,并根据用户选择的日期动态计算并应用附加费用的整个过程。
1. 添加自定义配送日期字段
首先,我们需要在WooCommerce结账页面添加一个用于选择配送日期的文本输入框。这个输入框将作为日期选择器的载体。
function custom_delivery_date_field( $checkout ) {    woocommerce_form_field( 'delivery_date', array(        'type'          => 'text',        'class'         => array('form-row-wide'),        'id'            => 'datepicker',        'required'      => true,        'label'         => __('Select Delivery Date', 'your-text-domain'),        'placeholder'   => __('Click to select date', 'your-text-domain'),    ));}add_action( 'woocommerce_after_order_notes', 'custom_delivery_date_field' );登录后复制这段代码通过 woocommerce_after_order_notes 钩子在订单备注下方添加了一个名为 delivery_date 的文本字段。id 设置为 datepicker,这将是前端Javascript初始化日期选择器的目标元素。
2. 集成并配置xdsoft DateTimePicker
为了提供友好的日期选择体验,我们将集成xdsoft DateTimePicker。此步骤包括加载必要的CSS和Javascript库,并初始化日期选择器。
function load_and_init_datetimepicker( $available_gateways ) {   ?>    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.min.css"/ >    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.full.min.js"></script>        <script type="text/javascript">        jQuery(document).ready(function($) {            jQuery.datetimepicker.setLocale('en'); // 设置语言环境            var currentDate = new Date();            var minutes = currentDate.getMinutes();            // 将当前分钟数向上取整到最近的30分钟,例如15->30, 40->60 (变为下一小时的00)            var m = (Math.ceil(minutes / 30) * 30) % 60;            currentDate.setMinutes(m);                      jQuery('#datepicker').datetimepicker({                // beforeShowDay: $.datepicker.noWeekends, // 如果需要禁用周末,请取消注释此行                format: 'Y/m/d H:i:s', // 日期时间格式                minDate: 0,             // 最小可选日期为今天                minTime: '8:00',        // 最小可选时间                step: 30,               // 时间步长为30分钟                allowTimes:[            // 允许选择的时间段                    '09:00', '09:30', '10:00', '10:30', '11:00', '11:30', '12:00', '12:30',                     '13:00', '13:30', '14:00', '14:30', '15:00', '15:30', '16:00', '16:30', '17:00'                ],                onSelectDate:function(ct,$i){                    // 每次选择日期后触发结账页面更新,以便重新计算费用                    $( 'body' ).trigger( 'update_checkout' );                },                onSelectTime:function(ct,$i){                    // 每次选择时间后触发结账页面更新,以便重新计算费用                    $( 'body' ).trigger( 'update_checkout' );                }                         });        });    </script>   <?php }add_action( 'woocommerce_after_checkout_form', 'load_and_init_datetimepicker', 20 );登录后复制这段代码通过 woocommerce_after_checkout_form 钩子在结账表单加载后执行。它会加载xdsoft DateTimePicker的CSS和JS文件,并初始化 #datepicker 元素。
format: 定义日期时间的显示和提交格式。minDate: 0 表示最小可选日期为今天。minTime: 设置每天最早的可选时间。step: 设置时间选择的步长(例如30分钟)。allowTimes: 限制用户只能选择特定时间段。onSelectDate 和 onSelectTime: 这两个回调函数在用户选择日期或时间后触发 update_checkout 事件。这个事件会通知WooCommerce重新计算购物车和费用,确保附加费用能够动态更新。3. 验证配送日期选择
在用户提交订单之前,确保配送日期字段已被填写是必要的。
 集简云
                                                    集简云                            软件集成平台,快速建立企业自动化与智能化
 22                                                                                                        查看详情
22                                                                                                        查看详情                             
                                    function validate_delivery_date_field() {           if ( isset( $_POST['delivery_date'] ) && empty( $_POST['delivery_date'] ) ) {        wc_add_notice( __( 'Please select the Delivery Date', 'your-text-domain' ), 'error' );     }}add_action( 'woocommerce_checkout_process', 'validate_delivery_date_field' );登录后复制woocommerce_checkout_process 钩子在结账表单处理时触发。如果 delivery_date 字段为空,则会显示一个错误通知,阻止订单提交。
4. 基于配送日期动态计算附加费用
这是实现核心逻辑的部分,我们将根据用户选择的配送日期来判断是否添加附加费用。
function wc_add_delivery_surcharge() {     // 仅在非后台页面且非AJAX请求时执行,防止不必要的计算    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {        return;    }    // 解析POST数据,因为在AJAX请求中,数据可能在$_POST['post_data']中    $post_data = array();    if ( isset( $_POST['post_data'] ) ) {        parse_str($_POST['post_data'], $post_data);    } else {        $post_data = $_POST;    }    // 检查配送日期是否已设置    if ( isset( $post_data['delivery_date'] ) && ! empty( $post_data['delivery_date'] ) ) {        $selected_date_str = sanitize_text_field( $post_data['delivery_date'] );        // 获取当前日期(不包含时间部分,以便进行天数比较)        $current_date_obj = new DateTime(date("Y-m-d"));        // 获取用户选择的日期(不包含时间部分)        $selected_date_obj = new DateTime(date("Y-m-d", strtotime($selected_date_str)));        // 计算日期差异        $interval = $current_date_obj->diff($selected_date_obj);        $difference_days = (int)$interval->format('%R%a'); // 获取带符号的天数差异        // 定义附加费用金额        $fee_amount = 5.00; // 例如,5.00元作为快速配送费        // 如果选择的日期是今天(0天差异)或明天(1天差异),则添加费用        if ( $difference_days == 0 || $difference_days == 1 ) {            // 添加费用,名称为“快速配送费”,金额为$fee_amount,可征税,税率等级为“standard”            WC()->cart->add_fee( __( 'Fast delivery charge', 'your-text-domain' ), $fee_amount, true, 'standard' );          } else {            // 如果选择的是其他日期,确保移除可能存在的“快速配送费”            // 注意:woocommerce_cart_calculate_fees 每次都会重新计算,            // 如果不满足条件,WC()->cart->add_fee() 将不会被调用,            // 但为确保万无一失,可以显式移除。            $fees = WC()->cart->get_fees();            foreach ( $fees as $key => $fee ) {                if ( $fee->name === __( "Fast delivery charge", 'your-text-domain' ) ) {                    unset( $fees[$key] );                }            }            // 重新设置购物车费用(如果有费用被移除)            if ( ! empty( $fees ) ) {                 WC()->cart->fees_api()->set_fees($fees);            } else {                // 如果所有费用都被移除,则清空费用数组                WC()->cart->fees_api()->set_fees(array());            }        }     } else {        // 如果delivery_date未设置或为空,确保移除可能存在的快速配送费        $fees = WC()->cart->get_fees();        foreach ( $fees as $key => $fee ) {            if ( $fee->name === __( "Fast delivery charge", 'your-text-domain' ) ) {                unset( $fees[$key] );            }        }        if ( ! empty( $fees ) ) {             WC()->cart->fees_api()->set_fees($fees);        } else {            WC()->cart->fees_api()->set_fees(array());        }    }}add_action( 'woocommerce_cart_calculate_fees','wc_add_delivery_surcharge' );登录后复制这段代码通过 woocommerce_cart_calculate_fees 钩子实现费用计算。
它首先解析 $_POST 数据以获取 delivery_date。然后,它将当前日期和选择的配送日期转换为 DateTime 对象,并计算它们之间的天数差异。如果差异为0(今天)或1(明天),则使用 WC()-youjiankuohaophpcncart->add_fee() 添加一个名为“快速配送费”的附加费用。如果选择的是其他日期,或者 delivery_date 未设置,它会遍历购物车中的所有费用,并移除名为“快速配送费”的费用,以确保费用只在满足条件时才显示。5. 保存并显示配送日期信息
为了在订单管理和客户邮件中查看配送日期,我们需要将选择的日期保存到订单元数据中,并在相应位置显示。
function save_delivery_date_field( $order_id ) {     if ( isset( $_POST['delivery_date'] ) && ! empty( $_POST['delivery_date'] ) ) {        update_post_meta( $order_id, 'delivery_date', sanitize_text_field( $_POST['delivery_date'] ) );    }}  add_action( 'woocommerce_checkout_update_order_meta', 'save_delivery_date_field' );function show_delivery_date_field_order( $order ) {       $delivery_date = get_post_meta( $order->get_id(), 'delivery_date', true );   if ( $delivery_date ) {       echo '<p><strong>' . __( 'Delivery Date', 'your-text-domain' ) . ':</strong> ' . esc_html( $delivery_date ) . '</p>';   }}add_action( 'woocommerce_admin_order_data_after_billing_address', 'show_delivery_date_field_order', 10, 1 );function show_delivery_date_field_emails( $order, $sent_to_admin, $plain_text, $email ) {    $delivery_date = get_post_meta( $order->get_id(), 'delivery_date', true );    if ( $delivery_date ) {        echo '<p><strong>' . __( 'Delivery Date', 'your-text-domain' ) . ':</strong> ' . esc_html( $delivery_date ) . '</p>';    }}add_action( 'woocommerce_email_after_order_table', 'show_delivery_date_field_emails', 20, 4 );登录后复制woocommerce_checkout_update_order_meta: 在订单创建后,将 delivery_date 字段的值保存为订单的元数据。woocommerce_admin_order_data_after_billing_address: 在WooCommerce后台订单详情页面的账单地址下方显示保存的配送日期。woocommerce_email_after_order_table: 在所有WooCommerce订单邮件的订单表格下方显示配送日期。注意事项与总结
代码位置:所有PHP代码应放置在您主题的 functions.php 文件中,或者更推荐的方式是创建一个自定义插件来管理这些功能。文本域:在 __('Text', 'your-text-domain') 中,请将 'your-text-domain' 替换为您主题或插件的实际文本域,以便进行国际化。费用金额:您可以根据需要修改 $fee_amount 的值来调整附加费用的金额。日期选择器配置:xdsoft DateTimePicker提供了丰富的配置选项,您可以根据业务需求调整 minDate、maxDate、allowDates、beforeShowDay 等参数,例如禁用周末或特定节假日。测试:在生产环境中使用前,请务必在开发或测试环境中进行全面测试,确保所有功能按预期工作。**以上就是WooCommerce结账:实现基于配送日期选择的附加费用与日期选择器集成的详细内容,更多请关注php中文网其它相关文章!
 
 
 
 
 
 
 
 
 




