Ever wished your WooCommerce store could let customers pick their preferred delivery date and time? Good news—it can! With a simple code snippet, you can add this feature to your checkout page, giving your customers more control and improving their shopping experience.
In this post, I’ll walk you through what the code does, how to use it, and why using the Code Snippets plugin is the way to go.
What Does This Code Do?
This code adds two new fields to your WooCommerce checkout page:
1. Preferred Delivery Date: A calendar date picker where customers can select a delivery date within a specified range.
2. Preferred Delivery Time: A dropdown menu of time slots based on your defined schedule.

Here’s what the code handles:
- Configurable Delivery Schedule: You set the start and end times, the interval between time slots (like every 15 minutes), and how many days ahead customers can book.
- Disable Weekends: Option to disable deliveries on weekends.
- Validation: Ensures customers select both a date and time within the allowed range before placing an order.
- Order Integration: Saves the selected date and time with the order details, so you can see it in the admin dashboard and include it in emails to customers.
Video: How to Allow Customers to Choose the Delivery Date and Time in WooCommerce?
How to Add This Feature to Your Store
You can add this functionality to your WooCommerce store by adding the provided code. There are two main ways to do this:
Option 1: Using the functions.php File
1. Access Your Theme’s Files: Go to your WordPress dashboard, navigate to Appearance > Theme Editor, and open the functions.php file.
2. Backup First: Always make a backup of your functions.php file before making changes.
3. Add the Code: Paste the entire code snippet at the end of the functions.php file.
4. Save Changes: Click “Update File” to save.
Important: Editing the functions.php file can be risky. A small error can break your site, and updates to your theme might overwrite your changes.
Option 2: Using the Code Snippets Plugin (Recommended)
1. Install the Plugin: From your WordPress dashboard, go to Plugins > Add New, search for “Code Snippets,” install, and activate it.
2. Add a New Snippet: Navigate to Snippets > Add New.
3. Name Your Snippet: Give it a descriptive name like “Delivery Date and Time Picker.”
4. Paste the Code: Copy the entire code snippet into the code area.
5. Save and Activate: Click “Save Changes and Activate.”
Use this code:
if (!defined('ABSPATH')) {
exit; // Exit if accessed directly
}
// Delivery Time Configuration
define('DELIVERY_START_TIME', '10:00'); // Format: 'HH:mm' (24-hour format)
define('DELIVERY_END_TIME', '18:00'); // Format: 'HH:mm' (24-hour format)
define('DELIVERY_INTERVAL', 15); // in minutes (30 = half hour slots, 60 = hour slots)
// Delivery Date Configuration
define('DELIVERY_DAYS_AHEAD', 90); // number of days ahead to allow booking
define('DELIVERY_MIN_DAYS_AHEAD', 1); // minimum days ahead for delivery (1 = next day, 0 = today)
define('DELIVERY_DISABLE_WEEKENDS', true); // set to false to allow weekend deliveries
// Disabled Days Configuration (0 = Sunday, 6 = Saturday)
global $DELIVERY_DISABLED_DAYS;
$DELIVERY_DISABLED_DAYS = array(); // Initialize empty array
if (DELIVERY_DISABLE_WEEKENDS) {
$DELIVERY_DISABLED_DAYS = array(0, 6); // 0 = Sunday, 6 = Saturday
}
// Calculate date range
function wpsh_get_delivery_date_range() {
static $dates = null;
if ($dates === null) {
$dates = array(
'start' => date('Y-m-d', strtotime('+' . DELIVERY_MIN_DAYS_AHEAD . ' day')),
'end' => date('Y-m-d', strtotime('+' . DELIVERY_DAYS_AHEAD . ' days'))
);
}
return $dates;
}
// Generate time slots function
function wpsh_generate_time_slots($include_empty = true) {
static $time_slots = null;
if ($time_slots === null) {
$slots = array();
$current = strtotime(DELIVERY_START_TIME);
$end = strtotime(DELIVERY_END_TIME);
while ($current <= $end) {
$time_formatted = date('H:i', $current);
$time_display = date('g:i A', $current);
$slots[$time_formatted] = $time_display;
$current = strtotime('+' . DELIVERY_INTERVAL . ' minutes', $current);
}
$time_slots = $slots;
}
if ($include_empty) {
return array_merge(
array('' => __('Select a time slot', 'woocommerce')),
$time_slots
);
}
return $time_slots;
}
// Add custom date and time picker fields on the checkout page
add_action('woocommerce_after_checkout_billing_form', 'wpsh_add_delivery_fields');
function wpsh_add_delivery_fields($checkout) {
global $DELIVERY_DISABLED_DAYS;
$date_range = wpsh_get_delivery_date_range();
// Ensure $DELIVERY_DISABLED_DAYS is an array
if (!is_array($DELIVERY_DISABLED_DAYS)) {
$DELIVERY_DISABLED_DAYS = array();
}
// Convert PHP array to JavaScript array
$disabled_days_json = json_encode($DELIVERY_DISABLED_DAYS);
?>
<!-- Load flatpickr resources -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/flatpickr/4.6.13/flatpickr.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/flatpickr/4.6.13/flatpickr.min.js"></script>
<script type="text/javascript">
jQuery(document).ready(function($) {
// Define disabled days array
const disabledDays = <?php echo json_encode($DELIVERY_DISABLED_DAYS); ?>;
// Initialize flatpickr
flatpickr("#arrival_date", {
enableTime: false,
dateFormat: "Y-m-d",
minDate: "<?php echo esc_js($date_range['start']); ?>",
maxDate: "<?php echo esc_js($date_range['end']); ?>",
disable: [
function(date) {
// Get day of week (0-6)
const day = date.getDay();
// Check if this day should be disabled
return disabledDays.includes(day);
}
],
locale: {
firstDayOfWeek: 1 // Start with Monday
},
onOpen: function(selectedDates, dateStr, instance) {
console.log('Calendar opened');
console.log('Disabled days:', disabledDays);
},
onChange: function(selectedDates, dateStr, instance) {
console.log('Selected date:', dateStr);
}
});
// Form validation
$('form.checkout').on('checkout_place_order', function() {
const selectedDate = $('#arrival_date').val();
const selectedTime = $('#arrival_time').val();
if (!selectedDate) {
alert('Please select a preferred delivery date.');
return false;
}
if (!selectedTime) {
alert('Please select a preferred delivery time.');
return false;
}
return true;
});
});
</script>
<style type="text/css">
/* Ensure the date input has sufficient width */
#arrival_date {
min-width: 100%;
background: #fff !important;
cursor: pointer;
}
/* Make the calendar icon visible */
.flatpickr-calendar {
background: #fff;
}
/* Improve the calendar appearance */
.flatpickr-day.disabled {
cursor: not-allowed;
color: #ddd;
}
.flatpickr-day.selected {
background: #2271b1;
border-color: #2271b1;
}
</style>
<?php
// Add delivery date field
woocommerce_form_field('arrival_date', array(
'type' => 'text',
'class' => array('form-row-wide'),
'label' => __('Preferred delivery date', 'woocommerce'),
'required' => true,
'id' => 'arrival_date',
'placeholder' => __('Click to select a date', 'woocommerce'),
'custom_attributes' => array(
'autocomplete' => 'off',
'readonly' => 'readonly'
)
), $checkout->get_value('arrival_date'));
// Add delivery time field
woocommerce_form_field('arrival_time', array(
'type' => 'select',
'class' => array('form-row-wide'),
'label' => __('Preferred delivery time', 'woocommerce'),
'required' => true,
'id' => 'arrival_time',
'options' => wpsh_generate_time_slots()
), $checkout->get_value('arrival_time'));
}
// Validate the custom fields on checkout submission
add_action('woocommerce_checkout_process', 'wpsh_validate_delivery_fields');
function wpsh_validate_delivery_fields() {
$arrival_date = sanitize_text_field($_POST['arrival_date'] ?? '');
$arrival_time = sanitize_text_field($_POST['arrival_time'] ?? '');
$date_range = wpsh_get_delivery_date_range();
if (empty($arrival_date)) {
wc_add_notice(__('Please select a preferred delivery date.', 'woocommerce'), 'error');
return;
}
if (empty($arrival_time)) {
wc_add_notice(__('Please select a preferred delivery time.', 'woocommerce'), 'error');
return;
}
// Validate date range
$date_timestamp = strtotime($arrival_date);
$min_timestamp = strtotime($date_range['start']);
$max_timestamp = strtotime($date_range['end']);
if ($date_timestamp < $min_timestamp || $date_timestamp > $max_timestamp) {
wc_add_notice(sprintf(__('Please select a valid delivery date within the next %d days.', 'woocommerce'), DELIVERY_DAYS_AHEAD), 'error');
return;
}
// Validate time slot
$valid_slots = wpsh_generate_time_slots(false);
if (!array_key_exists($arrival_time, $valid_slots)) {
wc_add_notice(__('Please select a valid delivery time slot.', 'woocommerce'), 'error');
return;
}
}
// Save the custom fields data as order item meta
add_action('woocommerce_checkout_create_order_line_item', 'wpsh_save_delivery_fields', 10, 4);
function wpsh_save_delivery_fields($item, $cart_item_key, $values, $order) {
if (!empty($_POST['arrival_date'])) {
$date = sanitize_text_field($_POST['arrival_date']);
$formatted_date = date_i18n(get_option('date_format'), strtotime($date));
$item->add_meta_data(__('Preferred delivery date', 'woocommerce'), $formatted_date);
}
if (!empty($_POST['arrival_time'])) {
$time = sanitize_text_field($_POST['arrival_time']);
$formatted_time = date_i18n(get_option('time_format'), strtotime("2000-01-01 $time"));
$item->add_meta_data(__('Preferred delivery time', 'woocommerce'), $formatted_time);
}
}
// Display delivery information helper function
function wpsh_display_delivery_information($order) {
$displayed = false;
foreach ($order->get_items() as $item_id => $item) {
$delivery_date = $item->get_meta('Preferred delivery date');
$delivery_time = $item->get_meta('Preferred delivery time');
if (!$displayed && ($delivery_date || $delivery_time)) {
echo '<h3>' . esc_html__('Preferred Delivery Information', 'woocommerce') . '</h3>';
$displayed = true;
}
if ($delivery_date) {
echo '<p><strong>' . esc_html__('Preferred delivery date', 'woocommerce') . ':</strong> '
. esc_html($delivery_date) . '</p>';
}
if ($delivery_time) {
echo '<p><strong>' . esc_html__('Preferred delivery time', 'woocommerce') . ':</strong> '
. esc_html($delivery_time) . '</p>';
}
}
}
// Add delivery information to emails and thank you page
add_action('woocommerce_email_order_meta', 'wpsh_add_delivery_fields_to_emails', 20, 3);
function wpsh_add_delivery_fields_to_emails($order, $sent_to_admin = false, $plain_text = false) {
wpsh_display_delivery_information($order);
}
add_action('woocommerce_thankyou', 'wpsh_add_delivery_fields_to_thankyou', 20);
function wpsh_add_delivery_fields_to_thankyou($order_id) {
$order = wc_get_order($order_id);
if ($order) {
wpsh_display_delivery_information($order);
}
}
// Show delivery fields in admin
add_action('woocommerce_admin_order_data_after_billing_address', 'wpsh_show_delivery_fields_in_admin', 10);
function wpsh_show_delivery_fields_in_admin($order) {
wpsh_display_delivery_information($order);
}
Why Use Code Snippets?
• Safety: It prevents errors that can occur from editing core files.
• Organization: Keeps all your custom code in one place.
• Portability: Snippets remain active even if you change themes.
• Easy Management: You can easily enable, disable, or modify snippets without digging into code files.
Configuring the Delivery Options
The code includes some settings at the top that you can customize:
define('DELIVERY_START_TIME', '10:00'); // Delivery start time
define('DELIVERY_END_TIME', '18:00'); // Delivery end time
define('DELIVERY_INTERVAL', 15); // Time slots in minutes
define('DELIVERY_DAYS_AHEAD', 90); // How many days ahead customers can book
define('DELIVERY_MIN_DAYS_AHEAD', 1); // Minimum days ahead for delivery
define('DELIVERY_DISABLE_WEEKENDS', true); // Disable weekend deliveries
- DELIVERY_START_TIME and DELIVERY_END_TIME: Set the daily delivery window.
- DELIVERY_INTERVAL: Set the length of each time slot (e.g., 15 minutes).
- DELIVERY_DAYS_AHEAD: How far into the future customers can schedule a delivery.
- DELIVERY_MIN_DAYS_AHEAD: Minimum days before the earliest delivery date.
- DELIVERY_DISABLE_WEEKENDS: Set to true to prevent deliveries on weekends.
Feel free to adjust these settings to match your business hours and policies.
Disabling Specific Days (Like Weekends)
There’s a handy part of the code that lets you disable specific days of the week for deliveries. This is great if, for example, you don’t offer deliveries on weekends.
Here’s the line in the code that does this:
$DELIVERY_DISABLED_DAYS = array(0, 6); // 0 = Sunday, 6 = Saturday
What’s Happening Here?
By customizing the $DELIVERY_DISABLED_DAYS array, you can tailor the delivery date options to perfectly fit your business’s schedule.
$DELIVERY_DISABLED_DAYS: This is an array (a list) that holds the numbers representing the days you want to disable.
Day Numbers: In programming, days of the week are often numbered from 0 to 6, where:
- 0 = Sunday
- 1 = Monday
- 2 = Tuesday
- 3 = Wednesday
- 4 = Thursday
- 5 = Friday
- 6 = Saturday
In the code above, we’re disabling Sunday (0) and Saturday (6), effectively preventing customers from selecting weekends for delivery.
Customizing Disabled Days
You can easily adjust this to match your delivery schedule. Here are some examples:
Disable only for Sundays:
$DELIVERY_DISABLED_DAYS = array(0); // 0 = Sunday
Disable Wednesdays and Fridays:
$DELIVERY_DISABLED_DAYS = array(3, 5); // 3 = Wednesday, 5 = Friday
Disable Weekdays (Only Deliver on Weekends):
$DELIVERY_DISABLED_DAYS = array(1, 2, 3, 4, 5); // Disables Monday to Friday
How It Affects the Date Picker
When customers go to select a delivery date at checkout:
- Disabled Days: The days you’ve specified will be grayed out and unselectable in the calendar.
- Customer Experience: This guides customers to choose only the dates you’re available for deliveries, reducing confusion and potential scheduling issues.
Why This is Useful
- Control Over Schedule: It gives you full control over which days you’re willing to deliver.
- Avoids Mistakes: Prevents customers from selecting dates when you’re closed or unavailable.
- Flexibility: Easily adjustable as your business hours change—just update the array.
Quick Tip
Remember, after changing the disabled days in the code, always test the date picker on your checkout page to ensure it’s working as expected.
What Happens When You Add This Code?
Once the code is active:
Woocommerce Checkout Page:
- Customers will see two new fields under the billing details—“Preferred delivery date” and “Preferred delivery time.”
- The date field uses a calendar picker, ensuring customers only select valid dates.
- The time field provides a dropdown of available time slots.
- Validation: The checkout won’t proceed unless both fields are filled out correctly.
Order Details:
- Admin View: You can see the selected date and time in the order details within your dashboard.
- Customer Emails: The delivery preferences are included in order confirmation emails.
- Thank You Page: After checkout, customers see their selected delivery date and time.
Final Thoughts
Adding a delivery date and time picker enhances the customer experience by allowing them to choose when they receive their orders. It’s especially useful for businesses offering local delivery or services that require scheduling.
Using the Code Snippets plugin makes this addition easy and safe, even if you’re not a developer. It’s a straightforward way to add custom functionality to your WooCommerce store without the risk of breaking your site.