WooCommerce Checkout Fields

It is the first tutorial in the series about Checkout Fields and Order Custom Fields. We begin with WooCommerce checkout form customization.

/82 comments

WooCommerce just like WordPress has a lot of great actions and filters (sometimes you’ll understand that not enough, but it is ok). When working with filters you can change the only file – functions.php and it will be enough (of course it would be better if this is the functions.php of your child theme).

The main filter we will work today is woocommerce_checkout_fields.

But if you’re looking how to skip the cart and implement a one page checkout for your WooCommerce store, this plugin should help you. Actually it allows you to create a custom checkout page in your store.

Introduction to woocommerce_checkout_fields

If you are here just because you want to remove some unnecessary checkout fields or because you would like to disable ZIP code validation, you can safely skip this step. But if you want to understand the whole process, you’re in the right place.

Ok, so, first of all open your WooCoommerce shop checkout. For me it looks like this.

WooCommerce StoreFront Theme Checkout Page.
This is the screenshot of the checkout page on my test website. Storefront theme is active. Right now we will try to manage the checkout fields.

By the way, if you are looking a way how to change "Place order" button text, then I recommend this tutorial.

add_filter( 'woocommerce_checkout_fields' , 'misha_print_all_fields' );
 
function misha_print_all_fields( $fields ) {
 
	//if( !current_user_can( 'manage_options' ) )
	//	return; // in case your website is live
 
	print_r( $fields ); // wrap results in pre html tag to make it clearer
	exit;
 
}

After inserting this piece of code you will see the array of all checkout fields with the parameters instead of the checkout form. As you can see in array, these fields are sorted by groups: billing, shipping, account, order.

And a specific field array looks like this:

[billing_company] => Array
(
	[label] => Company name
	[class] => Array
	(
		[0] => form-row-wide
	)
	[autocomplete] => organization
  	[priority] => 30
)

Disable Zip Post Code, Phone Number and State Validation

Below is the validation.

WooCommerce Default Fields Validation.
Not sure why but sometimes clients ask me to turn the validation off.

Yes, in this post we will work mostly with woocommerce_checkout_fields, but sometimes, when you have both billing and shipping fields in your checkout it is better to use woocommerce_default_address_fields action hook (which is described in a separate tutorial) because it affects both shipping and billing fields at the same moment.

So, it will be easier to disable post code and state validation with it.

add_filter( 'woocommerce_default_address_fields' , 'misha_disable_address_fields_validation' );
 
function misha_disable_address_fields_validation( $address_fields_array ) {
 
	unset( $address_fields_array['state']['validate']);
	unset( $address_fields_array['postcode']['validate']);
	// you can also hook first_name and last_name, company, country, city, address_1 and address_2
 
	return $address_fields_array;
 
}

Well, but what is with the phone field? It is not included in the address fields array. We will use woocommerce_checkout_fields to disable its validation.

add_filter( 'woocommerce_checkout_fields', 'misha_no_phone_validation' );
 
function misha_no_phone_validation( $woo_checkout_fields_array ) {
	unset( $woo_checkout_fields_array['billing']['billing_phone']['validate'] );
	return $woo_checkout_fields_array;
}

More about WooCommerce Checkout validation you can read in this tutorial.

Remove Checkout Fields

One day my client asked me to remove all the checkout fields except name, email and phone, because she wanted her customers to pay by cash when they come to her office to receive purchased products.

I think it is obvious, but please, do not hide checkout fields in CSS.

Removing fields is one of the most easiest steps in this tutorial. And here is how to do it:

add_filter( 'woocommerce_checkout_fields', 'misha_remove_fields', 9999 );
 
function misha_remove_fields( $woo_checkout_fields_array ) {
 
	// she wanted me to leave these fields in checkout
	// unset( $woo_checkout_fields_array['billing']['billing_first_name'] );
	// unset( $woo_checkout_fields_array['billing']['billing_last_name'] );
	// unset( $woo_checkout_fields_array['billing']['billing_phone'] );
	// unset( $woo_checkout_fields_array['billing']['billing_email'] );
	// unset( $woo_checkout_fields_array['order']['order_comments'] ); // remove order notes
 
	// and to remove the billing fields below
	unset( $woo_checkout_fields_array['billing']['billing_company'] ); // remove company field
	unset( $woo_checkout_fields_array['billing']['billing_country'] );
	unset( $woo_checkout_fields_array['billing']['billing_address_1'] );
	unset( $woo_checkout_fields_array['billing']['billing_address_2'] );
	unset( $woo_checkout_fields_array['billing']['billing_city'] );
	unset( $woo_checkout_fields_array['billing']['billing_state'] ); // remove state field
	unset( $woo_checkout_fields_array['billing']['billing_postcode'] ); // remove zip code field
 
	return $woo_checkout_fields_array;
}

