Let’s imagine you want to add a custom checkout field (not an additional billing or shipping field) on the WooCommerce Checkout page. For example, it might be a customer licence number – this has got nothing to do with billing and nothing to do with shipping.

Ideally, this could be something that should show above the checkout order notes – so yes, not in the billing or shipping form. So, here’s how you do it – hope it helps you understand that anything is possible!

Here’s our new custom checkout field, purposely displayed outside the billing/shipping forms.

PHP Snippet (Part 1 of 3): Add New Field @ WooCommerce Checkout

In here we display the new field on the WooCommerce Checkout page, and specifically above the “Order Notes”, which usually display in the shipping column.

The new field ID is “license_no“, which will be useful to remember in parts 2 and 3.

/**
 * @snippet       Add Custom Field @ WooCommerce Checkout Page
 * @how-to        Get CustomizeWoo.com FREE
 * @author        Rodolfo Melogli
 * @testedwith    WooCommerce 3.8
 * @donate $9     https://businessbloomer.com/bloomer-armada/
 */
 
add_action( 'woocommerce_before_order_notes', 'bbloomer_add_custom_checkout_field' );
 
function bbloomer_add_custom_checkout_field( $checkout ) { 
   $current_user = wp_get_current_user();
   $saved_license_no = $current_user->license_no;
   woocommerce_form_field( 'license_no', array(        
      'type' => 'text',        
      'class' => array( 'form-row-wide' ),        
      'label' => 'License Number',        
      'placeholder' => 'CA12345678',        
      'required' => true,        
      'default' => $saved_license_no,        
   ), $checkout->get_value( 'license_no' ) ); 
}

PHP Snippet (Part 2 of 3): Validate New Checkout Field

Now, once the checkout is processed, we want to make sure our field is not empty. Remember, we chose “required” => true which means the field will have a required mark beside its label. However, this is not enough – we still need to generate an error message if our field is empty.

/**
 * @snippet       Validate Custom Field @ WooCommerce Checkout Page
 * @how-to        Get CustomizeWoo.com FREE
 * @author        Rodolfo Melogli
 * @testedwith    WooCommerce 3.8
 * @donate $9     https://businessbloomer.com/bloomer-armada/
 */

add_action( 'woocommerce_checkout_process', 'bbloomer_validate_new_checkout_field' );
 
function bbloomer_validate_new_checkout_field() {    
   if ( ! $_POST['license_no'] ) {
      wc_add_notice( 'Please enter your Licence Number', 'error' );
   }
}

PHP Snippet (Part 3 of 3): Save & Show New Field @ WooCommerce Orders & Emails

If validation is passed, WooCommerce processes the order. But the new field value gets lost, as there is no function that “stores” that value into the so-called “Order Meta Data”. We need to save and also to display the field value inside orders and order emails.

/**
 * @snippet       Save & Display Custom Field @ WooCommerce Order
 * @how-to        Get CustomizeWoo.com FREE
 * @author        Rodolfo Melogli
 * @testedwith    WooCommerce 3.8
 * @donate $9     https://businessbloomer.com/bloomer-armada/
 */

add_action( 'woocommerce_checkout_update_order_meta', 'bbloomer_save_new_checkout_field' );
 
function bbloomer_save_new_checkout_field( $order_id ) { 
    if ( $_POST['license_no'] ) update_post_meta( $order_id, '_license_no', esc_attr( $_POST['license_no'] ) );
}
 
add_action( 'woocommerce_admin_order_data_after_billing_address', 'bbloomer_show_new_checkout_field_order', 10, 1 );
  
function bbloomer_show_new_checkout_field_order( $order ) {    
   $order_id = $order->get_id();
   if ( get_post_meta( $order_id, '_license_no', true ) ) echo '<p><strong>License Number:</strong> ' . get_post_meta( $order_id, '_license_no', true ) . '</p>';
}

add_action( 'woocommerce_email_after_order_table', 'bbloomer_show_new_checkout_field_emails', 20, 4 );
 
function bbloomer_show_new_checkout_field_emails( $order, $sent_to_admin, $plain_text, $email ) {
    if ( get_post_meta( $order->get_id(), '_license_no', true ) ) echo '<p><strong>License Number:</strong> ' . get_post_meta( $order->get_id(), '_license_no', true ) . '</p>';
}
Share:

Leave a Reply