0

0

WooCommerce结账:实现基于配送日期选择的附加费用与日期选择器集成

霞舞

霞舞

发布时间:2025-10-31 11:13:36

|

183人浏览过

|

来源于php中文网

原创

WooCommerce结账:实现基于配送日期选择的附加费用与日期选择器集成

本教程详细指导如何在woocommerce结账页面集成xdsoft datetimepicker,并根据用户选择的配送日期(当天或次日)动态添加附加费用。文章涵盖了自定义日期字段的创建、前端日期选择器的配置、后端条件费用计算逻辑、结账页面动态更新,以及将配送日期保存并显示在订单详情和邮件中的完整实现步骤,旨在提升店铺配送的灵活性和自动化管理能力。

在WooCommerce商店中,为特定配送日期(例如当日或次日达)提供附加费用是一种常见的业务需求。这不仅能为客户提供更灵活的配送选项,也能为商家带来额外的收入。本教程将引导您完成在WooCommerce结账页面添加一个自定义配送日期选择器,并根据用户选择的日期动态计算并应用附加费用的整个过程。

1. 添加自定义配送日期字段

首先,我们需要在WooCommerce结账页面添加一个用于选择配送日期的文本输入框。这个输入框将作为日期选择器的载体。

/**
 * 在WooCommerce结账页面添加自定义配送日期字段
 *
 * @param WC_Checkout $checkout 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库,并初始化日期选择器。

/**
 * 加载xdsoft DateTimePicker脚本并初始化
 *
 * @param array $available_gateways 可用的支付网关
 */
function load_and_init_datetimepicker( $available_gateways ) {
   ?>
    
        
    
   

这段代码通过 woocommerce_after_checkout_form 钩子在结账表单加载后执行。它会加载xdsoft DateTimePicker的CSS和JS文件,并初始化 #datepicker 元素。

  • format: 定义日期时间的显示和提交格式。
  • minDate: 0 表示最小可选日期为今天。
  • minTime: 设置每天最早的可选时间。
  • step: 设置时间选择的步长(例如30分钟)。
  • allowTimes: 限制用户只能选择特定时间段。
  • onSelectDate 和 onSelectTime: 这两个回调函数在用户选择日期或时间后触发 update_checkout 事件。这个事件会通知WooCommerce重新计算购物车和费用,确保附加费用能够动态更新。

3. 验证配送日期选择

在用户提交订单之前,确保配送日期字段已被填写是必要的。

/**
 * 验证自定义配送日期字段
 */
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 字段为空,则会显示一个错误通知,阻止订单提交。

析稿Ai写作
析稿Ai写作

科研人的高效工具:AI论文自动生成,十分钟万字,无限大纲规划写作思路。

下载

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()->cart->add_fee() 添加一个名为“快速配送费”的附加费用。
  • 如果选择的是其他日期,或者 delivery_date 未设置,它会遍历购物车中的所有费用,并移除名为“快速配送费”的费用,以确保费用只在满足条件时才显示。

5. 保存并显示配送日期信息

为了在订单管理和客户邮件中查看配送日期,我们需要将选择的日期保存到订单元数据中,并在相应位置显示。

/**
 * 保存配送日期到订单元数据
 *
 * @param int $order_id 订单ID
 */
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' );

/**
 * 在WooCommerce后台订单详情页显示配送日期
 *
 * @param WC_Order $order 订单对象
 */
function show_delivery_date_field_order( $order ) {    
   $delivery_date = get_post_meta( $order->get_id(), 'delivery_date', true );
   if ( $delivery_date ) {
       echo '

' . __( 'Delivery Date', 'your-text-domain' ) . ': ' . esc_html( $delivery_date ) . '

'; } } add_action( 'woocommerce_admin_order_data_after_billing_address', 'show_delivery_date_field_order', 10, 1 ); /** * 在WooCommerce订单邮件中显示配送日期 * * @param WC_Order $order 订单对象 * @param bool $sent_to_admin 是否发送给管理员 * @param bool $plain_text 是否为纯文本邮件 * @param WC_Email $email 邮件对象 */ 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 '

' . __( 'Delivery Date', 'your-text-domain' ) . ': ' . esc_html( $delivery_date ) . '

'; } } 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 等参数,例如禁用周末或特定节假日。
  • 测试:在生产环境中使用前,请务必在开发或测试环境中进行全面测试,确保所有功能按预期工作。
  • **

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

2687

2023.09.01

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

1662

2023.10.11

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

1523

2023.10.11

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

953

2023.10.23

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

1420

2023.10.23

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

1235

2023.11.03

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1488

2023.11.09

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1306

2023.11.13

PS使用蒙版相关教程
PS使用蒙版相关教程

本专题整合了ps使用蒙版相关教程,阅读专题下面的文章了解更多详细内容。

23

2026.01.19

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 0.8万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.9万人学习

CSS教程
CSS教程

共754课时 | 21万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号