I set 9999 priority to the hook because I want to run it as late as possible. Of course if you remove the checkout billing details, you shoudn’t hope that card payments will work for you. Of course they won’t. But if you would like to use PayPal Standard, everything should be ok.

After implementing the above code my checkout looks like this.

You can easily remove unnecessary checkout fields in WooCommerce.
If you receive payments on your website, especially payments by card, please, be careful with removing fields.

If you want to disable terms and conditions checkbox, you actually do not need any code, just go to WooCommerce settings and turn it off there. Read below where to find it.

Make Checkout Fields Optional or Required

Well, let’s continue with the same story – my client asked me: "Misha, please make the phone and email fields fullwidth, place email before phone and let’s make last name and phone fields not required".

I begin with making fields not required. All you need is to change the only parameter in the fields array, let’s do it now:

add_filter( 'woocommerce_checkout_fields' , 'misha_not_required_fields', 9999 );
 
function misha_not_required_fields( $f ) {
 
	unset( $f['billing']['billing_last_name']['required'] ); // that's it
	unset( $f['billing']['billing_phone']['required'] );
 
	// the same way you can make any field required, example:
	// $f['billing']['billing_company']['required'] = true;
 
	return $f;
}

Change Fields Order

If you read this post from the beginning, you remember that client asked me to place the email field before the phone. I decided to write a separate tutorial about fields reordering.

Anyway, sometimes after the reordering you get something like this:

Ordering checkout fields in WooCommerce, unexpected result.
Well, it is not what I expected.

But why this happened? Because it is not enough just to sort the fields array, you have to apply appropriate classes to each field as well.

Actually each checkout field has its own style (CSS class) depending on its position, there are 3 main classes:

Now we’ll make phone and email fields fullwidth with the code below.

add_filter( 'woocommerce_checkout_fields' , 'misha_checkout_fields_styling', 9999 );
 
function misha_checkout_fields_styling( $f ) {
 
	$f['billing']['billing_email']['class'][0] = 'form-row-wide';
	$f['billing']['billing_phone']['class'][0] = 'form-row-wide';
 
	return $f;
 
}

Finally:

You can make the WooCommerce checkout fields to be floated left or right, or make them fullwidth.

Change Labels and Placeholders

Below you can find the code that allows to change the label of the billing first name field and the placeholder of the order notes field.

add_filter( 'woocommerce_checkout_fields' , 'misha_labels_placeholders', 9999 );
 
function misha_labels_placeholders( $f ) {
 
	// first name can be changed with woocommerce_default_address_fields as well
	$f['billing']['billing_first_name']['label'] = 'Your mom calls you';
	$f['order']['order_comments']['placeholder'] = 'What\'s on your mind?';
 
	return $f;
 
}

And the result:

On this screenshot we have changed the label of the First name field and the placeholder of the Order Notes field.

Terms and Conditions Checkbox

And before you continue to the next step and begin creating this checkbox in the code, I want to show you a very simple and correct way to do it.

First — create your "Terms and Conditions" page in Pages > Add New.
Second — go to WooCommerce > Settings > Advanced and set the page there.

Simple and correct way to add Terms and Conditions checkbox to the checkout page.
WooCommerce > Settings > Advanced > Page Setup

That’s all – after you select the page there and save changes the checkbox will appear on your checkout page just before the "Place Order" button.

If you want to change "Terms and Conditions" text, check this guide.

Add Your Own Custom Checkout Fields

In this part of the post I will add two fields to the WooCommerce checkout form — a dropdown select just under the billing details and "Subscribe" checkbox to the order notes section. The first field will be a required field.

I will also try to describe this process in details.

First of all we should decide where we would like to place our new fields. And here is the choice:

I think everything is clear from the names of locations — it is also the name of the action hook, we will use below. The field locations are also mentioned here in the same order as in the template code.

