WooCommerce Custom Checkout Validation

In this tutorial we remove default validation and create custom validation rules. Also I will show you one trick how to replace all the default validation messages with just a single one.

#WooCommerce, #checkout, #season_2  /    /   7

Remove Default Validation from Fields #

If you need to remove validation for some of WooCommerce checkout fields, let’s say email, phone or postcode, all you have to do is to remove validate parameter from a field. You can do it in woocommerce_checkout_fields filter hook, example:

add_filter( 'woocommerce_checkout_fields', 'misha_no_email_validation' );
 
function misha_no_email_validation( $fields ){
 
	unset( $fields['billing']['billing_email']['validate'] );
	return $fields;
 
}

I already mentioned this topic in my WooCommerce checkout fields tutorial, check other examples there.

Validate First and Last names to Contain Only Letters #

When creating your custom validation, you do have to do anything in woocommerce_checkout_fields hook (I mean validate parameter of course).

Just use woocommerce_after_checkout_validation to add your custom validation rules and error messages for them.

add_action( 'woocommerce_after_checkout_validation', 'misha_validate_fname_lname', 10, 2);
 
function misha_validate_fname_lname( $fields, $errors ){
 
    if ( preg_match( '/\\d/', $fields[ 'billing_first_name' ] ) || preg_match( '/\\d/', $fields[ 'billing_last_name' ] )  ){
        $errors->add( 'validation', 'Your first or last name contains a number. Really?' );
    }
}

Here is my result:

Custom validation for First name and Last name checkout fields.

JavaScript validation #

Did you notice something weird on the previous screenshot? 😁 No? Do you see that the error message says that either first name or last name is incorrect, but both of the fields are highlighted in green, not in red?

Let me show what I mean:

JavaScript validation of a billing first name checkout field

Much better, huh? How to implement it?

WooCommerce JS validation function is in checkout.js but it only checks if email matches the pattern and if the required fields are not empty. We have to add some custom JavaScript somewhere to create our own validation function. All we need is to operate with two wrapper classes: woocommerce-validated, woocommerce-invalid.

Below is a very simple example for the Billing Last Name field, you can upgrade this code if you want.

$('body').on('blur change', '#billing_last_name', function(){
	var wrapper = $(this).closest('.form-row');
	// you do not have to removeClass() because Woo do it in checkout.js
	if( /\d/.test( $(this).val() ) ) { // check if contains numbers
		wrapper.addClass('woocommerce-invalid'); // error
	} else {
		wrapper.addClass('woocommerce-validated'); // success
	}
});

Just in case if you do not know where to put the code – you can insert it to any of your website existing js files or even to website wp_footer(), example:

<?php
add_action( 'wp_footer', 'misha_checkout_js' );
function misha_checkout_js(){
 
	// we need it only on our checkout page
	if( !is_checkout() ) return;
 
	?>
	<script>
	jQuery(function($){
		// code will be here
	});
	</script>
	<?php
}

How to Show Only One Error Message? #

Below on the screenshot is what I mean:

A lot of validation errors at once in WooCommerce Checkout

So, how to prevent it and display just one error message instead?

Custom error message in WooCommerce Checkout

Easy peasy 😁

add_action( 'woocommerce_after_checkout_validation', 'misha_one_err', 9999, 2);
 
function misha_one_err( $fields, $errors ){
 
	// if any validation errors
	if( !empty( $errors->get_error_codes() ) ) {
 
		// remove all of them
		foreach( $errors->get_error_codes() as $code ) {
			$errors->remove( $code );
		}
 
		// add our custom one
		$errors->add( 'validation', 'Please fill the fields!' );
 
	}
 
}
Misha Rudrastyh
About the author Misha Rudrastyh

Passionate about WordPress and snowboarding, creating websites for over 9 years! Let's work together — just contact me.

If you are a developer too, subscribe to my facebook page.

Comments 7

  • Hey Misha, me again

    Well, this approach of your works really fine and thank you for that. Now I did tweak your code a little and comes up with this one:

    add_action( 'woocommerce_after_checkout_validation', 'misha_one_err', 9999, 2);
    function misha_one_err( $fields, $errors ){
    	// if any validation errors
    	if( !empty( $errors->get_error_codes() ) ) {
    		// remove all of them
    		foreach( $errors->get_error_codes() as $code ) {
    			$errors->remove( $code );
    		}
    		// add our custom one
    		$errors->add( 'validation', 'Please fill in all required fields to place order!' );
     
    	} else if ( empty( $_POST['billing_first_name'] ) ) {
    		$errors->add( 'woocommerce_password_error', __( 'First Name is a required field' ) );
    	} else if ( empty( $_POST['billing_last_name'] ) ) {
    		$errors->add( 'woocommerce_password_error', __( 'Last Name is a required field' ) );
    	} else if ( empty( $_POST['billing_address_1'] ) ) {
    		$errors->add( 'woocommerce_password_error', __( 'Street Address is a required field' ) );
    	} else if ( empty( $_POST['billing_city'] ) ) {
    		$errors->add( 'woocommerce_password_error', __( 'Town / City is a required field' ) );
    	} else if ( empty( $_POST['billing_state'] ) ) {
    		$errors->add( 'woocommerce_password_error', __( 'Province / State is a required field' ) );
    	} else if ( empty( $_POST['billing_postcode'] ) ) {
    		$errors->add( 'woocommerce_password_error', __( 'Postcode / ZIP is a required field' ) );
    	} else if ( empty( $_POST['billing_phone'] ) ) {
    		$errors->add( 'woocommerce_password_error', __( 'Phone is a required field' ) );
    	} 
    }

    I want to retain the error shown if a specific filed is empty and generate the error “Please fill in all required fields to place order!” ONLY if all fields are empty. I’m aware that there’s something wrong in my code above. Can you help me with this?

  • Hello Misha,

    Thank you for this one. It took me months to find this answer on how to show only one error message in checkout page. One quick question, is this also applicable to those fields in Woocommerce My Account billing address and account details? What hook should I use?

    • Hey 👋

      I’m glad, always welcome!

      No, for billing addresses there is a different hook woocommerce_after_save_address_validation, but I’m afraid it won’t work for you the same way.

      Try this code:

      add_action( 'woocommerce_after_save_address_validation', 'misha_notices', 20, 3 );
       
      function misha_notices( $user_id, $load_address, $address ){
       
      	if ( wc_notice_count( 'error' ) > 1 ) {
       
      		// empty notices
      		WC()->session->set( 'wc_notices', array() );
      		// add our custom one
      		wc_add_notice( 'Incorrect fields', 'error' );
       
      	}
       
      }
  • hey Misha! could you explain a bit more about how to implement the JS code – i don’t get if it’s needed to do both PHP in functions file and JS in Footer.

    thanks

Leave your question or feedback

phpjsHTMLCSSSQLCode
Please, enter a comment
Please, enter a name
Incorrect email