Rearranging WooCommerce Checkout Fields
To rearrange the woocommerce checkout fields which include any custom fields we will need to override form-billing.php by copying it out from the from the WooCommerce plugins directory – wp-content/plugins/woocommerce/templates/checkout to a directory under our theme wp-content/themes/yourtheme/woocommerce/checkout/. I have already explained this bit in Part 1 of this tutorial.
The following snippet worked for my setup of custom fields and the current WooCommerce version 3.0. There may be a better way to do this but with custom WooCommerce fields I couldn’t find another approach that worked. Compare the following to your custom fields and required field order to make the appropriate changes.
<div class="woocommerce-billing-fields">
<?php if ( wc_ship_to_billing_address_only() && WC()->cart->needs_shipping() ) : ?>
<h3><?php _e( 'Billing & Shipping', 'woocommerce' ); ?></h3>
<?php else : ?>
<h3><?php _e( 'Personal details', 'woocommerce' ); ?></h3>
<?php endif; ?>
<?php do_action( 'woocommerce_before_checkout_billing_form', $checkout ); ?>
<?php
//rearrange the checkout fields
$reordered_billing_fields = array(
"title",
"billing_first_name",
"billing_last_name",
"billing_address_1",
"billing_address_2",
"billing_address_3",
"billing_city",
"billing_country",
"billing_state",
"billing_postcode",
"billing_email",
"billing_phone",
"billing_tel_2",
"billing_company",
"billing_email_2",
"newsletter",
"receive_emails"
);
?>
<div class="woocommerce-billing-fields__field-wrapper">
//Commented out the default billing fields, and added our own loop below
<?php /* foreach ( $checkout->get_checkout_fields( 'billing' ) as $key => $field ) :
woocommerce_form_field( $key, $field, $checkout->get_value( $key ) );
endforeach; */ ?>
//Loop through the rearranged custom billing fields
<?php foreach ($reordered_billing_fields as $key) : ?>
<?php woocommerce_form_field( $key, $checkout->checkout_fields['billing'][$key], $checkout->get_value( $key ) ); ?>
<?php endforeach; ?>
</div>
<?php do_action( 'woocommerce_after_checkout_billing_form', $checkout ); ?>
</div>
Here’s an example of custom WooCommerce fields rearranged on the checkout page:

It looks like WooCommerce have added a priority array field in version WC version 3. Once the checkout loads, there is a javascript function which re-orders all of the fields. So to move the email field up, you would use the following function.
add_filter(‘woocommerce_checkout_fields’ , function($fields){
$fields[‘billing’][‘billing_email’][‘priority’] = 15;
return $fields;
});
Thanks, Mark! This is a much better solution. Mine’s a bit of a hack. I’ll try this out during my next update, and have the post modified.