Make phone field optional at WooCommerce checkout page

Do your customers find it hard to fill the form at your checkout page? Well, too bad, you just lost a customer. Many of the required fields at the WooCommerce checkout page are US-oriented. Many checkout pages often require filling in a phone number, but only accept a phone number formatted in a specific way, with a predefined number of digits. If your e-shop is not US-based, or if it is but you sell internationally, you might frustrate customers who cannot fill in their phone number and cannot proceed to finalize their order.
 

Getting ready

Before doing any code modifications, it’s always a good idea to take a full backup of our site and make sure that we have FTP access or access to cPanel or Plesk or other control panel with access to a file manager.

If you wonder what is the best way to add code snippets to your site, have a look at our previous article about safely adding PHP code.
 

1- Make the field optional in theme settings

Many WooCommerce oriented themes have a specific set of options that allow you to customize the fields at the checkout page. Storefront, created by Automattic (the same team behind WooCommerce and WordPress itself), lets you decide which fields you want to make mandatory and which ones not via the Customizer.

So, if you use Storefront, or a similar theme that allows for it, simply go to Appearance > Customize and then select the WooCommerce tab. Go to Checkout, and from the dropdown under “Phone Field” select “Optional”.
Screenshot - Storefront customizer

And, that’s it. Now all your customers will have the option to fill in the phone field only if they want to.
 

2- Completely hide phone field from both “Checkout” and “My account” pages

Making phone optional in the theme settings in Customizer has one drawback: Phone field is still visible (and required) in the “Addresses” tab in “My account”. So, if your customer needs to change something in their address, they will not be able to save unless they actually fill in the phone field:

Screenshot - "My account" page "Addresses" tab

In order to hide the phone field entirely from both “My account” and “Checkout” pages, we will add the following snippet:

// Remove billing phone (and set email field class to wide)
add_filter( 'woocommerce_billing_fields', 'remove_billing_phone_field', 20, 1 );
function remove_billing_phone_field($fields) {
    $fields ['billing_phone']['required'] = false; // To be sure "NOT required"
 
    $fields['billing_email']['class'] = array('form-row-wide'); // Make the field wide
 
    unset( $fields ['billing_phone'] ); // Remove billing phone field
    return $fields;
}
 
// Remove shipping phone (optional)
add_filter( 'woocommerce_shipping_fields', 'remove_shipping_phone_field', 20, 1 );
function remove_shipping_phone_field($fields) {
    $fields ['shipping_phone']['required'] = false; // To be sure "NOT required"
 
    unset( $fields ['shipping_phone'] ); // Remove shipping phone field
    return $fields;
}

The two filters we added will remove the phone field from both “Billing” and “Shipping” address and newly registered customers will not be asked to fill in the phone information in the Checkout page.
 

3- Make phone field optional on Checkout page based on shipping country

Here a somewhat more elaborate scenario: Let’s say your e-store has some shipping partners in your country and a few more countries. The shipping partner picks up the product from you and delivers it to your customer. However, they require a phone number, so that they can contact the customer about date and hour of delivery.

In this case, it would be very helpful to make phone field mandatory for the countries where the shipping company requires it and optional for other countries.

Here is a snippet that will allow you to do just that:

function defined_countries_for_phone_field(){
    return array( 'UK', 'BE', 'GE', 'IT', 'ES' );
}
 
// Remove "(optional)" from non required "Billing phone" field
add_filter( 'woocommerce_form_field' , 'remove_checkout_optional_fields_label', 10, 4 );
function remove_checkout_optional_fields_label( $field, $key, $args, $value ) {
 
    // Get the defined countries codes
    $countries = defined_countries_for_phone_field();
 
    // Get Customer shipping country
    $shipping_country = WC()->customer->get_shipping_country();
 
    // Only on checkout page and My account > Edit address for billing phone field
    if( 'billing_phone' === $key && ( ( is_wc_endpoint_url( 'edit-address' )
    && ! in_array($shipping_country, $countries) ) || is_checkout() ) ) {
        $optional = '&nbsp;<span class="optional">(' . esc_html__( 'optional', 'woocommerce' ) . ')</span>';
        $field = str_replace( $optional, '', $field );
    }
    return $field;
}
 
