Reordering checkout fields in WooCommerce 3

For WooCommerce 3+ (update):

Since WooCommerce 3.0 checkout fields have changed a little bit so is not possible to reorder fields as before.

There is a new ‘priority’ argument that handle fields order, for checkout fields and my account fields as well.

Here is fully functional example for WooCommerce 3+:

// REORDERING CHECKOUT BILLING FIELDS (WOOCOMMERCE 3+)
add_filter( "woocommerce_checkout_fields", "reordering_checkout_fields", 15, 1 );
function reordering_checkout_fields( $fields ) {

    ## ---- 1. REORDERING BILLING FIELDS ---- ##

    // Set the order of the fields
    $billing_order = array(
        'billing_first_name',
        'billing_last_name',
        'billing_email',
        'billing_phone',
        'billing_company',
        'billing_address_1',
        'billing_address_2',
        'billing_postcode',
        'billing_city',
        'billing_state',
        'billing_country'
    );

    $count = 0;
    $priority = 10;

    // Updating the 'priority' argument
    foreach($billing_order as $field_name){
        $count++;
        $fields['billing'][$field_name]['priority'] = $count * $priority;
    }

    ## ---- 2. CHANGING SOME CLASSES FOR BILLING FIELDS ---- ##

    $fields['billing']['billing_email']['class'] = array('form-row-first');
    $fields['billing']['billing_phone']['class'] = array('form-row-last');

    $fields['billing']['billing_postcode']['class'] = array('form-row-first');
    $fields['billing']['billing_city']['class'] = array('form-row-last');
    
    ## ---- RETURN THE BILLING FIELDS CUSTOMIZED ---- ##

    return $fields;
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.


Before WooCommerce 3

I am not completely sure, but you there are some things that you can’t do like merging billing fields with account fields. If you want to do that is going to be much more complicated than what you are trying to do here. In that case you will need to rewrite/create some checkout templates…

Another thing is that billing_email and billing_phone are sharing the same line together with 'class' => 'form-row-first' and 'class' => 'form-row-last'. When not this class is define 'class' => 'form-row-wide'… So you are going to need overriding these 'class' too.

After that you dont need to use 'woocommerce_checkout_init' hook…
You can still use 'woocommerce_checkout_fields'.
Also you can merge all of them in one function this way:

/*
 * Creating, overriding and reordering custom fields.
 */
add_filter( "woocommerce_checkout_fields", "custom_override_checkout_fields", 11, 1 );
function custom_override_checkout_fields( $fields ) {

    // Creating 'billing_email2' field
    $fields['billing']['billing_email2'] = array(
        'type'          => 'text',
        'label'         => __( 'Confirm Email Address', 'woocommerce' ),
        'placeholder'   => _x( 'Confirm Email Address', 'placeholder', 'woocommerce' ),
        'required'      => true,
        'class'         => array('form-row-last'),
        'clear'         => true
    );

    // =======> I don't really know if you need this one  <========
    // it already exist (see in first reference link at bottom).

    // Creating 'account_password2' field 
    if ( get_option( 'woocommerce_registration_generate_password' ) == 'no' ) {
        $fields['account']['account_password2'] = array(
            'type'          => 'password',
            'label'         => __( 'Confirm password', 'woocommerce' ),
            'placeholder'   => _x( 'Confirm Password', 'placeholder', 'woocommerce' ),
            'required'      => true,
            'class'         => array('form-row-wide') //,
            // 'clear'         => true
        );
    }

    // Overriding existing billing_phone field 'class' property 
    $fields['billing']['billing_phone']['class'] = array('form-row-wide');


    // Reordering billing fields
    $order = array(
        "billing_first_name",
        "billing_last_name",
        "billing_email",
        "billing_email2",
        "billing_phone",
        "billing_company",
        "billing_address_1",
        "billing_address_2",
        "billing_postcode",
        "billing_country"
    );

    foreach($order as $field)
    {
        $ordered_fields[$field] = $fields["billing"][$field];
    }

    $fields["billing"] = $ordered_fields;

    return $fields;
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

As I have said before, I think that you can’t merge billing fields with account fields.
As 'account_password2' already exist if you refer to official documentation (see below in first reference link), you may not need to create it. You will have to test this and to fine tune it. But this is the way to do it.


References:

Leave a Comment