WooCommerce: Move / Reorder Checkout Fields (Email, Country, etc.)

We’ve already seen how to disable fields on the checkout page by using a simple snippet.

Given my ultimate goal of trying to do as much as possible without installing heavy-weight plugins, today we’ll take a look at how to move fields around inside the billing & shipping sections.

WooCommerce: move billing/shipping checkout fields around
WooCommerce: move billing/shipping checkout fields around

PHP Snippet: Move / Reorder Fields @ WooCommerce Checkout Page

WooCommerce 3.0 has added a “priority” field to each billing and shipping field. Now moving fields @ checkout is much easier!

 * @snippet       Move / ReOrder Fields @ Checkout Page
 * @how-to        Get CustomizeWoo.com FREE
 * @author        Rodolfo Melogli
 * @compatible    Woo 4.9.2
 * @community     https://businessbloomer.com/club/

add_filter( 'woocommerce_default_address_fields', 'bbloomer_reorder_checkout_fields' );

function bbloomer_reorder_checkout_fields( $fields ) {

	// default priorities:
	// 'first_name' - 10
	// 'last_name' - 20
	// 'company' - 30
	// 'country' - 40
	// 'address_1' - 50
	// 'address_2' - 60
	// 'city' - 70
	// 'state' - 80
	// 'postcode' - 90

  // e.g. move 'company' above 'first_name':
  // just assign priority less than 10
  $fields['company']['priority'] = 8;

  return $fields;

PHP Snippet: Move Email Field @ WooCommerce Checkout Page

I’ve written a full article on this feature alone: https://www.businessbloomer.com/woocommerce-move-email-field-to-top-checkout/ – enjoy!

Where to add custom code?

You should place custom PHP in functions.php and custom CSS in style.css of your child theme: where to place WooCommerce customization?

This code still works, unless you report otherwise. To exclude conflicts, temporarily switch to the Storefront theme, disable all plugins except WooCommerce, and test the snippet again: WooCommerce troubleshooting 101

Related content

  • WooCommerce: Add “Confirm Email Address” Field @ Checkout
    A correct email address is worth a thousand dollars, some ecommerce expert would say πŸ™‚ So, you don’t want your WooCommerce checkout visitors to mess up with that, do you? What about adding an “Email Verification” field? In this way, we can make sure they double check their entry – and also show an error […]
  • WooCommerce: How to Add a Custom Checkout Field
    Let’s imagine you want to add a custom checkout field (and not an additional billing or shipping field) on the WooCommerce Checkout page. For example, it might be a customer licence number – this has got nothing to do with billing and nothing to do with shipping. Ideally, this custom field could show above the […]
  • WooCommerce: Hide Checkout Fields if Virtual Product @ Cart
    If you sell downloadable/virtual products and need to simplify your WooCommerce checkout when such product type is in the Cart, you’ve come to the right place! Here’s a simple snippet, as well as a handy mini-plugin, that checks if there are only “virtual” products in the Cart and hides all the billing fields and order […]
  • WooCommerce: Add House Number Field @ Checkout
    A North European client told me they’re really strict about billing and shipping addresses over there. Couriers usually require a separate “House Number” in order to dispatch packages within those countries. This must be therefore placed on the checkout, BESIDE the “Address_1” field and made required. Also, it’s a good idea to make this show […]
  • WooCommerce: Display Required Field Errors “Inline” @ Checkout
    If you’re familiar with the upcoming Gutenberg editor, you’ll know there have been a million doubts in regard to accessibility. So, accessibility matters – and WooCommerce has a few issues as well. One interesting accessibility fix is the error notification system on the checkout page. Yes, the missing fields error show on top of the […]

Rodolfo Melogli

Business Bloomer Founder

Author, WooCommerce expert and WordCamp speaker, Rodolfo has worked as an independent WooCommerce freelancer since 2011. His goal is to help entrepreneurs and developers overcome their WooCommerce nightmares. Rodolfo loves travelling, chasing tennis & soccer balls and, of course, wood fired oven pizza. Follow @rmelogli

99 thoughts on “WooCommerce: Move / Reorder Checkout Fields (Email, Country, etc.)

  1. Hi,
    Using your snippet “as is” trying to reorder email field on top, I got an issue. The field was not reordered but duplicated.

    To fix that, I had to change the hook from ‘woocommerce_default_address_fields’ to ‘woocommerce_checkout_fields’.

    My working version of the snippet is then :

    add_filter( 'woocommerce_checkout_fields', 'bbloomer_reorder_checkout_fields' );
    function bbloomer_reorder_checkout_fields( $fields ) {
       // default priorities:
       // 'first_name' - 10
       // 'last_name' - 20
       // 'company' - 30
       // 'country' - 40
       // 'address_1' - 50
       // 'address_2' - 60
       // 'city' - 70
       // 'state' - 80
       // 'postcode' - 90
      // e.g. move 'company' above 'first_name':
      // just assign priority less than 10
        $fields['billing']['billing_email']['priority'] = 5;
        return $fields;
    1. Thanks for sharing!

  2. Dont works for me with the theme MARTFURY. I dont know if theme is incompatible with this snippet or the snippet are deprecated.

    1. Not sure, each theme is different. Does it work with Storefront or 2021?

  3. Not sure this is working in latest WP 5.5.x
    Added snippet and email textbox copied to top with no label..
    at bottom email textbox and label still shown I have screenshot if you need.

    Please advise


    1. Works for me. Please temporarily deactivate all plugins but WooCommerce and let me know if it works.

      1. I will setup a dev environment and then re-test.


        1. retested on techlivingreview.com a dev site with all plugins disabled. looks like an issue with the theme
          It is Kadence Pro. I disabled pro addon so free theme is running.

          Email txt box is copied to top but lable is not..


          1. That’s what I thought

  4. As pointed out by previous commentators, moving state and city before address doesn’t work. They are arranged properly in the output, but reordered from JavaScript.

    1. Ok thank you

  5. hi πŸ™‚
    using the following code with wc v-3.9.2:

    add_filter( ‘woocommerce_checkout_fields’, ‘wisite_checkout_fields_order’ );
    function wisite_checkout_fields_order( $checkout_fields ) {
    $checkout_fields[‘billing’][‘billing_city’][‘priority’] = 50;
    $checkout_fields[‘billing’][‘billing_address_1’][‘priority’] = 60;
    $checkout_fields[‘billing’][‘billing_address_2’][‘priority’] = 70;
    return $checkout_fields;

    it is working, in a sense that the markup changes (each field gets the proper ‘data-priority’ attribute value)
    but there seem to be a js process running after the page is loaded that rearranges fields back…
    Appreciate any help / thoughts on this…

    1. Maybe you need to change filter and use “default fields” instead. I don’t remember the actual name of the filter, try to look through the comments please

  6. Hi Rodolfo,

    is there a way to use this php snipet to add a field (form table) with new input (SSN) in different priorities to the billing fields? I already have it at the bottom of the check out page but would like to move it up below the name field.

    Thank you for you time and all your great tips.

    1. Hermann, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  7. Hi Rodolfo,
    I guess I do not fully understand how filters work and perhaps it’s me who make some mistakes, but here’s a strange case: sometimes the filter is called more than once during the same event or ‘transaction’. On a test website it was called twice and on the live website 4 times, and on the same second. The filter was, for instance, woocommerce_email_recipient_new_order.
    The fix seems to remove the filter after the first call, as they suggest here: https://wordpress.stackexchange.com/questions/225721/hook-added-to-the-content-seems-to-be-called-multiple-times

    Have you ever seen it? How do you explain that?

    1. Hi Franco πŸ™‚ Is this related to this snippet or you mean in general?

  8. Amazing collection of tips you’ve got here. May I ask how you are showing the order summary and payment details to the right of the billing details?

    1. Thanks Chris. That’s just a little bit of CSS there

  9. Hi Rodolfo!
    I just updated my WooCommerce from 3.3.5 to 3.5.3. In the previous version I used your code snippet (thanks btw!) to order my Shipping fields in Checkout, but this latest WC update has messed it all up. They don’t even appear to use the default priorities you list.
    You mentioned that you had put a ticket in to WC, did they ever issue a fix/patch for this issue? Will our old code still work or are there modifications to be made?

    1. Hey Holly, thanks for your comment! I think it was solved by https://github.com/woocommerce/woocommerce/pull/21763, so it should work… alternatively you could try using the “woocommerce_checkout_fields” filter, not sure. Send me an update

    2. I can confirm `woocommerce_checkout_fields` works in WC 3.5.3

      1. Excellent!

  10. Hey Rodolfo!

    Not sure what I’m doing wrong but the field override only happens when the country is changed in checkout.
    For example:

         function bbloomer_move_checkout_email_field( $address_fields ) {
             $address_fields['billing_email']['priority'] = 1;
             return $address_fields;
         add_filter( 'woocommerce_billing_fields', 'bbloomer_move_checkout_email_field', 10 , 1 );

    I’m using woocommerce 3.5.0

    1. Yes, Emina, thanks for that – see previous comment πŸ™‚

  11. Hi there, just wanted to let you know that this code has stopped working since the recent version of Woocommerce.


    1. Hey Moe, thanks for your comment! Yes, it seems there is a bug with WooCommerce – I just posted the issue here: https://github.com/woocommerce/woocommerce/issues/21751

  12. Hello Rodolfo how are you? I have a problem, the fields that are not by default do not add them to me. What solution could I do? Add a new field to upload a file and I have not been able to reorder it in any way. I await your answer friend! Thanks for your time

    1. Hello Jose, thanks so much for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding! ~R

  13. Hi there,

    Thank you for the code btw – it’s helped me out a lot!

    I’m still trying figure out how to add the account sections to the top, i.e username and password.

    Can you use the same layout for the account section as shown above?

    1. Hey Max – thanks so much for your comment! I’m not 100% sure, but the account fields might be separate from the billing ones so they could only moved in bulk to the very top of the checkout. Try studying the checkout-form template and see if you can spot something there πŸ™‚

  14. Hi Rodolfo, thank, of course I understand, but do you maybe know the hook that I would need to use for my filter? I will try to figure out how to do it myself…

    1. Hey Kristina! You should look into the form-edit-address.php file and backtrace to see what filter you should be using πŸ™‚

  15. hello Rodolfo,
    I have reordered und changed/unset a few of my billing and shipping fields on the checkout page. Thank you for your snippet! However, on the “My Account” page that every registered or just signed up user has(to add or edit his addresses), you can still the shipping and billing fields unchanged. Is there a way to also change these?

    thank you!

    1. Hello Maria, thanks for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R

  16. Hi Rudolfo. Just used the top code to put the country field at the top of the form. Woocommerce and wordpress 4.9. worked perfectly.

  17. Is there a way to move the Order Comments (order_comments) field on the Checkout page to the Cart page?
    Reason is because if people use PayPal or Amazon Pay on the Cart page to pay (thus skipping the form), they will not get to the Checkout page at all to leave note/comments…

    1. Vuster, thanks so much for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R

  18. Dear Rodolfo

    I used this code that you mentioned above but unfortunately, Address_1 always locate above city meanwhile I set priority 42 for city. Can you help me about that?

    it’s the code that I have used:

    $fields[‘state’][‘priority’] = 41;
    $fields[‘city’][‘priority’] = 42;

    Many thanks for your awesome article

    1. Mehdi, thanks so much for your comment! Unfortunately this is custom troubleshooting work and I cannot help here via the blog comments. Thanks a lot for your understanding! ~R

  19. Hello! Is it possible in woocommerce to display Shipping methods first on the checkout page?

    And based on options (local pickup / shipping), we can control which fields to be displayed for billing address? As I dont want to force my customer to enter full address if he is opting for Local Pickup.

    1. Hey Pyatachok, thanks so much for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here on the blog. Thanks a lot for your understanding! ~R

  20. This works only for default flieds.
    1. add a custom field to billing.

    /* Adauga CNP*/
    add_filter( 'woocommerce_checkout_fields' , 'cod_numeric_personal' );
    function cod_numeric_personal( $fields ) {
         $fields['billing']['billing_cnp'] = array(
         'label'     => __('CNP', 'woocommerce'),
        'placeholder'   => _x('CNP', 'placeholder', 'woocommerce'),
        'required'  => false,
        'class'     => array('fizica form-row-wide'),
        'clear'     => true
         return $fields;

    2. reorder fields WC 3.0

    add_filter( 'woocommerce_default_address_fields', 'bbloomer_move_checkout_fields_woo_3' );
    function bbloomer_move_checkout_fields_woo_3( $fields ) {
     $fields['billing_cnp']['priority'] = 8;
      return $fields;

    The second snipped adds a new field without label, first position of billing

    1. I think i figured out.
      If you want to add a custom field to billing and reorder it

      function wc_imod_billing_fields( $address_fields ) {
              $address_fields['billing_cnp']['placeholder'] = 'CNP';
              $address_fields['billing_cnp']['label'] = 'CNP';
      	$address_fields['billing_cnp']['required'] = true;
      	$address_fields['billing_cnp']['priority'] = 22;
          return $address_fields;
      add_filter( 'woocommerce_billing_fields', 'wc_imod_billing_fields', 10, 1 ); 
      1. Thanks for your valuable feedback Stefan!

  21. Hey guys.

    Is there an easy way to display the billiing address fields in Shipping session?
    I’m using a multistep plugin, and I wanted my customer to fill address info in second step, which will be the “shipping” session.
    I don’t really ship stuff, as I only sell virtual products.

    I have the Extra Checkout Fields plugin, if I just Disable the fields in Billing and recreate them in Shipping, with same name and all, will it behave properly?



    1. Hey Diego, thanks for your comment! If you don’t ship stuff, you should disable shipping from the General settings: https://docs.woocommerce.com/document/configuring-woocommerce-settings/#section-1

  22. Hi there. That’s a really straightforward function. It helped me a lot! Thanks.

    However, it seems impossible to me to reorder the billing_postcode | shipping_postcode fields, which I’d like to place right before the country select field as follows:

    $fields2['billing']['billing_postcode'] = $fields['billing']['billing_postcode'];
    $fields2['billing']['billing_country'] = $fields['billing']['billing_country'];

    It seems WooCommerce 2.6.x will reorder the billing_postcode | shipping_postcode fields according to the locale as set in `wc-address-i18n.js` https://github.com/woocommerce/woocommerce/blob/release/2.6/assets/js/frontend/address-i18n.js#L45

    I’d really I’m not sure how to solve this issue. I’d really appreciate any inputs regarding an alternative method in order to achieve that.

    Best wishes,

    1. Hey Adriano! Hopefully you’re using Woo 3.0.6 by now? πŸ˜€

  23. Hi Rodolfo,
    Great work and thank you for updating and helping everyone out so regularly. πŸ™‚

    This might be a dumb question from a novice (me), but why in the Woocommerce 3.0.4 snippet at the top is there no ’email’ or ‘phone’ fields?
    Did I miss it mentioned somewhere else?
    I would like to move my email and phone fields as they are appearing last in the field order.

    Thank you again.

    1. In addition….
      I tried the 3.0.4 snippet with the field names ’email’ and ‘phone’ and set their respective priorities and they didn’t move. The other fields listed in the snippet however moved ok.

      1. Hey Peter, thanks for your comments! Email and Phone are generated via a different function so they will require a different filter – do a search through the PHP to see if you can find it πŸ™‚

          1. Thanks Rodolfo and Maxim.
            That did the trick.

  24. Hi Rodolfo,

    Thanks for the snippets, they helps me very well!

    I think you need add example for billing fields to Woo 3.x examples

    function ld_wc_filter_billing_fields( $address_fields ) {
        $address_fields['billing_email']['priority'] = 30;
        $address_fields['billing_phone']['required'] = false;
        $address_fields['billing_phone']['priority'] = 98;
        return $address_fields;
    add_filter( 'woocommerce_billing_fields', 'ld_wc_filter_billing_fields', 10, 1 );
    1. Thank you so much Maxim!

    2. Will this make Email and Phone number on top ?

    3. Was able to bring on top of first and last name
      here is actual code
      function ld_wc_filter_billing_fields( $address_fields ) {
      $address_fields[‘billing_email’][‘priority’] = 9;

      $address_fields[‘billing_phone’][‘required’] = false;
      $address_fields[‘billing_phone’][‘priority’] = 8;
      return $address_fields;
      add_filter( ‘woocommerce_billing_fields’, ‘ld_wc_filter_billing_fields’, 10, 1 );

      1. Thanks Kumar πŸ™‚

  25. Hi Rodolfo,

    I am simply wanting to add email address field in billing to go to the very top of the form fields. I don’t see email as a customisable option in your code above for 3.0? Do I just add the field in there like the others and assign 8 (anything lower than 10)? Very new to this. I do have a child theme and have the functions php window open… I also want to know how to make phone field an optional field, not a required field?

    Much thanks!


  26. Hi Rodolfo,
    unfortunately the snippet is not working anymore after the newest update of Woocommerce. Do you know what needs to be changed?


    1. Hey Patrick, well spotted! I did some research and in fact I found this in the forums: https://wordpress.org/support/topic/reordering-checkout-fields-doesnt-work-anymore-on-3-0-4/.

      So, I took some time to update this article, and now you’ve got the solution at the top of the page πŸ™‚


      1. Hi Rodolfo,
        thank you so much!
        May I also ask: I need to not only reorder the fields, but also change required to non-required, change label etc…so would I need to add for example:

        add_filter( 'woocommerce_default_address_fields', 'bbloomer_move_checkout_fields_woo_3' );
        function bbloomer_move_checkout_fields_woo_3( $fields ) {
          $fields['company']['priority'] = 8;
          $fields['company']['required'] =  true;
          $fields['billing_phone']['label'] = 'Telephone';
          return $fields;

        Is this correct?
        Thank you!

          1. Hey Rodolfo,
            thanks, but if I compare the two they are actually the same??


            1. Ah πŸ™‚ You’re right! By the way, have you tried your snippet yet?

              1. Yes, it’s working, thank you so much! I really appreciate it!

  27. Hi Rodolfo,

    Long time no see. I think we talk couple years ago. πŸ™‚

    I want to move custom fields defined by one plugin to “woocommerce_checkout_order_review”. Is it possible with a snippet? Thanks.

    1. Hey Robert πŸ™‚ Yes, this is possible, and it will depend on your custom plugin, so unfortunately I don’t have a “universal” snippet that can help. Thank you!

  28. hi
    some of the fields eg first name are half off the left margin on the checkout page any ideas guys


    1. Hey Phil thanks for your comment! Do you have a screenshot? Is this related to my snippet?

  29. Hi Rodolfo,

    Great snippet! Thanx!
    On my webshop every order is “shipped to a different address”, so I would like to hide the “ship to different address” checkbox.
    Do you know how I can fix this?

    Kind regards,


  30. Hello Rodolfo,
    I have learned many great snippets from you and wanted to thank you for that. I also have a question and was wondering if you could help: I need to change the layout of the checkout page. I need to move the payment options with the “agree to terms&conditions” checkbox ABOVE the order-review table. The Order button should stay at the bottom though.
    I know this has to be done by overriding the template in a child theme, but I just can’t get this to work as the payment option box is combined together with the order-reviwe table in the template. Maybe there is an option for this via a function, but I am not very well versed in PHP…

    I would love to hear back from you, many thanks!

    1. Thanks very much for your comment Felix! Have you tried watching my tutorial at https://businessbloomer.com/customize-checkout-page-woocommerce? That should help you a little πŸ™‚

      1. Hi Rodolfo,
        thank you, but I am really not much further πŸ™ I know I can remove the payment box with

        remove_action( ‘woocommerce_checkout_order_review’, ‘woocommerce_checkout_payment’, 20 );

        and add it somewhere else, but this also removes the terms&condition checkbox as well as the order button, which I want to keep underneath the order-review table

        1. Hey Felix, yes, of course you remove the whole section with that remove_action, so it’s really not the best thing to do in this case. Maybe you should use the template override that I don’t particularly like: https://docs.woocommerce.com/document/template-structure/

          1. Hi Rodolfo,
            yes, liike I mentioned I have tried to get this to work but every time I override these templates I am getting a white screen. I can’t figure out what I need to change in these templates…

            1. Strange, it works on my test site πŸ™‚ Are you pasting this in your functions.php? And when you get a white screen, what error is displayed if you enable WP_DEBUG?

              1. Rodolfo, I am not talinkg about the remove action that I mentioned above. That one is working, but like I said my goal is t o move the payment box WITHOUT the order button ON TOP of the order review table. The terms checkbox should be ON TOP of the paymant box, so that the layout is the following:
                1. Billing address
                2. Shipping address
                3. Terms checkbox
                4. Payment options box
                5. order-review table
                6. order button

                I have tried removing certain parts in the checkout templates and adding them in other ones, but I can’t get it to work like I want to πŸ™

                1. Hey Felix, thanks so much for your follow-up! Sorry that you haven’t been successful at the task – unfortunately this is custom work and I cannot provide a complementary solution here on the blog. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding! ~R

  31. Hello im trying to add a subtitle under the Country lable.
    in the checkout page.

    billing country

    something like this:
    * Country
    bla bla bla
    (Select box)

    how can i do this ? πŸ™‚

    1. Hey Itay, thanks for your comment πŸ™‚ It is a bit off topic though! You should use a checkout filter to edit the label of the field billing_country. You can find more info here: https://docs.woocommerce.com/document/tutorial-customising-checkout-fields-using-actions-and-filters/#section-2

  32. Great tutorial! Thank you. Just one thing… when adding this to functions.php it makes the “Order Comments” field disappear.

    I tried adding the following, but it didn’t work:

    $fields2['order']['order_comments']		= $fields['order']['order_comments']

    Any help would be much appreciated.

    1. Gonzalo, thank you so much for your comment (also – I will be visiting Peru soon!). This is pretty strange actually, I’ve tried it and you’re right, it doesn’t work. I’m launching my course tomorrow so maybe I’ll take a look at this next week πŸ™‚ Thank you!

  33. Is it possible user login in my account and reorder same product if yes then how can possible

    1. Hey Abhishek, thanks for your comment! I’m afraid I don’t understand what you’re looking for here – can you maybe provide a screenshot? Thanks πŸ™‚

      1. Hi Rodolfo
        Actually my concern that when user login in WooCommerce account he will find all the old order but in this table he can’t reorder the same product. So need that is reorder the same product is it possible in woocommerce

        1. Hey Abhishek, really sorry but I’m not sure I get what you need. This snippet is to reorder fields on the checkout, no matter if the user is logged in or not. Sorry πŸ™‚

  34. Hi Rodolfo, your are the best woocommerce teacher & development in this world. Amaizing, I love your tutorials. Please I want to move the order & payment info under shipping, on the left column, because the page it is too large and I think itΒ΄s better to see all at the first view. Sorry about my english.
    Thank you very much

    1. Hey Fabiola, thanks for your comment – your English is perfect! If you want to move order and payment info on the left, some custom PHP work will be needed. This is not a great idea as overriding a full template means you will need to re-do the job every time WooCommerce releases a big update.

      Other than that, take a look at the form-checkout.PHP file under woocommerce/templates/checkout, and then follow this official guide by WooCommerce to override it.

      Let me know πŸ™‚

  35. Hi Rodolfo,

    How do you move the ‘your order’ section to the right?

    1. Hello Julian, and thanks for your comment πŸ™‚ Do you mean you want to move the order & payment info under shipping, on the right column? May I ask why?

  36. You are an incredible resource! Thank you so much for sharing your expertise with us. It is much appreciated!

    1. Thank you! I truly appreciate your feedback πŸ™‚

Questions? Feedback? Customization? Leave your comment now!

If you are writing code, please wrap it like so: [php]code_here[/php]. Failure to complying with this, as well as going off topic or not using the English language will result in comment disapproval. You should expect a reply in about 2 weeks - this is a popular blog but I need to get paid work done first. Please consider joining the Business Bloomer Club to get quick WooCommerce support. Thank you!

Your email address will not be published. Required fields are marked *