Customize WooCommerce Address Fields Order

Here is a quick way to customize WooCommerce shipping and billing addresses fields order. Before providing you the code to reorder the fields, i’d like to explain how these fields are displayed. They are printed on many parts of WooCommerce: my account page, emails etc…

There are basically 4 existing functions to retrieve address fields, all located in classes/class-wc-order.php:

  • get_billing_address()
  • get_shipping_address()
  • get_formatted_billing_address()
  • get_formatted_shipping_address()

The functions that we need are get_formatted_billing_address() and get_formatted_shipping_address(). Both contain a specific filter that we can use to re-order fields:

  • woocommerce_order_formatted_billing_address
  • woocommerce_order_formatted_shipping_address

From these two filters, we can create custom functions that will define a custom order. To do so, we have to deal with WordPress add_filter() built-in function. The add_filter() function is a function that allows you to override specific parts of any kind of stuff within WordPress, or within any theme or plugin for WordPress. In our case the filter is applied on arrays. So, we need to create custom functions that will obviously returns arrays. Here is the snippet that will allow you to re-order billing fields. Please note that the code will apply these changes on all locations where the billing address is displayed.

From there, all you have to do is to change the order of the fields within the new array. And Boom! The magic appears. You can do the exact same thing with the shipping fields, simply adjust the filter name, and fields names. If you want to change both shipping fields and billing fields order, make sure you use two separate functions with different names. That may sound silly, but it’s not. Many people just copy and paste the same function twice in there functions.php, and of course that doesn’t work and break the website… So, just to make sure here is the code to re-order shipping fields:

And that’s it! I hope you liked it, and please feel free to discuss the code in the comments section!

15 responses to “Customize WooCommerce Address Fields Order”

  1. maxi

    Hello Remi, great post, i’ve been trying to get the information from a custom field in the database to the billing address for a while now but i just can’t make it work, i followed your instructions to the letter but i get the following error: Fatal error: Using $this when not in object context in…

    I just need to retrieve one field from the database, here’s what my functions.php looks like:

    add_filter( ‘woocommerce_order_formatted_billing_address’ , ‘cuit_pedido’ );
    function cuit_pedido() {
    $address = array(
    ‘billing_cuit’ => $this->billing_cuit
    );
    return $address;
    }

  2. EvitaJoseph

    Hi Remi , I’m so glad u’re out there. I’m also trying to change the font size of the product name on my wordpress woocommerce online retail store. Please how do i go about it.

  3. Thanks for the clear and useful explanation Rémi!

  4. […] notifying admins when a customer changes an address, and Remi Corson posted a helpful overview of how to customize the address fields on an […]

  5. web2sign

    Hi Remi…. I got an error on this… the $this is not defined.

    1. i dont think that this error message is linked to that code

  6. web2sign

    I mean this Fatal error: Using $this when not in object context

    1. bloodytom

      I’m getting the same error.

      1. Ok then , i need to check if it’s not a WC 2.1 related issue

  7. Wonderm00n

    Hi Remi,

    This does not work for several reasons:
    – $this is not being passed on to the function
    – $this is an array and not an object
    – but mainly because the format is actually done at ->countries->get_formatted_address() and not at ->get_formatted_billing_address()

    ->countries->get_formatted_address() then gets the address format from a defaults list, based on the country, located at ->get_address_formats() and that’s where you should get into.

    Also, this is defined by country. If you want to override the format for all countries (which you should not), you need to unset all the address_formats array entries and leave only the “default” one with your desired format.

    Here’s an example to change/set the Portuguese address format:


    add_filter('woocommerce_localisation_address_formats', 'my_pt_address_format');
    function my_pt_address_format($format) {
    //$format['default']="{name}\n{company}\n{address_1}\n{address_2}\n{city}\n{state}\n{postcode}\n{country}";
    $format['PT']="{company}\n{name}\n{address_1}\n{address_2}\n{city}\n{postcode}\n{state}\n{country}";
    return $format;
    }

  8. arunatmdinfomatics

    HI There, we are trying to get different fields while registration,like name , email id, pass, email etc. But when we are reaching my account page none of the data is visible in my account page.

    Also when we try to edit Shipping and billing details, we want to set default country to Australia and right now its – UK

    Please help

  9. ngshingne@yahoo.in

    Sir, i save custom field (billing_vat_number) to the table wp_usermeta. now i want to display on billing address page such as billing_first_name, billing_last_name, billing_company and billing_vat_number

    i used in function.php but no result shown
    add_filter( ‘woocommerce_order_formatted_billing_address’ , ‘company_vat’ );
    function company_vat() {
    $address = array(
    ‘billing_vat_number’ => $this->billing_vat_number
    );
    return $address;
    }

    can anybody mail me ngshingne@yahoo.in

  10. […] Dieses Tutorial zeigt dir, wie sich die Reihenfolge der Adressfelder im Bestellprozess ändern lässt. […]

  11. Mike

    Bonjour Remi,
    Merci pour ce filtre bien sympa qui me torture depuis 2 jours :)!
    J’ai créé un plugin simple pour pouvoir utiliser mondial relay, je pensai quand utilisant cette fonction l’adresse serai changée mais non. voici le code de ma fonction qui varie légèrement diffèrente de la votre.

    add_filter( ‘woocommerce_order_formatted_shipping_address’ , ‘woo_custom_order_formatted_shipping_address’,10,2 );

    function woo_custom_order_formatted_shipping_address($address, $wc_order) {

    $address_mr = get_post_meta( $wc_order->id, ‘_field_mondial_relay’);
    if($adresse_mr = true){
    $address = array(‘first_name’=> get_post_meta( $wc_order->id, ‘_field_mondial_relay’, true ),);
    return $address;
    }
    else{
    return false;
    }
    }

    Sa fonctionne bien, seulement les autres commandes ont une adresse de livraison vide , seul les commandes Mondial Relay ont leur adresse de livraison.
    J’aurai aimé savoir s’il était possible de poser une condition comme je l’ai fait sur ce filtre ?

    Dans tous les cas merci pour votre partage ! ce n’ai pas la 1ère fois que profite de votre savoir !
    Merci

    1. Hello, il faudrait créer une condition en amont du type:

      if( … ) {
      add_filter( ‘woocommerce_order_formatted_shipping_address’ , ‘woo_custom_order_formatted_shipping_address’,10,2 );
      }

      voir même mettre cette condition dans une fonction hookée sur une action

Leave a Reply