
本教程详细指导如何在woocommerce商店的结账页面集成xdsoft datetimepicker,允许顾客选择配送日期和时间。文章涵盖了如何添加自定义日期选择字段、验证输入、动态计算并收取基于选择日期的额外费用(例如,当日或次日配送费),以及将选定的配送日期保存并显示在订单详情和邮件中。通过此教程,您可以为客户提供更灵活的配送选项,并有效管理相关费用。
在现代电商环境中,提供灵活的配送选项对于提升用户体验至关重要。本教程将引导您在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', // 用于JavaScript初始化的ID
'required' => true,
'label' => __('Select Delivery Date', 'your-text-domain'),
'placeholder' => __('Click to select date and time', 'your-text-domain'),
));
}
add_action( 'woocommerce_after_order_notes', 'custom_delivery_date_field' );
/**
* 验证配送日期字段是否已选择
*/
function validate_custom_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_custom_delivery_date_field' );上述代码通过 woocommerce_form_field 函数创建了一个文本输入框,并将其放置在订单备注下方。validate_custom_delivery_date_field 函数则确保用户在提交订单前必须选择一个配送日期。
2. 集成XDSoft DateTimePicker
为了让用户能够方便地选择日期和时间,我们将使用XDSoft DateTimePicker。这需要引入必要的JavaScript和CSS库,并初始化日期选择器。
/**
* 引入XDSoft DateTimePicker库并初始化
*/
function enqueue_datetimepicker_scripts() {
// 引入jQuery UI (如果xdsoft datetimepicker依赖它,虽然通常不直接依赖)
// wp_enqueue_script( 'jquery-ui-datepicker' ); // 如果需要jQuery UI Datepicker的功能
// 引入XDSoft DateTimePicker的CSS和JS
wp_enqueue_style( 'jquery-datetimepicker-css', 'https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.min.css', array(), '2.5.20' );
wp_enqueue_script( 'jquery-datetimepicker-js', 'https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.full.min.js', array('jquery'), '2.5.20', true );
?>
这段代码首先通过 wp_enqueue_style 和 wp_enqueue_script 引入了DateTimePicker的CSS和JS文件。然后,在 woocommerce_after_checkout_form 钩子中,使用JavaScript初始化了 #datepicker 元素。关键配置包括 format(日期时间格式)、minDate(禁用过去日期)、minTime(最早可选时间)、step(时间间隔)和 allowTimes(允许选择的具体时间点)。最重要的是,onSelectDate 和 onSelectTime 回调函数会在用户选择日期或时间后触发 update_checkout 事件,这将强制WooCommerce重新计算购物车总价,从而动态更新费用。
3. 实现即时配送费用逻辑
现在,我们将添加核心逻辑:根据用户选择的配送日期,判断是否为当日或次日配送,并据此收取额外费用。
/**
* 根据选择的配送日期添加额外费用
*/
function wc_add_delivery_surcharge() {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
return;
}
// 从POST数据中解析配送日期
$post_data = array();
if ( isset( $_POST['post_data'] ) ) {
parse_str( $_POST['post_data'], $post_data );
}
// 确保配送日期字段存在且不为空
if ( isset( $post_data['delivery_date'] ) && ! empty( $post_data['delivery_date'] ) ) {
$current_date_stamp = strtotime( date("Y-m-d") ); // 当天的0点时间戳
$selected_date_stamp = strtotime( substr($post_data['delivery_date'], 0, 10) ); // 截取日期部分并转换为时间戳
// 计算日期差异(天数)
$datediff_seconds = $selected_date_stamp - $current_date_stamp;
$difference_days = floor( $datediff_seconds / (60 * 60 * 24) );
$fee_amount = 5.00; // 即时配送费用金额
// 如果选择的日期是今天(0天差异)或明天(1天差异)
if ( $difference_days == 0 || $difference_days == 1 ) {
WC()->cart->add_fee( __( 'Fast delivery charge', 'your-text-domain' ), $fee_amount, true, 'standard' );
} else {
// 如果不是当日或次日,确保移除可能存在的费用
// 注意: WooCommerce 3.2+ 推荐使用 WC()->cart->remove_fee()
// 对于动态更新的购物车,通常在每次计算时重新添加或不添加费用即可
// 如果需要显式移除,可以遍历现有费用
$fees = WC()->cart->get_fees();
foreach ($fees as $key => $fee) {
if($fees[$key]->name === __( "Fast delivery charge", 'your-text-domain' )) {
unset($fees[$key]); // 从费用数组中移除
}
}
// 重新设置费用数组 (如果需要,但通常add_fee会在每次计算时重新评估)
// WC()->cart->set_fees($fees); // 此行可能不是必需的,取决于WooCommerce版本和具体行为
}
} else {
// 如果delivery_date字段不存在或为空,也需要移除可能的费用
$fees = WC()->cart->get_fees();
foreach ($fees as $key => $fee) {
if($fees[$key]->name === __( "Fast delivery charge", 'your-text-domain' )) {
unset($fees[$key]);
}
}
}
}
add_action( 'woocommerce_cart_calculate_fees', 'wc_add_delivery_surcharge' );此函数挂载到 woocommerce_cart_calculate_fees 钩子,这是WooCommerce计算购物车总价和费用的地方。
- 它首先从 $_POST['post_data'] 中解析出 delivery_date 的值。parse_str 是处理AJAX请求中表单数据的好方法。
- 然后,它将当前日期和选定日期都转换为时间戳,并计算它们之间的天数差异。
- 如果差异为0(今天)或1(明天),则使用 WC()->cart->add_fee() 添加一个名为“Fast delivery charge”的额外费用。
- 如果差异不是0或1,则确保移除可能已添加的即时配送费用,以防止重复收费或错误收费。
4. 保存并显示配送日期
为了确保配送日期信息在订单处理过程中可用,我们需要将其保存到订单元数据中,并在后台订单详情页和客户邮件中显示。
/**
* 保存配送日期字段到订单元数据
*
* @param int $order_id 订单ID
*/
function save_delivery_date_field_to_order_meta( $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_to_order_meta' );
/**
* 在后台订单详情页显示配送日期
*
* @param WC_Order $order 订单对象
*/
function display_delivery_date_in_admin_order( $order ) {
$delivery_date = $order->get_meta( 'delivery_date' );
if ( ! empty( $delivery_date ) ) {
echo '' . __( 'Delivery Date', 'your-text-domain' ) . ': ' . esc_html( $delivery_date ) . '
';
}
}
add_action( 'woocommerce_admin_order_data_after_billing_address', 'display_delivery_date_in_admin_order', 10, 1 );
/**
* 在订单邮件中显示配送日期
*
* @param WC_Order $order 订单对象
* @param bool $sent_to_admin 是否发送给管理员
* @param bool $plain_text 是否为纯文本邮件
* @param WC_Email $email 邮件对象
*/
function display_delivery_date_in_emails( $order, $sent_to_admin, $plain_text, $email ) {
$delivery_date = $order->get_meta( 'delivery_date' );
if ( ! empty( $delivery_date ) ) {
echo '' . __( 'Delivery Date', 'your-text-domain' ) . ': ' . esc_html( $delivery_date ) . '
';
}
}
add_action( 'woocommerce_email_after_order_table', 'display_delivery_date_in_emails', 20, 4 );
- save_delivery_date_field_to_order_meta 函数在订单创建时,将用户选择的 delivery_date 保存为订单的自定义字段。
- display_delivery_date_in_admin_order 函数在WooCommerce后台的订单编辑页面显示这个自定义字段。
- display_delivery_date_in_emails 函数则确保在发送给客户和管理员的订单邮件中也包含配送日期信息。
注意事项与总结
- 代码位置: 建议将所有PHP代码放入您主题的 functions.php 文件中,或者创建一个自定义插件来管理这些功能。
- 文本域: 示例代码中使用了 your-text-domain 作为文本域。在实际使用时,请替换为您的主题或插件的实际文本域,以便进行国际化。
- 日期格式: 确保前端JavaScript中的 format 与后端PHP中处理日期字符串的逻辑保持一致,以避免解析错误。
- 费用调整: 您可以根据业务需求调整 wc_add_delivery_surcharge 函数中的 $fee_amount。
- 测试: 在生产环境部署前,务必在测试环境中进行全面测试,确保所有功能按预期工作,特别是费用计算和日期验证。
- 兼容性: 确保您的WooCommerce版本与XDSoft DateTimePicker库兼容。
通过以上步骤,您已经成功地在WooCommerce结账页面添加了一个功能完善的配送日期选择器,并实现了基于日期选择的动态费用收取机制。这不仅提升了客户的购物体验,也为您的商店提供了更精细的配送管理能力。










