# Preferred Delivery Date Field at Checkout

> Adds a date picker to the classic checkout so customers can choose a delivery date after your lead time, then shows the date on the order screen and in emails.

- Type: PHP
- Runs: Run everywhere
- Category: [WooCommerce](https://wpide.com/library/category/woocommerce/)
- Requires: WooCommerce
- Tags: woocommerce, checkout, delivery, fields
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/woo-checkout-delivery-date/

## Code

```php
$wpide_delivery = array(
    'label'         => 'Preferred delivery date',
    'lead_days'     => 2,    // Earliest date = today + this many days.
    'max_days'      => 60,   // Latest date customers can pick.
    'required'      => false,
    'skip_weekends' => true,
);

add_filter( 'woocommerce_checkout_fields', function ( $fields ) use ( $wpide_delivery ) {
    $fields['order']['wpide_delivery_date'] = array(
        'type'              => 'date',
        'label'             => $wpide_delivery['label'],
        'required'          => $wpide_delivery['required'],
        'priority'          => 5,
        'custom_attributes' => array(
            'min' => wp_date( 'Y-m-d', strtotime( '+' . $wpide_delivery['lead_days'] . ' days' ) ),
            'max' => wp_date( 'Y-m-d', strtotime( '+' . $wpide_delivery['max_days'] . ' days' ) ),
        ),
    );

    return $fields;
} );

add_action( 'woocommerce_after_checkout_validation', function ( $data, $errors ) use ( $wpide_delivery ) {
    $value = (string) ( $data['wpide_delivery_date'] ?? '' );

    if ( '' === $value ) {
        return;
    }

    $date = DateTime::createFromFormat( '!Y-m-d', $value, wp_timezone() );

    if ( ! $date || $date->format( 'Y-m-d' ) !== $value ) {
        $errors->add( 'validation', 'Please choose a valid delivery date.' );
        return;
    }

    $earliest = new DateTime( 'today +' . $wpide_delivery['lead_days'] . ' days', wp_timezone() );

    if ( $date < $earliest ) {
        $errors->add( 'validation', sprintf( 'The earliest delivery date is %s.', esc_html( wp_date( get_option( 'date_format' ), $earliest->getTimestamp() ) ) ) );
    } elseif ( $wpide_delivery['skip_weekends'] && (int) $date->format( 'N' ) >= 6 ) {
        $errors->add( 'validation', 'We do not deliver at weekends. Please choose a weekday.' );
    }
}, 10, 2 );

add_action( 'woocommerce_checkout_create_order', function ( $order, $data ) {
    if ( ! empty( $data['wpide_delivery_date'] ) ) {
        $order->update_meta_data( '_wpide_delivery_date', sanitize_text_field( $data['wpide_delivery_date'] ) );
    }
}, 10, 2 );

$wpide_delivery_label = $wpide_delivery['label'];

add_action( 'woocommerce_admin_order_data_after_shipping_address', function ( $order ) use ( $wpide_delivery_label ) {
    $date = $order->get_meta( '_wpide_delivery_date' );

    if ( $date ) {
        printf( '<p><strong>%s:</strong> %s</p>', esc_html( $wpide_delivery_label ), esc_html( wp_date( get_option( 'date_format' ), strtotime( $date ) ) ) );
    }
} );

add_filter( 'woocommerce_email_order_meta_fields', function ( $fields, $sent_to_admin, $order ) use ( $wpide_delivery_label ) {
    $date = $order->get_meta( '_wpide_delivery_date' );

    if ( $date ) {
        $fields['wpide_delivery_date'] = array( 'label' => $wpide_delivery_label, 'value' => wp_date( get_option( 'date_format' ), strtotime( $date ) ) );
    }

    return $fields;
}, 10, 3 );
```

## Notes

Uses the browser's date picker; set 'lead_days' for the earliest date and 'skip_weekends' to refuse Saturdays and Sundays.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Preferred Delivery Date Field at Checkout" in its snippet library and add it in one click; or create a new PHP snippet in WPIDE (or any code snippets plugin) and paste the code above. More snippets: https://wpide.com/library/
