
本教程详细指导如何在woocommerce结账页面集成xdsoft datetimepicker,并根据用户选择的配送日期(当天或次日)动态添加附加费用。文章涵盖了自定义日期字段的创建、前端日期选择器的配置、后端条件费用计算逻辑、结账页面动态更新,以及将配送日期保存并显示在订单详情和邮件中的完整实现步骤,旨在提升店铺配送的灵活性和自动化管理能力。
在WooCommerce商店中,为特定配送日期(例如当日或次日达)提供附加费用是一种常见的业务需求。这不仅能为客户提供更灵活的配送选项,也能为商家带来额外的收入。本教程将引导您完成在WooCommerce结账页面添加一个自定义配送日期选择器,并根据用户选择的日期动态计算并应用附加费用的整个过程。
首先,我们需要在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初始化日期选择器的目标元素。
为了提供友好的日期选择体验,我们将集成xdsoft DateTimePicker。此步骤包括加载必要的CSS和JavaScript库,并初始化日期选择器。
/**
* 加载xdsoft DateTimePicker脚本并初始化
*
* @param array $available_gateways 可用的支付网关
*/
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 元素。
在用户提交订单之前,确保配送日期字段已被填写是必要的。
/**
* 验证自定义配送日期字段
*/
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 字段为空,则会显示一个错误通知,阻止订单提交。
这是实现核心逻辑的部分,我们将根据用户选择的配送日期来判断是否添加附加费用。
/**
* 根据配送日期动态添加附加费用
*/
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 钩子实现费用计算。
为了在订单管理和客户邮件中查看配送日期,我们需要将选择的日期保存到订单元数据中,并在相应位置显示。
/**
* 保存配送日期到订单元数据
*
* @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 '<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 );
/**
* 在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 '<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结账:实现基于配送日期选择的附加费用与日期选择器集成的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号