This is particularly useful for Print on Demand services, hand-crafted items, or any product that requires a bit of customization. One way to communicate this additional delay is via Lead Times. Lead times let a potential customer know that there could be a short delay from when the purchase the product to when it is ready to ship.
Now there are plugins out there that can do this sort of thing, but it’s such an easy thing to DIY, I figured I share my strategy. For ease of use you may copy/paste these snippets into your functions.php file, or copy and paste this code into your own plugin.
The following snippet of code will create two fields in the Product -> Inventory tab:
As an admin, you only need to use one of the above options.
add_action('woocommerce_product_options_inventory_product_data', function (){ echo '<div class="option_group">'; echo '<h2>Lead Time</h2>'; echo '<p>This information will indicate to the customer if there is a lead time for ordering these products.</p>'; woocommerce_wp_text_input( array( 'id' => 'lead_time_days', 'name' => 'lead_time_days', 'value' => get_post_meta( get_the_ID(), 'lead_time_days', true ), 'label' => __( 'Lead Time Days', 'woocommerce' ), 'placeholder' => '', 'desc_tip' => 'true', 'type' => 'number' ) ); woocommerce_wp_text_input( array( 'id' => 'lead_time_note', 'name' => 'lead_time_note', 'value' => get_post_meta( get_the_ID(), 'lead_time_note', true ), 'label' => __( 'Lead Time Note', 'woocommerce' ), 'placeholder' => '', 'desc_tip' => 'true', 'type' => 'text' ) ); echo '</div>'; });
Now WooCommerce doesn’t automatically save our new fields for us. We have to do that ourselves:
add_action( 'woocommerce_process_product_meta', function ( $id, $post ){ update_post_meta( $id, 'lead_time_days', $_POST['lead_time_days'] ); update_post_meta( $id, 'lead_time_note', $_POST['lead_time_note'] ); }, 10, 2 );
Next we hook into the woocommerce_single_product_summary hook, which typically shows the product information in general. We decided it looks best at priority 10, but please feel free to adjust this placement and hook if you prefer it elsewhere.
This bit of code simply fetches the fields, and wraps them in a bit of HTML prior to display.
add_action('woocommerce_single_product_summary', function(){ global $product; $leadTime = [ 'days' => get_post_meta( get_the_ID(), 'lead_time_days', true ), 'note' => get_post_meta( get_the_ID(), 'lead_time_note', true ), ]; if( ! ( $leadTime['days'] || $leadTime['note'] ) ) return ''; ?> <div class="lead-time-notice"> <?php if( $leadTime['note']) { printf('<p class="lead-time-note">%s</p>', esc_html( $leadTime['note'] ) ); } ?> <?php if( $leadTime['days']) { printf('<p class="lead-time-length">This product will ship in <span class="lead-time-days">%s Days</span></p>', intval( $leadTime['days'] ) ); } ?> </div> <?php }, 10 );
Lastly, you can style the messages using a bit of CSS. Try editing it to give the effect you’re going for!
add_action('wp_footer', function(){ <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cstyle%3E%0A%20%20%20%20%20%20%20%20.lead-time-notice%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20margin-top%3A%206px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20margin-bottom%3A%206px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20display%3A%20block%20!important%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20width%3A%20auto%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3A%20%23666e24%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20padding%3A%206px%2012px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20background%3A%20%23eef3c2%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20border%3A%201px%20solid%20%23bac370%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20border-radius%3A%205px%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20.lead-time-days%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20font-weight%3A%20bold%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20.lead-time-length%2C%20.lead-time-note%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20margin%3A%200px%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%3C%2Fstyle%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<style>" title="<style>" /> });