• Skip to main content
  • Skip to primary sidebar
  • About
  • Contact
  • Resources
  • Blog
    • Easy Digital Downloads
    • General
    • Genesis Framework
    • jQuery/JavaScript
    • Project Management
    • WordPress Functions
    • WordPress Plugin Development
  • Army Lessons

Scott DeLuzio

WordPress Development Tutorials

How to Edit WooCommerce Checkout Fields

April 11, 2014 Scott DeLuzio 143 Comments

Edit WooCommerce Checkout FieldsWooCommerce is a great free plugin for WordPress that lets you transform your humble blog into a full-fledged e-commerce site. For most shops running WooCommerce as their shopping cart platform, the default checkout form fields are more than enough to get their customer’s orders processed. There are times though when someone might want to edit WooCommerce checkout fields.

Note: This tutorial assumes that you have some knowledge of functions and filters. If you do not, it is not advisable to continue on your own.

Custom code shown below should be copied into your child theme’s functions.php file, or a site specific plugin.

Don’t want to mess with code?

You can easily add custom fields to WooCommerce Checkout and edit existing fields with Conditional Woo Checkout Field Pro. Get Conditional Woo Checkout Field Pro

Edit WooCommerce Checkout Fields

I recently had a client who needed to edit WooCommerce checkout fields to change the label and placeholder text on the order comments box, as well as make the phone number, not a required field. Adding a simple function to their child theme’s functions.php file allowed me to achieve these results.

// WooCommerce Checkout Fields Hook
add_filter( 'woocommerce_checkout_fields' , 'custom_wc_checkout_fields' );
// Change order comments placeholder and label, and set billing phone number to not required.
function custom_wc_checkout_fields( $fields ) {
    $fields['order']['order_comments']['placeholder'] = 'Enter your placeholder text here.';
    $fields['order']['order_comments']['label'] = 'Enter your label here.';
    $fields['billing']['billing_phone']['required'] = false;
    return $fields;
}

// WooCommerce Checkout Fields Hook add_filter( 'woocommerce_checkout_fields' , 'custom_wc_checkout_fields' ); // Change order comments placeholder and label, and set billing phone number to not required. function custom_wc_checkout_fields( $fields ) { $fields['order']['order_comments']['placeholder'] = 'Enter your placeholder text here.'; $fields['order']['order_comments']['label'] = 'Enter your label here.'; $fields['billing']['billing_phone']['required'] = false; return $fields; }

If you instead wanted to remove the billing phone field completely from the checkout screen rather than simply making it optional, you could use the following code in your function:

unset($fields['billing']['billing_phone']);

unset($fields['billing']['billing_phone']);

Those fields aren’t the only WooCommerce checkout fields that can be customized. The following is a list of all the checkout fields that can be customized.

  • [‘billing’][‘billing_first_name’]
  • [‘billing’][‘billing_last_name’]
  • [‘billing’][‘billing_company’]
  • [‘billing’][‘billing_address_1’]
  • [‘billing’][‘billing_address_2’]
  • [‘billing’][‘billing_city’]
  • [‘billing’][‘billing_postcode’]
  • [‘billing’][‘billing_country’]
  • [‘billing’][‘billing_state’]
  • [‘billing’][‘billing_email’]
  • [‘billing’][‘billing_phone’]
  • [‘shipping’][‘shipping_first_name’]
  • [‘shipping’][‘shipping_last_name’]
  • [‘shipping’][‘shipping_company’]
  • [‘shipping’][‘shipping_address_1’]
  • [‘shipping’][‘shipping_address_2’]
  • [‘shipping’][‘shipping_city’]
  • [‘shipping’][‘shipping_postcode’]
  • [‘shipping’][‘shipping_country’]
  • [‘shipping’][‘shipping_state’]
  • [‘account’][‘account_username’]
  • [‘account’][‘account_password’]
  • [‘account’][‘account_password-2’]
  • [‘order’][‘order_comments’]

Each of the above fields can be customized with the following properties.

  • [‘type’] – This changes what type of field you are displaying. Valid types are text, textarea, password, or select.
  • [‘label’] – This is the text that indicates to the customer what to enter into the field. Note this is not the “placeholder” text that is shown in the field before the customer enters their information.
  • [‘placeholder’] – This is the text that occupies the text box before the customer enters their information. This text “disappears” after the customer clicks in the field and begins typing. This placeholder is useful when you want to give a sample of the information you are looking for from your customer.
  • [‘class’] – The class for the input.
  • [‘required’] – This value can be either true (if the field is required) or false (if the field is not required). You can see how this is used in the example above for the billing phone field.
  • [‘clear’] – This will apply a clear fix to the field or label it is set on. Valid values are true or false.
  • [‘label_class’] – Allows you do define a custom class for the label element it is set for.
  • [‘options’] – Allows you to set an array of options for select boxes.

Using the above information, you have complete control to edit WooCommerce checkout fields however you need.

Have you edited any checkout fields in your WooCommerce shop? Share what you did in the comments.

WooCommerce, WordPress Plugin Development Customize, e-Commerce, WooCommerce

Reader Interactions

