如何在WooCommerce结账页根据所选配送日期添加订单额外费用
WooCommerce 当日/次日配送附加费实现方案
实现逻辑分为3个核心模块:前端日期选择监听、后端动态费用计算、订单数据持久化,以下是完整可直接使用的修改后代码:
1. 原有代码调整(新增日期选择监听逻辑)
你原有代码中load_calendar_dates函数需要新增日期变化回调,修改后代码如下:
function load_calendar_dates( $available_gateways ) { ?> <script type="text/javascript"> jQuery(document).ready(function($) { jQuery.datetimepicker.setLocale('en'); var currentDate = new Date(); var minutes = currentDate.getMinutes(); 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", 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' ], // 新增:日期选择变化回调 onChangeDateTime: function(dp,$input){ let selectDate = $input.val(); // 发送AJAX请求更新配送附加费 $.ajax({ url: '<?php echo admin_url('admin-ajax.php'); ?>', type: 'POST', data: { action: 'update_delivery_surcharge', delivery_date: selectDate, nonce: '<?php echo wp_create_nonce('delivery_date_nonce'); ?>' }, success: function(res){ // 刷新结账页费用预览 $(document.body).trigger('update_checkout'); } }); } }); }); </script> <?php } add_action( 'woocommerce_after_checkout_form', 'load_calendar_dates', 20 );
2. 新增后端费用计算逻辑
将以下代码添加到你主题的functions.php或自定义插件中即可:
// 处理AJAX请求,存储选择的配送日期到会话 add_action('wp_ajax_update_delivery_surcharge', 'save_delivery_date_to_session'); add_action('wp_ajax_nopriv_update_delivery_surcharge', 'save_delivery_date_to_session'); function save_delivery_date_to_session() { // 安全校验 if (!wp_verify_nonce($_POST['nonce'], 'delivery_date_nonce')) { wp_send_json_error('非法请求'); } if (isset($_POST['delivery_date'])) { WC()->session->set('selected_delivery_date', sanitize_text_field($_POST['delivery_date'])); wp_send_json_success('日期已保存'); } wp_send_json_error('日期参数缺失'); } // 动态计算配送附加费 add_action('woocommerce_cart_calculate_fees', 'add_delivery_surcharge'); function add_delivery_surcharge() { // 仅在结账页生效 if (is_admin() && !defined('DOING_AJAX')) return; if (!is_checkout()) return; $delivery_date = WC()->session->get('selected_delivery_date'); if (empty($delivery_date)) return; // 转换为站点时区的时间,避免时区偏差 $site_timezone = new DateTimeZone(wc_timezone_string()); $select_dt = DateTime::createFromFormat('Y/m/d H:i:s', $delivery_date, $site_timezone); $today = new DateTime('now', $site_timezone); $today->setTime(0,0,0); $tomorrow = (clone $today)->modify('+1 day'); $surcharge = 0; // 判断是否为当日或次日配送 if ($select_dt >= $today && $select_dt < $tomorrow) { $surcharge = 15; // 当日配送附加费,可自行修改金额 } elseif ($select_dt >= $tomorrow && $select_dt < (clone $tomorrow)->modify('+1 day')) { $surcharge = 10; // 次日配送附加费,可自行修改金额 } if ($surcharge > 0) { // 第二个参数设为true表示附加费需要计税,不需要可改为false WC()->cart->add_fee('紧急配送附加费', $surcharge, true); } } // 新增:配送日期保存到订单元数据 add_action('woocommerce_checkout_create_order', 'save_delivery_date_to_order'); function save_delivery_date_to_order($order) { $delivery_date = WC()->session->get('selected_delivery_date'); if (!empty($delivery_date)) { $order->update_meta_data('配送日期', sanitize_text_field($delivery_date)); // 清空会话数据 WC()->session->__unset('selected_delivery_date'); } } // 新增:后台订单详情页显示配送日期 add_action('woocommerce_admin_order_data_after_billing_address', 'show_delivery_date_in_admin_order'); function show_delivery_date_in_admin_order($order) { $delivery_date = $order->get_meta('配送日期'); if ($delivery_date) { echo '<p><strong>配送日期:</strong>' . esc_html($delivery_date) . '</p>'; } }
注意事项
- 附加费金额可自行修改代码中标注的
15和10数值 - 如果不需要区分当日和次日的附加费金额,直接统一设置为相同数值即可
- 代码默认使用站点后台设置的时区判断日期,不会出现时区偏差问题
- 原有代码的日期校验逻辑可保留不变,已经兼容新增功能
内容的提问来源于stack exchange,提问作者shadow_hunter104
相关产品推荐
相关产品推荐