// Make the billing phone field optional (by default)
add_filter( 'woocommerce_billing_fields', 'filter_billing_phone_field', 10, 1 );
function filter_billing_phone_field( $fields ) {
 
    // Get the defined countries codes
    $countries = defined_countries_for_phone_field();
 
    // Get Customer shipping country
    $shipping_country = WC()->customer->get_shipping_country();
 
    // Only on checkout page and My account > Edit address
    if ( ( is_wc_endpoint_url( 'edit-address' )
    && ! in_array($shipping_country, $countries) ) || is_checkout() )
        $fields['billing_phone']['required'] = false;
 
    return $fields;
}
 
// Real time shipping country selection actions
add_action( 'woocommerce_after_order_notes', 'custom_checkout_scripts_and_fields', 10, 1 );
function custom_checkout_scripts_and_fields( $checkout ) {
    $required = esc_attr__( 'required', 'woocommerce' );
 
    // Get the defined countries codes
    $countries = defined_countries_for_phone_field();
 
    // Hidden field for the phone number validation
    echo '<input type="hidden"  name="billing_phone_check" id="billing_phone_check" value="0">';
    $countries_str = "'".implode( "', '", $countries )."'"; // Formatting countries for jQuery
    ?>
    <script type="text/javascript">
        (function($){
            var required = '<abbr class="required" title="<?php echo $required; ?>">*</abbr>',
                countries = [<?php echo $countries_str; ?>],
                location = $('#shipping_country option:selected').val(),
                phoneCheck = 'input#billing_phone_check',
                phoneField = '#billing_phone_field';
 
            function actionRequire( actionToDo='yes', selector='' ){
                if ( actionToDo == 'yes' ) {
                    $(selector).addClass("validate-required");
                    $(selector+' label').append(required);
                } else {
                    $(selector).removeClass("validate-required");
                    $(selector+' label > .required').remove();
                }
                $(selector).removeClass("woocommerce-validated");
                $(selector).removeClass("woocommerce-invalid woocommerce-invalid-required-field");
            }
 
            // Default value Once DOM is loaded (with a 300 ms delay)
            setTimeout( function(){
                actionRequire( 'no', phoneField );
                if( $.inArray( location, countries ) >= 0  && $(phoneCheck).val() == '0' ){
                    actionRequire( 'yes',phoneField );
                    $(phoneCheck).val('1');
                }
            }, 300 );
 
            // Live value
            $( 'form.checkout' ).on( 'change', '#shipping_country', function(){
                var location = $('#shipping_country option:selected').val();
                if ( $.inArray( location, countries ) >= 0 && $(phoneCheck).val() == 0 ) {
                    actionRequire( 'yes' ,phoneField );
                    $(phoneCheck).val('1');
                } else if ( $(phoneCheck).val() == 1 ) {
                    actionRequire( 'no' ,phoneField );
                    $(phoneCheck).val('0');
                }
            });
       })(jQuery);
        </script>
    <?php
}
 
// Phone number validation, when the field is required
add_action('woocommerce_checkout_process', 'billing_phone_field_process');
function billing_phone_field_process() {
    // Check if set, if its not set add an error.
    if ( ! $_POST['billing_phone'] && $_POST['billing_phone_check'] == '1' )
        wc_add_notice( __( 'Please enter a number phone.' ), 'error' );
}

With the code snippet above, if the customer wants the product shipped to one of the following countries: UK ('UK'), Belgium ('BE'), Germany ('GE'), Italy ('IT') or Spain ('ES'), the phone field will be mandatory. For every other shipping country, it will be optional.
 

Wrapping up

Requiring your customers to fill in a phone number in order to complete checkout can create problems, especially if you sell internationally and your customer is from a country where the phone number format is different than your own.

  • Making the phone field optional in the “Checkout” page by tweaking the theme settings in Customizer.
  • Removing the phone field from both “Checkout” and “My account” pages with a code snippet
  • Making phone field required in the “Checkout” page only if the customer’s shipping country is in a predefined list of countries.

Please let us know in the comments which method works for you better.

Leave a Reply