Comments

  1. Romain says

    May 22, 2014 at 11:58 pm

    Hello,
    First thank you very much for this tutorial !
    I would like to display the post code and the city on the same line in my billing and shipping forms.
    I can edit the label and the input of each field, but I don’t know how to edit the class of the p tag which contain the label and the input.
    Do you have any idea ?
    Many thanks,
    Romain

    Reply
    • Scott says

      May 23, 2014 at 8:58 am

      I’m assuming you want to have the post code and city boxes on the same line on the checkout fields (that the customer fills out) like this:
      Address 1
      Address 2
      City Post Code
      State
      If that is the case, I believe you will need to change the class of the city from class="form-row form-row-wide address-field" to class="form-row form-row-first address-field". The post code field should be OK as is, but just in case it should be class="form-row form-row-last address-field" (note there may be additional class elements to add if there is validation required, such as validate-required validate-postcode woocommerce-invalid woocommerce-invalid-required-field, etc.)
      This can be done by adding a class for each field like this: $fields['billing']['billing_city']['class'] = 'form-row form-row-first address-field'; or $fields['billing']['billing_postcode']['class'] = 'form-row form-row-last address-field';. Use the lists above as a guide for which fields can go in between the [”] in the code. To determine what class is being used on those fields right now, right click on the field in your checkout page and select “Inspect Element” from the menu. It should open a smaller window at the bottom of your browser that will show that field’s source code. If your browser doesn’t have that option, select “View Source” and search for the form field you are looking for.
      To reorder the fields, you can use something like this:
      add_filter( 'woocommerce_order_formatted_billing_address' , 'reorder_billing_address' );
      function reorder_billing_address() {

      $address = array(
      'first_name' => $this->billing_first_name,
      'last_name' => $this->billing_last_name,
      'company' => $this->billing_company,
      'address_1' => $this->billing_address_1,
      'address_2' => $this->billing_address_2,
      'city' => $this->billing_city,
      'postcode' => $this->billing_postcode,
      'state' => $this->billing_state,
      'country' => $this->billing_country
      );

      return $address;

      }

      I believe that will get you where you want to be.

      Reply
      • Lawrie says

        August 27, 2014 at 11:38 am

        Thanks for this – really helpful. However, it’s worth noting that the [‘class’] is actually an array element, so rewriting it as a string will result in a fatal error. Creating/modifying it as an array works perfectly:


        $fields['billing']['billing_first_name']['class'] = array('box', 'alignleft');

        Note that this will append these classes to the existing ones, rather than flat-our replace them.

        Reply
        • peter says

          September 30, 2014 at 6:39 am

          how can I remove a class? I want to set 2 fields on the same line.
          I added the “form-row-first” class but I can’t remove the “form-row-wide” class.

          Reply
        • navneet kumar says

          March 17, 2015 at 6:52 am

          how can i make a custom checkout form with all the fields changed?
          do i need to put extra validation on all these fields. I have used following codes to solve this. but after submitting it does not go to the thankyou page.
          ”

          Internetbutik

          Skicka till:
          * = Obligatoriska fält
          cart->get_checkout_url() ); ?>
          <form name="checkout" method="post" class="checkout woocommerce-checkout" action="” enctype=”multipart/form-data”>

          checkout_fields ) > 0 ) : ?>

          Kundnummer:

          * Namn:

          Företag:

          * Leverans – Adress:

          * Postnummer:

          * Land

          Fakturering – Adress:

          Postnummer

          Postort:

          Land:

          * E-post:

          Mobiltelefon:

          Telefon:

          Meddelande:

          “

          Reply
          • Scott says

            March 17, 2015 at 10:10 am

            Navneet,
            To be honest, the code you listed is in a language I do not understand, but it seems as if it will not do anything to change the checkout fields as-is.

            I would suggest that you take a look at the Conditional Woo Checkout Field Pro plugin, which will allow you to have full control over the checkout form. You can add new checkout fields that only show up if a certain product (or products) are in the customer’s cart, and allows you to edit all of the default checkout fields.

            I hope this helps.

      • Jay says

        June 8, 2015 at 9:23 pm

        Hey Scott, thanks for being so helpful! Hopefully you can help me as well, I have tried using your code to re-order billing address fields, basically I am required to move the zip code above city. However after applying your filter I don’t get any changes. Perhaps something has changed in newer versions of woocommerce. Any ideas? Thanks in advance!
        J

        Reply
  2. John says

    June 23, 2014 at 8:44 pm

    Hi there,

    Thanks for this awesome tutorial!

    But I need some help if you can.

    So I’m trying to change “Town / City” to “Suburb”.

    Here is the code what I placed to function.php:

    `// Hook in
    add_filter( ‘woocommerce_checkout_fields’ , ‘custom_override_checkout_fields’ );

    // Our hooked in function – $fields is passed via the filter!
    function custom_override_checkout_fields( $fields ) {
    $fields[‘billing’][‘billing_city’][‘placeholder’] = ‘Suburb’;
    $fields[‘billing’][‘billing_city’][‘label’] = ‘Suburb’;
    return $fields;
    }`

    It doesn’t want to work  I noticed something when I reload the page I can see it changed to “Suburb” after a few second change it back to “Town / City”

    Did I miss something? Can you help me where?

    Thanks for your help.

    Reply
    • Scott says

      June 24, 2014 at 9:29 am

      John,
      I copied and pasted exactly what you posted in your comment into a test site’s functions.php file and it worked just like you wanted it to.
      I also clicked through to the URL you posted with your comment, which I’m assuming is the site you are trying to get this to work on. Went through and added something to the cart and the checkout page seems to be showing Suburb in both the label and placeholder spots in place of Town/City.
      Try clearing your browser’s cache or give it a shot on another browser/computer to see it working. Also, if you have a plugin that caches your pages such as W3 Total Cache, Wordfence (there’s a caching option in the settings), WP Super Cache, etc. try clearing the plugin’s cache.
      Let me know if you need any other help.
      Scott

      Reply
      • John says

        July 1, 2014 at 4:47 pm

        It worked because I changed it in one of the Woocommerce file but unfortunately that isn’t an option because every time Woocommerce gets a new update after that all the changes gone. Now I copied the code again it does the same thing. When I refresh the page I can see the Suburb but after a few sec change back to Town/City.
        I leave it now to see yourself and I don’t use any of cache plugin I also cleaned the browser no changes.

        Thanks
        John

        Reply
        • Scott says

          July 1, 2014 at 4:53 pm

          I’d be happy to take a look at this for you to get a permanent solution in place. Check out http://oizuled.com/wpservices/troubleshoot-wordpress-errors/ if you would like me to take a look.
          Thanks,
          Scott

          Reply
        • John says

          July 1, 2014 at 4:58 pm

          Sorry my bad. It seems to be working now. Thanks for your help. 🙂

          Reply
          • Ben Su says

            August 8, 2017 at 12:22 pm

            How to solve it?

          • Gal says

            January 3, 2018 at 8:23 am

            hi getting the same problem. how did you solve it???

          • Gopu says

            February 15, 2018 at 11:46 pm

            Hi,

            In specific cases you need to use the woocommerce_default_address_fields filter. This filter is applied to all billing and shipping default fields:

            country
            first_name
            last_name
            company
            address_1
            address_2
            city
            state
            postcode
            For example, to make the lable of ‘city’ field :

            // Hook in
            add_filter( ‘woocommerce_default_address_fields’ , ‘custom_override_default_address_fields’ );

            // Our hooked in function – $address_fields is passed via the filter!
            function custom_override_default_address_fields( $address_fields ) {
            $address_fields[‘city’][‘label’] = false;

            return $address_fields;
            }

      • Anne says

        July 28, 2015 at 10:10 am

        Hi Joe,
        Great tutorial! I’m having a similar issue with John and mine doesn’t seem to work. I’m trying to change the type of the shipping state field to a select and the label to State. When the page is reloading, I see the changes but it reverts when it has fully loaded. Here’s the code I used:
        function custom_override_checkout_fields( $fields ) {
        $fields[‘shipping’][‘shipping_state’][‘label’] = ‘State’;
        $fields[‘shipping’][‘shipping_state’][‘type’] = ‘select’;
        $fields[‘shipping’][‘shipping_state’][‘options’] = array(‘state_1’ => ‘A’, ‘state_2’ => ‘B’,
        ‘state_3’ => ‘C’);
        return $fields;
        }
        add_filter( ‘woocommerce_checkout_fields’ , ‘custom_override_checkout_fields’ );

        Any help would be great.

        Reply
        • Mamun says

          May 10, 2016 at 3:33 pm

          Having the similar problem here too. Any update?
          Thank you for a nice article

          Reply
        • leah says

          June 22, 2023 at 5:32 am

          hello i have same problem
          I changed using the hook woocommerce_billing_fields and it comes back after seconds/

          what to do?
          plaese
          thank you!!

          Reply
  3. Joe says

    June 26, 2014 at 11:53 am

    thanks, helped a lot more than woocommerce could. for instance..

    unset($fields[‘billing’][‘billing_address_2’][‘placeholder’]);

    Reply
    • Scott says

      June 26, 2014 at 12:34 pm

      Joe, I’m glad this helped you out.

      Reply
  4. Karen says

    July 18, 2014 at 9:50 am

    I don’t see to be able to edit the default value for postcode, or province/state?? I’ve tried to change these values the same way as the rest, but these do not change. Any ideas?

    Reply
    • Scott says

      July 21, 2014 at 11:40 am

      Hi Karen,
      You should be able to edit the default value (i.e. the words “Postcode” “Province/State”) by following the code above. Be sure to use the appropriate billing or shipping label in the code. ['billing']['billing_postcode'] or ['shipping']['shipping_postcode'], etc.
      If you think there is something more involved that’s going on and would like someone to take a look for you, please take a look at our troubleshooting WordPress errors service.

      Reply
  5. V K Rajagopalan says

    September 13, 2014 at 11:59 am

    Hi Scott,

    Thanks for this article on woocommerce checkout page customization.

    But, I needed to know one thing that was not covered in this article. On the WooCommerce Checkout page, if I wish to make the billing Email ID as display only and not editable, how to make the changes?

    Let me give below the php that I have used for replacing the billing email id with the user’s account email id.

    // Hook in – created by VKR on 13-SEP-2014
    add_filter( ‘woocommerce_checkout_fields’ , ‘custom_override_checkout_fields’ );

    // Our hooked in function – $fields is passed via the filter!
    function custom_override_checkout_fields( $fields ) {
    $current_user = wp_get_current_user();
    $fields[‘billing’][‘billing_email’][‘default’] = $current_user->user_email;
    return $fields;
    }

    Now, I want to make this email field non-editable. How to modify the above code / add more code to achieve that also?

    Thanks for all your help.

    Raj

    Reply
  6. Ashish says

    September 18, 2014 at 11:45 pm

    It’s awesome ……. thank you so much 😀

    Reply
    • Scott says

      September 19, 2014 at 8:40 am

      Thanks Ashish.

      Reply
  7. peter says

    October 1, 2014 at 6:31 am

    how can I remove a class? I want to set 2 fields on the same line.
    I added the “form-row-first” class but I can’t remove the “form-row-wide” class.

    Reply
  8. kahara says

    October 13, 2014 at 2:46 am

    Thanks for this.

    What if i want to add an options field with checkboxes?

    Reply
  9. Davis says

    November 6, 2014 at 6:08 pm

    Hi,
    I added the following to my child theme’s functions.php
    [code]/**
    * Make Fields not required
    **/

    // WooCommerce Checkout Fields Hook
    add_filter( ‘woocommerce_checkout_fields’ , ‘custom_wc_checkout_fields’ );

    // Change order comments placeholder and label, and set billing phone number to not required.
    function custom_wc_checkout_fields( $fields ) {
    $fields[‘order’][‘order_comments’][‘placeholder’] = ‘Write Your Message.’;
    $fields[‘order’][‘order_comments’][‘label’] = ‘Message.’;
    $fields[‘billing’][‘billing_phone’][‘required’] = false;
    $fields[‘billing’][‘billing_address_1’][‘required’] = false;
    $fields[‘billing’][‘billing_address_2’][‘required’] = false;
    $fields[‘billing’][‘billing_city’][‘required’] = false;
    $fields[‘billing’][‘billing_postcode’][‘required’] = false;
    $fields[‘billing’][‘billing_state’][‘required’] = false;
    $fields[‘billing’][‘billing_country’][‘required’] = false;
    $fields[‘billing’][‘billing_postcode’][‘required’] = false;

    return $fields;
    }
    [/code]
    However – on my checkout page only the phone number is not required and when I click ‘Place Order’ it says I have not filled in anything when I have filled in everything. I only want email and Name to be required . Everything else should be optional.
    Thanks in Advance for any help.

    Reply
  10. Shade says

    December 9, 2014 at 1:23 pm

    Thank you so much for this! I am trying to make the zip code NOT a required field. However, when I use the code you provided, substituting
    $fields[‘billing’][‘billing_phone’][‘required’] = false;
    with
    $fields[‘shipping’][‘shipping_postcode’][‘required’] = false;
    it doesn’t seem to work.
    What am I doing wrong?

    Reply
  11. Alex Rosas says

    January 20, 2015 at 11:31 am

    I want to make the billing details, including name & email display only and not editable.. I am running a private site and we only want to ship to user info on file. Can this be accomplished with any of the methods above? It would be awesome if someone could post the code and instructions to make this happen. Thanks in advance!

    Reply
    • Scott says

      January 20, 2015 at 12:25 pm

      Hi Alex,
      In your case it seems like you should allow billing details to be editable. Here’s why…
      You may get a customer who for argument’s sake has two credit cards in two different names and two different addresses. Let’s say card 1 is to Samuel Smith at 123 Main St, Anytown USA 95680, and card 2 is Sam Smith at PO Box 537, Anothertown USA 95782.
      If billing details are hidden (or at least not editable), then they wouldn’t be able to decide which credit card they get to use, and perhaps cost you a sale if the account info on file is for an expired, or canceled credit card.
      Additionally, you only want to ship to the shipping address on file – how does the user enter in their shipping address? If the fields to enter it in are hidden, then they would never be able to enter it in the first place unless you only intend on selling to existing customers. I don’t know whether or not that’s the case though.
      In any event it seems like the only thing that should be hidden would be the shipping fields.

      I do sell a plugin that allows you to edit the default WooCommerce fields in addition to adding some custom fields, which you can find here http://surpriseazwebservices.com/plugins/conditional-woo-checkout-field-pro/. You would easily be able to hide any fields you’d like simply by changing the setting for each field.

      It would look something like this:

      Reply
  12. Coen says

    February 1, 2015 at 6:23 am

    Hi There,

    Great tutorial!

    On my checkout page, next to there being ‘Billing Fields’ and ‘Shipping Fields’, which I can all make disappear, there also is a section called ‘Additional Information’ that by default consists of a text field called ‘order notes’.
    I’d really like to remove this section entirely too, but cannot seem to get it done. I also don’t see any of your values pointing to not display this, correct?
    Any ideas? (So for clarity sake: I want to get rid of both the title ‘Additional Information’ (is a heading) and the text field ‘Order Notes’ situated directly below it).

    Your help would be much appreciated!

    Thanks, Coen.

    Reply
    • Scott says

      February 4, 2015 at 10:52 am

      Coen,
      It seems like you are only missing a small piece to accomplish what you are looking for. Use this in your function to change the fields:

      unset($fields['order']['order_comments']);

      This should remove the “Additional Information” field as you need.

      The full code you would need is:
      // WooCommerce Checkout Fields Hook
      add_filter( 'woocommerce_checkout_fields' , 'custom_wc_checkout_fields' );

      // Remove order comments
      function custom_wc_checkout_fields( $fields ) {
      unset($fields['order']['order_comments']);
      return $fields;
      }

      Reply
  13. Jonny says

    March 2, 2015 at 10:18 am

    Great Article, It has allowed me to take control of the majority of the checkout, however i am struggling to make the order comments a required field.

    I have tried the following but it doesnt seem to be working:

    $fields[‘order’][‘order_comments’][‘required’] = true;

    Any suggestions?

    Reply
    • Scott says

      March 2, 2015 at 12:49 pm

      In your theme’s functions.php or in a site specific plugin, use the following:

      add_filter( 'woocommerce_checkout_fields' , 'custom_wc_checkout_fields' );

      // Change order comments be required.
      function custom_wc_checkout_fields( $fields ) {
      $fields['order']['order_comments']['required'] = true;
      return $fields;
      }

      The code you provided in your comment seems correct. Perhaps there was something wrong with the rest of the add_filter or function.

      Reply
  14. Sara Dunn says

    March 12, 2015 at 6:05 am

    Just a comment to say THANK YOU for this simple code and tutorial. Worked instantly to change the placeholder on the State field. I really appreciate this resource!

    Reply
    • Scott says

      March 12, 2015 at 12:49 pm

      I’m glad it worked for you Sara!

      Reply
  15. Saurabh says

    March 30, 2015 at 1:20 am

    Hi Scott The payment gateway I am using doesn’t allow special characters at the end of address line which is quite common to be used by customers.Bcoz of this transaction fails .I tried changing placeholder text so that user knows about it but when I refresh checkout page I get to see my text for fraction of seconds but then default text of placeholder of various fields is shown.Can you please tell me whats wrong –
    add_filter(‘woocommerce_checkout_fields’,’custom_override_checkout_fields’);

    //change placeholder of address field
    function custom_override_checkout_fields($fields){
    $fields[‘billing’][‘billing_address_1’][‘placeholder’]=’Do not use any special characters at the end of address’;
    $fields[‘billing’][‘billing_address_2’][‘placeholder’]=’Do not use any special characters at the end of address’;
    $fields[‘shipping’][‘shipping_address_1’][‘placeholder’]=’Do not use any special characters at the end of address’;
    $fields[‘shipping’][‘shipping_address_2’][‘placeholder’]=’Do not use any special characters at the end of address’;
    return $fields;
    }
    Please reply and help me on this issue.Thank you .

    Reply
    • Scott says

      March 30, 2015 at 9:53 am

      Try changing the ['placeholder'] piece to ['label'] and see if the text shows up as a label, which is usually above the input field. It seems as if you have everything set up correctly, but I’m wondering if your browser (or maybe theme) is causing the text to disappear. Did you test it in other browsers?
      Also, the placeholder text is designed to disappear after the box is selected to make way for user input. This may cause issues for your customers if they didn’t happen to see the placeholder text when entering their address information on the first pass. If they get an error message or some transaction failed notice, they won’t know how to fix the problem. Using a label for this purpose might make the checkout process a little easier for your customers.

      Reply
      • Saurabh says

        March 31, 2015 at 2:02 am

        Thanks for your prompt reply.Sir I have checked in other browsers also but same problem is coming.I am using canvas child theme .Is it because some function in main theme overrides this.I tried writing this code in main theme file functions.php then blank screen turns up.Where I am going wrong please help.I tried changing that to label but same thing happened on refresh I see my text and as the page loads fully default value is replaced.Awaiting your reply Sir.Thanks in advance

        Reply
        • Scott says

          April 1, 2015 at 8:37 am

          The code you posted appears to be correct. Without seeing your actual site, and the code in use there I wouldn’t be able to troubleshoot this any further.
          I do have a plugin, which will allow you to accomplish what you are trying to do without having to add any extra code to your functions.php file. You can find the plugin here.

          Reply
  16. Mark says

    April 1, 2015 at 9:47 am

    Hi Scott,
    Thanks for putting this tutorial together. Would like to make one of the fields in the shipping section not editable, noticed a few comments about that here. Looked at your plugin, although not sure it does that. Do you have a suggestion on how to make a field not editable?
    Thanks much
    Mark

    Reply
    • Scott says

      April 6, 2015 at 9:45 am

      I don’t think that these filters will allow you to set the fields to not be editable. The code to disable the field would have to be inserted into the input field manually I would assume. Take a look at this article for the specific code to add. Unfortunately these WooCommerce filters do not provide the means for adding the disabled attribute to the input box.

      Reply
  17. krisha says

    April 6, 2015 at 10:24 pm

    Great tutorial. You are a real life savior.
    Thank you.

    Reply
  18. Brad says

    April 27, 2015 at 8:01 am

    I got a really simple one for ‘ya Scott. How do I change the actual text of “Billing Details” http://prntscr.com/6yrs0w?

    https://myburleson.com is a simple one page, one item, One Pager Theme, OnePage Checkout, customized forms, ….yadda yadda. (and the dang thing will be back down in a month once our High School reunion is over ~ HA!)

    What I still can’t seem to find is where I can change the actual text of “Billing Details” and / or “Your Order” http://prntscr.com/6yrvru

    Seems kinda dumb I’ve made it this far w/ the site, yet can’t figure out those two details. Hardcoded or done correctly via child functions.php ~ either way ~ (again, only up for about another month), what I need to find is ‘how’ to change it.

    Thanks!

    Reply
    • Scott says

      April 30, 2015 at 9:49 am

      In your theme’s files there should be a WooCommerce directory with various template files that control the layout of individual WooCommerce pages (product pages, checkout, cart, etc.). In your case, I think you’ll want to find the file called form-billing.php in the your-theme/woocommerce/checkout directory.

      Open that file in a text editor such as Notepad++, and find the line that has

      Change the ‘Billing Details’ part to whatever you’d like it to say, and save the file back to your site.

      In that same directory (your-theme/woocommerce/checkout), there should be another file called form-checkout.php. Open that up and find the line that looks just like the Billing Details line above, but instead says ‘Your order’. Change it to whatever you’d like it to say and save the file.

      If for some reason those files don’t exist in your theme, you can add them by simply copying the files from the WooCommerce plugin template directory. See the video on this page for more info on that.

      Reply
  19. Luca says

    April 30, 2015 at 2:47 am

    Hi,
    I have a curiosity about: how I could change the header h3 that read “Billing Information?”
    Thanx

    Reply
    • Scott says

      April 30, 2015 at 9:29 am

      You can edit the CSS that controls how the Billing Information header looks. If you are unsure what CSS class to edit, you can use your browser’s inspect element feature to find out if your theme has any special classes for that section. I think you can use this CSS in most cases though:
      .woocommerce-billing-fields h3 { /* Your CSS Styles */ }
      Again, you might want to check your theme to see if there are any CSS classes that might be more specific than that.

      Reply
  20. Christian says

    June 27, 2015 at 2:37 pm

    I’ve been trying to add the customers billing phone number to the my account page. I tried editing domain.com/themes/woocommerce/myaccount/my-address.php

    Any ideas?

    [php]
    /**
    * My Addresses
    * @package WooCommerce/Templates
    * @version 2.2.0
    */

    if ( ! defined( ‘ABSPATH’ ) ) {
    exit;
    }

    $customer_id = get_current_user_id();

    if ( ! wc_ship_to_billing_address_only() && get_option( ‘woocommerce_calc_shipping’ ) !== ‘no’ ) {
    $page_title = apply_filters( ‘woocommerce_my_account_my_address_title’, __( ‘My Addresses’, ‘mk_framework’ ) );
    $get_addresses = apply_filters( ‘woocommerce_my_account_get_addresses’, array(
    ‘billing’ => __( ‘Billing Address’, ‘mk_framework’ ),
    ‘shipping’ => __( ‘Shipping Address’, ‘mk_framework’ )
    ), $customer_id );
    } else {
    $page_title = apply_filters( ‘woocommerce_my_account_my_address_title’, __( ‘My Address’, ‘mk_framework’ ) );
    $get_addresses = apply_filters( ‘woocommerce_my_account_get_addresses’, array(
    ‘billing’ => __( ‘Billing Address’, ‘mk_framework’ )
    ), $customer_id );
    }

    $col = 1;
    [/php]

    [php] echo $page_title; [/php]

    [php] echo apply_filters( ‘woocommerce_my_account_my_address_description’, __( ‘The following addresses will be used on the checkout page by default.’, ‘mk_framework’ ) ); [/php]

    [php] if ( ! wc_ship_to_billing_address_only() && get_option( ‘woocommerce_calc_shipping’ ) !== ‘no’ ) echo ”; [/php]

    [php] foreach ( $get_addresses as $name => $title ) : [/php]

    <div class="col-[php] echo ( ( $col = $col * -1 )

    [php] echo $title; [/php]
    [php] _e( ‘Edit’, ‘mk_framework’ ); [/php]

    [php]
    $address = apply_filters( ‘woocommerce_my_account_my_address_formatted_address’, array(
    ‘first_name’ => get_user_meta( $customer_id, $name . ‘_first_name’, true ),
    ‘last_name’ => get_user_meta( $customer_id, $name . ‘_last_name’, true ),
    ‘company’ => get_user_meta( $customer_id, $name . ‘_company’, true ),
    ‘address_1’ => get_user_meta( $customer_id, $name . ‘_address_1’, true ),
    ‘address_2’ => get_user_meta( $customer_id, $name . ‘_address_2’, true ),
    ‘city’ => get_user_meta( $customer_id, $name . ‘_city’, true ),
    ‘state’ => get_user_meta( $customer_id, $name . ‘_state’, true ),
    ‘postcode’ => get_user_meta( $customer_id, $name . ‘_postcode’, true ),
    ‘billing_phone’ => get_user_meta( $customer_id, $name . ‘_billing_phone’, true ),
    ‘country’ => get_user_meta( $customer_id, $name . ‘_country’, true )
    ), $customer_id, $name );

    $formatted_address = WC()->countries->get_formatted_address( $address );

    if ( ! $formatted_address )
    _e( ‘You have not set up this type of address yet.’, ‘mk_framework’ );
    else
    echo $formatted_address;
    [/php]

    [php] endforeach; [/php]

    [php] if ( ! wc_ship_to_billing_address_only() && get_option( ‘woocommerce_calc_shipping’ ) !== ‘no’ ) echo ”; [/php]

    Reply
  21. Sanaa Nicolas says

    September 1, 2015 at 1:30 am

    Hi Scott,
    Great Tutorial.
    I’m trying to reorder the checkout fields using
    add_filter( ‘woocommerce_order_formatted_billing_address’ , ‘reorder_billing_address’ );
    But it seems that it’s no longer working.
    Please advise

    Reply
    • Scott says

      September 2, 2015 at 8:40 am

      Are you just using that filter, or is there a function that you are using. That filter alone won’t do anything to reorder the fields.
      What you’re looking for is something like this:

      add_filter( 'woocommerce_order_formatted_billing_address' , 'reorder_billing_address' );
      function reorder_billing_address() {
      
      $address = array(
      'first_name' => $this->billing_first_name,
      'last_name' => $this->billing_last_name,
      'company' => $this->billing_company,
      'address_1' => $this->billing_address_1,
      'address_2' => $this->billing_address_2,
      'city' => $this->billing_city,
      'postcode' => $this->billing_postcode,
      'state' => $this->billing_state,
      'country' => $this->billing_country
      );
      
      return $address;
      
      }
      

      I believe that will get you where you want to be.

      Reply
  22. Paul Oaten says

    October 28, 2015 at 1:49 pm

    Thank you very much for this tutorial. My question is whether or not it is possible to make the postcode/zip field required based on the users selection of billing country / shipping country.

    For example, I would like to set the postcode/zip field to ‘not required’ if the country is Republic of Ireland.

    All my efforts have failed so far!

    Reply
    • Scott says

      October 28, 2015 at 3:03 pm

      To be honest, I haven’t found a great way to do this yet, although I would think there is a better way to do this than what I am suggesting.

      In the following link, copy and paste the code to your theme’s functions.php, or in a site specific plugin.

      https://gist.github.com/ScottDeLuzio/90fd7b11c8e0dba539a0#file-functions-php

      The problem with this is that it will check to see if the customer is in the Republic of Ireland, and will cause the postcode to be not required. So if your shop’s base country is Ireland all customers will initially see the postcode field as being not required, even if they change their address to another country. However, any current customers logged into their account will see the postcode as required/not required per their location.

      Reply
      • Paul Oaten says

        October 29, 2015 at 6:01 am

        Hi Scott,

        thanks so much for looking at this. I tested it out and it worked pretty well, but didn’t affect the shipping fields.

        I added some more code to the gist to do that and a few other things. Would appreciate your comments:

        https://gist.github.com/ScottDeLuzio/90fd7b11c8e0dba539a0#file-functions-php

        Reply
        • Scott says

          October 29, 2015 at 9:34 am

          It looks like those changes will do what you want it to do.
          As I mentioned earlier, this still isn’t a perfect solution as the postcode requirement is set when the page loads, and does not change the requirement status when the country is changed by the customer at checkout.
          Here are a few scenarios to help illustrate:

          1. The shop’s base country is Ireland, so all “guest” customers (without an existing account, or at least not logged in if they have one) will be shown the checkout form with the postcode set as optional. If they change their country to another country where the postcode should be required, it will remain optional.
          2. A customer is logged into their account where they have previously set Ireland as their country. This will correctly set the postcode as optional at the checkout page for them.
          3. A customer is logged into their account where they have previously set any other country as their country. This will display the postcode as required per that country’s WooCommerce settings.

          The checkout form uses some JavaScript somewhere to update the list of states in either a drop-down list of states, or a plain text box depending on the country selected at any point in checkout. It isn’t dependent on the pre-existing settings like the postcode. However that functionality doesn’t seem to exist for the postcode, which is why you don’t get the dynamic update of the required field when the country changes.

          An alternative to all of this is to simply set the postcode field as optional for all countries. I think most people living in countries where a postcode would be required are accustomed to entering it in anyway. Similarly in countries where it is not required, customers are probably accustomed to skipping it. Depending on the payment processor you use, you can set whether or not a payment will fail based on the postcode entered. In Stripe, for example, you can set to decline charges that fail postcode verification, but they will not decline charges if a postcode is not sent to them. I’m guessing other payment processors have a similar setting.

          Reply
          • Paul Oaten says

            November 3, 2015 at 4:04 am

            Hi Scott,

            once again, thanks so much for sharing your input on this. The site I was testing on did not have Ireland set as the shop base. Based on what you have said, does this make a difference (for the better)?

        • Scott says

          November 3, 2015 at 1:09 pm

          Paul,
          The condition set in the code you provided earlier will only check the customer’s country when the page loads. In the case of the guest checkout where the shop’s base country is filled in when the checkout , the postcode requirement will be based off of the country that is set when the checkout page loads.
          Example scenarios:
          Shop’s base country is USA, with an Irish customer.
          1) Customer is a new customer and checks out as a guest. USA will be the default country selected, and the postcode will be required. Customer changes country to Ireland, and postcode will still be required (page has not been loaded since changing their country).
          2) Customer is an existing customer who is also logged into their account where they have previously set their country to Ireland. When the checkout page loads, the country will default to Ireland and the postcode will not be required.

          Hopefully this clarifies things a bit for you.

          Reply
  23. Lebis Alarcón says

    December 10, 2015 at 10:35 am

    Thanks, great tutorial… but I’m still having a problem with editing a dropdown field, I can’t figure out how to edit the placeholder of it… http://imgur.com/vL8YSEn

    Any idea?
    Thanks again.

    Reply
    • Scott says

      December 10, 2015 at 12:50 pm

      In your array of options for the dropdown field, you can set the first option to be something like '' => 'Select an Option',

      Reply
  24. Ashish Joshi says

    January 29, 2016 at 10:26 am

    Hi

    Great Code Help. I must say you saved a hell of hours to be spend overnight.

    Thanks

    Reply
  25. Gabriela says

    February 18, 2016 at 12:31 pm

    Oh please help me, when I pasted the code, I probably did something wrong and now I cannot view my site, neither access backpanel! I am shocked! I didnt close the tab where I am editing, so I can still access edit panel! What can I do?

    Reply
    • Scott says

      February 18, 2016 at 3:44 pm

      Can you undo the changes you made? I’m guessing there is some code that is out of place. Double check everything for all the correct placement of quotes, brackets, semi-colons, etc.

      Reply
  26. Rob says

    March 6, 2016 at 1:55 pm

    I read through and saw this question asked but no real answer. I’m looking to make two fields read-only that are pre-filled. Is there a way to do this?

    Reply
    • Scott says

      March 10, 2016 at 5:10 pm

      Instead of making the fields read-only you could simply remove them from the checkout page altogether using unset in your function:

      // WooCommerce Checkout Fields Hook
      add_filter( 'woocommerce_checkout_fields' , 'custom_wc_checkout_fields' );

      // Change order comments placeholder and label, and set billing phone number to not required.
      function custom_wc_checkout_fields( $fields ) {
      unset($fields['billing']['billing_first_name']);
      unset($fields['billing']['billing_last_name']); //or whatever fields you want to remove
      return $fields;
      }

      I only say remove them rather than make them read-only because a read-only field could complicate the checkout process. I’m not sure which fields you were referring to but imagine if someone wanted to change their name from “Robert” to “Rob” in the read-only field, got frustrated because they couldn’t edit it and ended up abandoning the cart.

      Now if you’re looking to add a new field that is read-only (i.e. a terms and conditions, or something like that) check out this plugin, which can do just that.

      Reply
  27. Olga says

    March 31, 2016 at 4:14 am

    Hello! How add and reorder and save shipping fields to page ‘My account’, checkout page, edit my account page?

    Reply
    • Scott says

      March 31, 2016 at 8:54 am

      Hi, you can add your own fields to the checkout page by following this tutorial.

      To reorder the default fields, you can follow this example. Simply place the fields in the order you want them to be in inside the $order = array();.

      Those will take care of the checkout page. The My Account page goes beyond the scope of this tutorial, but it should be possible by editing the WooCommerce template files for those pages.

      Reply
  28. Araceli says

    May 31, 2016 at 2:06 am

    Hello! I like your post and your entire blog a lot. I use this hook, but I have a problem. All the function works well except the billing_first_name new placeholder. Can you see the problem in my code?? Thanks!!

    // WooCommerce Checkout Fields Hook
    add_filter( ‘woocommerce_checkout_fields’ , ‘custom_wc_checkout_fields’ );

    // Change order comments placeholder and label, and set billing phone number to not required.
    function custom_wc_checkout_fields( $fields ) {
    $fields[‘billing’][‘billing_first_name’][‘placeholder’] = ‘Nombre o Razón Social’;
    $fields[‘billing’][‘billing_city’][‘placeholder’] = ‘Ciudad’;
    $fields[‘billing’][‘billing_last_name’][‘required’] = false;
    unset($fields[‘billing’][‘billing_company’]);
    return $fields;
    }

    Reply
    • Scott says

      June 1, 2016 at 11:09 am

      I wonder if the character (ó) in Razón is throwing it off? Could you try removing that letter temporarily? Also, it appears as if the single quotes around ‘billing’, ‘billing_first_name’ and ‘placeholder’ are using ‘ instead of ‘. Try re-typing those with the apostrophe key on your keyboard instead of copy/paste from a website.

      Reply
      • Araceli says

        June 2, 2016 at 2:33 am

        I tried as you told me . I wrote ” razon ” and I’ve tried to re-type the quotes. But it does not work.
        As a last attempt I tried to copy the entire line of billing_city and replace billing_city by billing_first_name, but does not work .
        It could be that another function is interfering with this?
        Thanks for your help!!

        I paste the entire function code of my child theme:

        [Admin Edit – added pasted code to pastebin]
        http://pastebin.com/HXYT4bj9

        Reply
        • Scott says

          June 2, 2016 at 1:56 pm

          Are you getting any errors on your site? If this is the code from your functions.php, it seems like it has a lot of PHP errors in it. There may also be other plugins on your site that are conflicting with this. If you want me to look into it further, could you reach out by clicking here.

          Reply
  29. otep says

    June 6, 2016 at 9:44 pm

    Hi sir i have question in the below of the checkout, “Your Order” section
    what is the hook of subtotal and shipping? thank you very much

    Reply
    • Scott says

      June 7, 2016 at 10:51 am

      You can find a complete list of hooks in the WooCommerce docs. I’m not entirely sure which section you’re after, but you would probably want to look at woocommerce_cart_item_subtotal, woocommerce_cart_totals_after_shipping, woocommerce_cart_totals_before_shipping, or maybe woocommerce_cart_totals_before_order_total.

      Reply
  30. Tim says

    July 5, 2016 at 10:02 am

    I have already purchased your plugin. Now I want to allow the “/” in the telephone field. How can I do this? Actually the validation does not allow it.

    Reply
    • Scott says

      July 5, 2016 at 11:01 am

      I just ran a quick test and the / character is allowed in a field with an input type of Text Box. It doesn’t automatically format a phone number to use certain characters (i.e. 555-555-5555 or 555/555/5555), but if the customer inputs their phone number with the / character it should come through in the order details.

      Reply
  31. Guilherme says

    August 17, 2016 at 9:08 am

    Good afternoon!
    At checkout the Name and Last Name fields are not enabled as Required * .
    Birth and phone are not showing the corret format, just like when you type CPF for example :
    Born: 11/05/1989 ( is getting so 05111989 )
    Phone: (31) 2222-2222 (Does not appear DDD and is also all together.

    Can you help me
    thank you now.
    Fallow Image and fallow secret information

    Reply
    • Scott says

      August 17, 2016 at 9:47 am

      To make the first and last name fields to be required, you would need the following:
      // Billing First and Last Name Required
      $fields['billing']['billing_first_name']['required'] = true;
      $fields['billing']['billing_last_name']['required'] = true;
      // Shipping First and Last Name Required
      $fields['shipping']['shipping_first_name']['required'] = true;
      $fields['shipping']['shipping_last_name']['required'] = true;

      To validate the date and phone number fields, you would need a custom function to validate the customer’s input for you.

      Something like this with some modifications should work for the phone number, although I haven’t tested it (Source). A similar approach should work for the date as well.

      function wc_validate_phone_number() {
      $phone = (isset( $_POST['billing_phone'] ) ? trim( $_POST['billing_phone'] ) : '');
      if ( ! preg_match( '/(?([0-9]{3}))?([ .-]?)([0-9]{3})2([0-9]{4})/', $phone ) ) {
      wc_add_notice( __( 'Invalid Phone Number. Please enter with a valid phone number. Eg: (123) 456 7890' ), 'error' );
      }
      }

      add_action( 'woocommerce_checkout_process', 'wc_validate_phone_number' );

      Reply
  32. Abdiel says

    August 22, 2016 at 8:52 pm

    Thanks for this post!

    Reply
  33. Barb Marik says

    September 16, 2016 at 6:08 pm

    I’ve got a doosie for you. I have Woot, a child theme to Storefront in WordPress. Sometime during the last 5 days, there must have been an update to something that caused both the billing_state and billing_country fields on my checkout page to completely stop working. I’ve tried everything and cannot get the fields to populate from the dropdown lists. To make it worse, because the fields won’t populate, customers cannot proceed to the payment page! I don’t know what to do. I’ve spent 3 months building this site and a guy at the hosting company I have actually suggested that I build a new site with a different template! Isn’t there a way to override these fields in WooCommerce?

    Reply
    • Scott says

      October 3, 2016 at 9:55 am

      I would check with the developer of the child theme you’re using to let them know of the bug. It may be something they are unaware of and can fix, or offer suggestions on how to correct it on your site.

      Reply
  34. Anuj says

    October 3, 2016 at 6:02 am

    I want my Town / City * to be pre-filled with the main city i am operating in (That way it enables the Cash on Delivery option) otherwise you will have to ill the town and city address first to be able to see it. I want my customers to know that I have Cash on delivery when they first visit the checkout page but it isnt available in All the areas. Thanks

    Reply
    • Scott says

      October 3, 2016 at 10:11 am

      You can easily do this with a bit of jQuery in a custom plugin, or your child theme’s functions.php file.
      jQuery(document).ready(function() {
      jQuery("#billing_city").val("Your City");
      });

      Replace “Your City” with your actual city name. You may want to also conditionally load that script when your checkout page loads by checking to see if the customer is logged in or not. That way their actual city gets loaded from their prior purchase history instead of “Your City”.

      Replace billing_city with shipping_city if you want that to only load for the shipping address, or copy that line and do the same thing for both.

      Reply
  35. Robert says

    October 26, 2016 at 8:15 am

    Hi Guys

    All the information given is really good

    I need to know how I can change the woocommerce checkout by

    Accepting only the city and aoutoloading the Postcode because I use diferent shipping companies and In Venezuela people is not used to use Postalcode

    Thank you

    Reply
  36. Jon says

    December 7, 2016 at 4:06 am

    Thanks, simple and very helpful.

    Reply
  37. Craig says

    January 24, 2017 at 4:03 am

    Thank you for posting this! Made my change nice and simple 😀

    Reply
  38. Tony Latimer says

    February 21, 2017 at 12:57 pm

    Lots of great information here! I do have one question. How can I force a 5 digit zip code? When someone uses a dash then tax is not calculated. I can accept dashes if I use a wild card after the zip code in the table but then it doesn’t calculate tax for 5 digit codes. The wild card use to work for both but something changed. Thanks!

    Reply
  39. kamran says

    March 23, 2017 at 2:13 am

    my woo-commerce website generate invoice from back-end to customer email, i want to make all shipping fields required to save order through back-end.

    i find many solutions which make fields required from front-end but those are not working when i generate order from back-end. i tried this code but not working

    Reply
    • Scott says

      March 31, 2017 at 3:18 pm

      This code is just for the front end. Are you saying that you want to force certain fields to be required when generating an order manually using the back end? I haven’t heard of a way to do this – I’m sure it’s possible, but it’s not something I’ve looked into before.

      Reply
  40. Tungaa says

    April 27, 2017 at 1:11 am

    Thank you for the post, Scott. Your explanations seems simple and easy to use.
    My problem is I want to add custom field to the checkout fields, like additional japanese katagana field for the first and last names, and display it in certain order after names.
    Please help me!

    Reply
    • Scott DeLuzio says

      April 27, 2017 at 8:47 am

      Check out this article on adding custom fields to WooCommerce instead.

      Reply
      • Tungaa says

        April 30, 2017 at 8:02 pm

        Dear Scott, thank you for the reply.
        I could create custom field (as it was shown on the linked page), now I have to display it among default checkout page. Is it possible to create field like billing_first_name_kana and place it just under the billing_first_name?

        Reply
  41. Steve says

    August 14, 2017 at 7:57 pm

    Hi Scott, thanks for the info. I have two questions for you that I’m having a lot of trouble with.

    1. How do I decrease the width of all of the text boxes on the checkout page so that they are all the same size?

    2. Is CSS a bad way to make adjustments? IF so, why is PHP better?

    Reply
    • Scott DeLuzio says

      August 15, 2017 at 9:24 am

      Your best bet is to look at the code on your checkout page to see if there are specific classes used on the other form fields that limit their width. CSS classes that are already defined are the way to make those adjustments.

      Reply
  42. Steve says

    August 14, 2017 at 8:00 pm

    Sorry, this is continuation of the above question. I forgot to ask one thing. If I make the text boxes less wide, how do I move all of them closer together? There seems to be a bigger gap between text boxes because they are now smaller. Thanks again

    Steve

    Reply
  43. navjot singh says

    September 11, 2017 at 10:58 am

    Thank you sir you have saved my day…….

    Reply
  44. martijn says

    September 20, 2017 at 10:54 am

    To continue above question, now to increase field sizes,I am having a lot of trouble finding the file where those sizes are defined, I removed the phone number field but now the email field is half size…I thought I read it here somewhere earlier but I can’t find it anymore…

    Thanks,
    Martijn

    Reply
  45. james says

    October 16, 2017 at 3:54 pm

    Hi there i am having a problem that should be a simple fix but i can not get it to work. All i want to do is make “state” a required field. i have tried the below code with no luck. If you could help that would be fantastic
    <?php
    add_filter( 'woocommerce_billing_fields', 'woo_filter_state_billing', 10, 1 );
    add_filter( 'woocommerce_shipping_fields', 'woo_filter_state_shipping', 10, 1 );
    function woo_filter_state_billing( $address_fields ) {
    $address_fields['billing_state']['required'] = true;
    return $address_fields;
    }
    function woo_filter_state_shipping( $address_fields ) {
    $address_fields['shipping_state']['required'] = true;
    return $address_fields;
    }

    and i have tried

    function woo_filter_state_shipping( $shipping_state ) {
    $shipping_state['shipping_state']['required'] = true;
    return $shipping_state;
    }

    Reply
    • Scott DeLuzio says

      October 17, 2017 at 8:43 am

      Try this:
      add_filter( 'woocommerce_default_address_fields' , 'custom_wc_checkout_fields' );
      function custom_wc_checkout_fields( $fields ) {
      $fields['state']['required'] = false;
      return $fields;
      }

      Reply
  46. Max says

    October 23, 2017 at 1:42 pm

    I looking for code, which can delete dash from order zipcode. For example when user enter 82-300 I want write to database 82300. Could you help me with this problem?

    Reply
  47. Max says

    November 3, 2017 at 9:22 am

    Is it possible easy to delete dash in zip code? In Poland proper zip code format is xx-xxx. I want to change billing and shipping zip code befere writing to database to xxxxx. Is it possible ?

    Reply
    • Scott DeLuzio says

      November 3, 2017 at 10:19 am

      Hi Max,
      Yes, it is possible. There was actually an issue on GitHub referring to this exact problem https://github.com/woocommerce/woocommerce/issues/11325

      Unfortunately that issue was closed without a resolution put in place, even though it is a simple fix.

      Here is a snippet of code you can add to your child theme’s functions.php or a site-specific plugin that will accomplish formatting and validating post codes for Polish addresses.

      https://gist.github.com/ScottDeLuzio/9689ff4b08f2bbf80a57fc91b6d45986

      Reply
  48. kibe says

    November 21, 2017 at 6:04 am

    Instead of “Billing address” I want some thing else like “Transfer Details”.

    Reply
  49. John Day says

    December 7, 2017 at 9:53 am

    I am trying to get my MailChimp integration set up with my WooCommerce check out. My list requires the State, which is default on the checkout, but it is abbreviated and I need it to be the full name. I have this code to pull the state info:
    add_filter( ‘mc4wp_integration_woocommerce_data’, function( $data ) {

    // Grab MailChimp field values from the current request
    $data[‘STATE’] = sanitize_text_field( $_POST[‘billing_state’] );

    // Return the fields so the plugin knows to send them to MailChimp
    return $data;
    });

    and this to convert the state abbreviation to full name:
    $us_state_abbrevs_names = array(
    ‘AL’=>’ALABAMA’,
    ‘AK’=>’ALASKA’,
    ‘AS’=>’AMERICAN SAMOA’,
    ‘AZ’=>’ARIZONA’,
    ‘AR’=>’ARKANSAS’,
    );
    but am not sure how to combine the two so that the field being returned to mailchimp is the full state name. Your help would be greatly appreciated. Thanks in advance.

    Reply
    • Scott DeLuzio says

      December 7, 2017 at 10:07 am

      Try something like this:
      add_filter( 'mc4wp_integration_woocommerce_data', function( $data ) {

      if ( isset( $_POST['billing_state'] ) ){
      switch( $_POST['billing_state'] ){
      case 'AL':
      $data['STATE'] = 'ALABAMA';
      break;
      case 'AK':
      $data['STATE'] = 'ALASKA';
      break;
      // Repeat from sea to shining sea :-)
      }
      }
      // Return the fields so the plugin knows to send them to MailChimp
      return $data;
      });

      Reply
  50. James says

    December 13, 2017 at 5:48 am

    Hi Scott, thanks for this tutorial! Do you know a way to modify the code in order to make checkout fields smaller? Example: Address, postal code and city fields are all the same size on the checkout page. What php snippet can I add to functions.php to make these fields shorter but the same length? For example, I’d like to have them the same size as the First Name and Last Name fields. Typically, users don’t need all this space. Thanks again Scott!

    Reply
    • Scott DeLuzio says

      December 13, 2017 at 1:33 pm

      Try putting this in your theme’s functions.php file:

      add_filter( 'woocommerce_checkout_fields' , 'custom_wc_checkout_fields' );
      // Change order comments placeholder and label, and set billing phone number to not required.
      function custom_wc_checkout_fields( $fields ) {
      $fields['billing']['billing_address_1']['class'] = array('form-row', 'form-row-first');
      $fields['billing']['billing_address_2']['class'] = array('form-row', 'form-row-last');
      $fields['billing']['billing_address_2']['label'] = 'Address 2'; //Optional, but the layout may look odd without a label above the field
      $fields['billing']['billing_city']['class'] = array('form-row', 'form-row-first');
      $fields['billing']['billing_state']['class'] = array('form-row', 'form-row-last');
      $fields['billing']['billing_postcode']['class'] = array('form-row', 'form-row-first');
      return $fields;
      }

      If you want all of the fields to be aligned to the left, you can change any instances of 'form-row-last' to 'form-row-first'.

      Reply
  51. David says

    December 13, 2017 at 7:25 am

    Hello Scott DeLuzio,
    Thank you for your post, I have a simple question if I may, I have avada theme installed on wordpress and I use woocommerce as my plugin, the question is this, how can I have those 3 fields one under the other: so Billing address, Shipping Address and Review & Payment not to be on columns (steps) like is now. Down I attached a print screen to see how I see the columns now. Thank you in advance 🙂

    Link with the print screen of my woocommerce checkout page: https://imgur.com/a/ozWei

    Reply
    • Scott DeLuzio says

      December 13, 2017 at 1:27 pm

      That’s going to be handled by your theme. Unfortunately, I don’t have much experience with Avada so I wouldn’t be able to help there. Perhaps reach out to Avada support to see if they can assist?

      Reply
      • David says

        December 13, 2017 at 4:29 pm

        ok. thank you for the reply

        Reply
  52. jaime says

    December 18, 2017 at 4:15 pm

    hello, very good your blog, I have a doubt, if I want to get a field of originals, for example zip code and address and store it in a variable on the checkout page, how could I do it?
    is that I am making a plugin that connects to an api, at the time of finalizing the purchase, this one must take the data that the user filled in the form, I have several days looking for the function to obtain that data, but I haven’t been able to solve it 🙁 thank you

    Reply
    • Scott DeLuzio says

      December 18, 2017 at 4:36 pm

      To clarify, are you trying to access the field data from existing information (for example retrieving the zip code from the customer’s account), or do you want to pass the information provided on the checkout page to the API?

      Reply
      • jaime says

        December 20, 2017 at 5:24 pm

        Thank you, sorry for the delay, I thought I got the notification mail, if that’s the first thing you comment, I need to take those fields as the zip code to send it, I didn’t get a viable solution, since the item is in the database and the fields are in the client, so I was going to get ajax.
        But after analyzing it, I can take all the data from the database, instead of doing it on the checkout page, I do it on the order-received page, do you think?
        I think you understand the idea, sorry my English is not very good.

        Reply
  53. Jennifer says

    January 18, 2018 at 9:43 am

    Thank you for the blog. I have followed the instructions in the post. However when i refresh the page, at first the field shows up as not required, but then at the very end of the loading it changes. It happens, Any Idea what could be causing this, I guess there is code that overrides this after the functions.php is called.

    Thanks for your help

    Reply
  54. Arianne Salamat says

    January 30, 2018 at 4:48 am

    Hi, I would like the Mobile Number field during checkout to be a required field. Can anyone help me?

    Reply
    • Scott DeLuzio says

      January 31, 2018 at 9:54 am

      I don’t think a Mobile Number field is a default field in WooCommerce. It may have been added by a plugin or theme, or perhaps it’s just the label for the default billing phone field that has changed. If it is the default billing phone field with a different label, you can try the first code above (remove the first two order comments lines), and change the last line to = true ( $fields['billing']['billing_phone']['required'] = true;)

      Reply
  55. Kumar says

    February 2, 2018 at 12:41 am

    I am looking to pre-populate Billing Company Field with OPtional. Can u help on code for function file.

    Reply
    • Scott DeLuzio says

      February 2, 2018 at 8:53 am

      You would use something like this:
      add_filter( 'woocommerce_checkout_fields' , 'your_custom_wc_checkout_fields' );
      function your_custom_wc_checkout_fields( $fields ) {
      $fields['billing']['billing_company']['placeholder'] = 'Optional';
      return $fields;
      }

      Reply
  56. mary cattapan says

    February 7, 2018 at 9:53 am

    HI, I am not at all tech savvy. I am trying to revise the very horrible website someone created for me. He left the words “test” in the address page of my cart when people check out. I want to remove it. How do I do that?

    Reply
  57. vi tính quận 7 says

    March 12, 2018 at 10:02 am

    How about select field variable product

    Reply
    • Scott DeLuzio says

      March 12, 2018 at 11:02 am

      This only concerns the fields on the checkout page, so it doesn’t matter what type of product you’re dealing with.

      Reply
  58. Swarnasanka says

    June 10, 2018 at 2:06 am

    hi

    i m from Sri Lanka . i m facing the same issue though my country have postal codes no one use it to buy . if ask that they will not continue on checkout the cart.

    i have two 2 questions
    1. how top remove mandatory postal code request
    2. if i remove that how can i give shipping rates to the site
    my shipping work as below
    city X for full cart wight 1 kg 100 and additional kg 50
    city Y full cart weight 1 kg 250 additional kg 50
    city Z full cart weight 1 kg 300 additional kg 50
    i can set this but need customer to select a field to select city .

    please help

    Regards
    Swarnasanka

    Reply
    • Scott DeLuzio says

      June 11, 2018 at 8:40 am

      In the first and second code examples above, you would use the unset method that is shown with the appropriate fields.

      So, something like this:

      // WooCommerce Checkout Fields Hook
      add_filter( 'woocommerce_checkout_fields' , 'custom_wc_checkout_fields' );
      // Remove the billing and shipping postcode fields
      function custom_wc_checkout_fields( $fields ) {
      unset($fields['billing']['billing_postcode']);
      unset($fields['shipping']['shipping_postcode']);
      return $fields;
      }

      As for the shipping, you would need to set up weight based shipping rates. You can try a plugin such as WooCommerce Weight Based Shipping, which I believe will let you set rates for each individual city. In the plugin’s screenshot under the Conditions section, it shows how you can limit the shipping rate to a specific destination (i.e. City X, City Y, or City Z). That should get you what you’re looking for.

      Hope this helps!

      Reply
  59. Renier Delport says

    August 12, 2018 at 4:16 am

    Thank you. After working with a few WooCommerce field manager plugins – which give a great visual representation of these fields, working with the functions is even easier ; )

    Reply
    • Scott DeLuzio says

      August 15, 2018 at 12:38 pm

      Glad it helped.

      Reply
  60. Chris Barriga says

    September 3, 2018 at 5:51 pm

    Hello, I need help with the checkout page in my woocommerce. I am trying to move the entire Shipping Field above the Billing Field as I would like to have the customer’s Shipping details first before the Billing.
    I have copied over the ‘form-checkout.php’ file into my child theme’s folder woocommerce/checkout/ and have modified it to the following:

    But having the ‘woocommerce_checkout_shipping’ before the ‘woocommerce_checkout_billing’ does not place the Shipping details above the Billing details.
    I don’t know if there is maybe something I am missing? Please let me know if this is even possible.
    Thanks!

    Reply
    • Scott DeLuzio says

      September 3, 2018 at 6:32 pm

      I believe you can edit your checkout page template file in your theme. Check out this document for more info on editing those files.

      Reply
      • Chris Barriga says

        September 4, 2018 at 11:11 am

        Thank you for your reply! It has lead me to the conclusion that my Astra theme was overriding the woocommerce checkout screen. I was able to disable that part of the theme and use the ‘form-checkout.php’ file correctly as I wanted to. Thanks again!

        Reply
  61. Valery says

    September 13, 2018 at 2:17 pm

    Making a checkout page for different types of customers?
    I want to make an option for woocommerce checkout page.

    It’s an option which will allow customer to choose between physic person or a business. Physic person will see basic fields which we have on checkout page, but for business, some additional fields. Is that possible? Maybe I can solve this through a plugin? Thanks you very much.

    Here is an example what I want to do.

    https://imgur.com/jKsNpK6

    Cheers.

    Reply
    • Scott DeLuzio says

      September 14, 2018 at 2:59 pm

      There might be a plugin that can handle this for you, but I’m not aware of one off the top of my head.

      Reply
  62. Shaun says

    December 17, 2018 at 2:50 pm

    I was hoping you could offer some suggestions on how to get this to work correctly. I added this code to the functions.php to force a shipping field on virtual products. Works great! Except when it comes to printing the invoice on virtual product the shipping field is left off. Any way to fix this?

    Reply
    • Scott DeLuzio says

      December 17, 2018 at 3:06 pm

      By default the shipping address is left off of the invoice for virtual products. You’ll need to edit the template files for that in WooCommerce to include the shipping address.

      I believe the two files are
      /templates/emails/email-addresses.php
      and
      /templates/order/order-details-customer.php

      I think all you need to do is remove the && $order->needs_shipping_address() code from each file and you should be able to get the shipping info back.

      Here is how to edit those files without losing your changes when WooCommerce updates.

      Reply
  63. Fab says

    January 31, 2019 at 3:01 am

    Hello,

    Thank you for your article. But it seems that doesn’t work anymore.

    I’ve try this on my custom theme functions.php file :

    // Hook in
    add_filter( ‘woocommerce_checkout_fields’ , ‘custom_override_checkout_fields’ );

    // Our hooked in function – $fields is passed via the filter!
    function custom_override_checkout_fields( $fields ) {

    $fields[‘billing’][‘billing_first_name’][‘class’] = ‘my-class’;

    return $fields;
    }

    Would I miss something?

    Thank you for your help!

    Reply
  64. harish says

    March 16, 2019 at 10:42 pm

    sir
    if i unset billing details it is ok for old customer and if new customer comes he is not able to fill and no payment is proceeded wat to do

    Reply
    • Scott DeLuzio says

      March 18, 2019 at 1:31 pm

      Just because you can change something doesn’t mean that you should.

      I wouldn’t suggest removing the billing details entirely. New customers will have no way to submit their payment. Existing customers might have their billing information available from a previous purchase, but you can’t guarantee that they will want to use the same billing information for future purchases. For example, if a customer makes a purchase with their personal credit card, they might enter their home address in the billing address fields, but they may make a second purchase with a company credit card, where they may need to enter their business address. Plus, if you remove the fields for existing customers, that information won’t get passed along with the order since there aren’t any form fields to complete with that information.

      I would suggest leaving the fields for billing details as they are unless there is a specific reason you need to remove them that can’t be handled any other way. I just can’t think of what that scenario might be.

      Reply
  65. Francesco says

    April 4, 2019 at 9:03 pm

    Hello,

    I’ve installed a plug-in for Italian invoice and it changed the billing city field length from 100% to half-left.
    How can I make it again 100%?

    I don’t know what code to insert in my functions.php

    Can you help me?

    Reply
    • Scott DeLuzio says

      April 5, 2019 at 9:19 am

      Something like this should help.

      add_filter( 'woocommerce_checkout_fields', 'sd_12432_custom_wc_checkout_fields' );
      function sd_12432_custom_wc_checkout_fields( $fields ){
      $fields['billing']['billing_city']['class'] = 'form-row form-row-wide';
      return $fields;
      }

      Please note that I haven’t tested this code, it’s just a sample to get you pointed in the right direction.

      Reply
  66. Alvina says

    August 27, 2019 at 2:29 am

    I am trying to remove extra fields from checkout page but I am having error. Is there any other way to do this? I have this code that I have created going through this tutorial https://www.cloudways.com/blog/how-to-edit-delete-fields-and-email-in-woocommerce-custom-checkout-fields/

    function remove_additional_information_checkout($fields){
    unset( $fields[“billing_last_name”] );
    unset( $fields[“billing_middle_name”] );
    return $fields;
    }
    add_filter( ‘woocommerce_billing_fields’, ‘remove_additional_information_checkout’ );

    Reply
  67. Gabriel Pinto-Hasagiv says

    October 31, 2019 at 6:35 pm

    Hi Scott,
    First thank you for a great tutorial!
    I’m trying to make the EMAIL & PHONE NUMBER to be in the same row but can’t make it,
    My form in the check out right now is:

    First Name Last Name
    Email
    Phone Number
    City
    User Name
    Password

    And i want it to be:
    First Name Last Name
    Email Phone Number
    City
    User Name Password

    Can you tell me how i can do that?
    Thank you!

    https://academy.pikmediagroup.com/checkout/

    Reply
  68. Jacob says

    November 26, 2020 at 10:31 pm

    Thank you. After working with a few WooCommerce field manager plugins – which give a great visual representation of these fields, working with the functions is even easier ; )

    Reply
  69. mehmet says

    January 24, 2023 at 2:25 am

    Hello there,

    How do I bring the name and surname labels on the payment page side by side using functions.php

    Reply

Leave a Reply Cancel reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Primary Sidebar

Come say hi!

  • Facebook
  • GitHub
  • Instagram
  • LinkedIn
  • Twitter
  • YouTube

Tweets by scottdeluzio

My Products

Conditional Checkout FieldsFull Screen Background ImagesQuick CheckoutWP1099

I use affiliate links throughout this site and may earn a commission if you purchase through my links. I do not link to products or services that I do not trust, or use myself.
© 2025 · Scott DeLuzio · Built on the Genesis Framework