These locations may not work for you just in one case — if WooCommerce default checkout templates: form-shipping.php and form-billing.php were overridden in the theme. In that case you can manually add the new fields to your theme files, /woocommerce/checkout directory.

// add fields
add_action( 'woocommerce_after_checkout_billing_form', 'misha_select_field' );
add_action( 'woocommerce_after_order_notes', 'misha_subscribe_checkbox' );
 
// save fields to order meta
add_action( 'woocommerce_checkout_update_order_meta', 'misha_save_what_we_added' );
 
// select
function misha_select_field( $checkout ){
 
	// you can also add some custom HTML here
 
	woocommerce_form_field( 'contactmethod', array(
		'type'          => 'select', // text, textarea, select, radio, checkbox, password, about custom validation a little later
		'required'	=> true, // actually this parameter just adds "*" to the field
		'class'         => array('misha-field', 'form-row-wide'), // array only, read more about classes and styling in the previous step
		'label'         => 'Preferred contact method',
		'label_class'   => 'misha-label', // sometimes you need to customize labels, both string and arrays are supported
		'options'	=> array( // options for <select> or <input type="radio" />
			''		=> 'Please select', // empty values means that field is not selected
			'By phone'	=> 'By phone', // 'value'=>'Name'
			'By email'	=> 'By email'
			)
		), $checkout->get_value( 'contactmethod' ) );
 
	// you can also add some custom HTML here
 
}
 
// checkbox
function misha_subscribe_checkbox( $checkout ) {
 
	woocommerce_form_field( 'subscribed', array(
		'type'	=> 'checkbox',
		'class'	=> array('misha-field form-row-wide'),
		'label'	=> ' Subscribe to our newsletter.',
		), $checkout->get_value( 'subscribed' ) );
 
}
 
// save field values
function misha_save_what_we_added( $order_id ){
 
	if( !empty( $_POST['contactmethod'] ) )
		update_post_meta( $order_id, 'contactmethod', sanitize_text_field( $_POST['contactmethod'] ) );
 
 
	if( !empty( $_POST['subscribed'] ) && $_POST['subscribed'] == 1 )
		update_post_meta( $order_id, 'subscribed', 1 );
 
}

The result:

It is simple enough to add your custom checkout fields, just do not forget to save the values to order meta.
After inserting the above code to your functions.php or to your custom plugin, the new fields will appear on the checkout page.

And after submitting the order you will see that the checkout field values appeared in the new order Custom Fields metabox.

We can save our custom checkout field values to the order meta. You can find it when edit the order.
If you can not find this metabox on the edit order page, turn it on in Screen Option tab which you can find on the top right part of the screen.

But what to do with the new checkout fields validation? required parameter of the woocommerce_form_field() just adds a * symbol near the field label, but do not process the validation.

Making fields required / Custom Validation / Creating Custom Error Notices

This small piece of code prints the notice if the preferred contact method has not been not selected. As I said before, for a custom checkout field it is not enough just to set required parameter to true to make it really required.

add_action('woocommerce_checkout_process', 'misha_check_if_selected');
 
function misha_check_if_selected() {
 
	// you can add any custom validations here
	if ( empty( $_POST['contactmethod'] ) )
		wc_add_notice( 'Please select your preferred contact method.', 'error' );
 
}

Look at the second parameter of the wp_add_notice function — it also supports "success" and "notice" notice types, but "error" is the only one what is relevant here.

Example of the WooCommerce error notice when custom required checkout fields are empty or not valid.

Ahaha, well, I supposed to add here much more interesting things about: integrating custom checkout fields into: View Order page, Thank you page, Edit Order Page (wp-admin), Emails… but I begin to think that in that case the post will be just a giant. So, I decided to continue in a separate posts. Subscribe below if you do not want to miss them.

More about WooCommerce Checkout

Misha Rudrastyh

Misha Rudrastyh

I love WordPress, WooCommerce and Gutenberg so much. 10 yrs of experience.

Need some custom developer help? Let me know

Follow Misha

Need some help with WooCommerce?

If you need some professional developer help, I will be happy to assist you.

Contact me Who I am?

Comments — 82

Leave a comment

php js HTML CSS Code

I will only use your personal information to contact you. Privacy Policy