Checkout fields

How to remove or edit WooCommerce checkout fields

Every extra field costs you orders, so the instinct to delete some is right. But four of the fields people try to remove are load bearing, and the snippet everyone copies stopped working on half of WooCommerce installs. Here is what actually works in 2026.

What this article covers

  • Safe to remove: phone, company, address line 2, and optionally the second name field.
  • Never remove: country, street address, town, postcode. Your shipping rates and tax are calculated from them.
  • The classic snippet is a woocommerce_checkout_fields filter, and the single most common mistake is forgetting to return the array.
  • The same snippet does nothing on the block checkout. Blocks reads three dedicated options instead, and ignores the field filter for required and hidden.

The short answer

WooCommerce builds its checkout form from a filterable array. To remove a field on the classic checkout you hook woocommerce_checkout_fields, unset the key you do not want, and return the array. That is roughly five lines in your theme's functions.php or a small site plugin.

On the block checkout that same code has no effect on visibility. Blocks reads three dedicated WordPress options for phone, company and address line 2, and it ignores the classic filter's required and hidden keys entirely. If you have ever pasted a snippet, seen nothing change, and assumed you had a caching problem, this is almost certainly why.

Before you remove anything: a shorter form is not automatically a better one. Baymard's research puts a long or complicated checkout at 17% of abandonments, well behind unexpected extra costs at 40%. Deleting two fields is worth doing. It will not fix a shipping surprise, and the full ranked list of what does is in how to reduce cart abandonment in WooCommerce.

Which fields are safe to remove, and which are load bearing

This is the part most tutorials skip, and it is the part that breaks stores. WooCommerce checkout fields fall into three groups.

Safe to remove or make optional

  • Phone. Genuinely optional for most stores. Check your couriers first: some delivery services require a contact number, and some payment gateways use it for fraud scoring.
  • Company name. Dead weight for a business selling to consumers. Keep it if you sell B2B or need it on invoices.
  • Address line 2. The most commonly removed field, and the one shoppers most often need. Consider making it optional rather than hidden, or hiding it behind a link, so people in apartments can still tell your courier which one.
  • Last name. Safe to make optional. Removing it entirely is riskier than it looks, because some gateways match the cardholder name.

Never remove

Country, street address, town and postcode stay. These are not cosmetic. WooCommerce calculates shipping rates and tax from them, and payment processors use the billing address for fraud checks and for 3D Secure. WooCommerce's own developer documentation is blunt about removing address data: "This is not something we encourage." Removing the country field specifically will cause orders to fail outright.

People try to hide postcode because it feels like friction. It is not friction, it is the input to your shipping table. Hiding it does not shorten your checkout, it breaks your totals, and the failure shows up as an unexplained drop in completed orders rather than as an error message.

Depends entirely on your store

The order notes field, the shipping address block when you sell only digital goods, and any field added by another plugin. For digital-only stores, turning off shipping in WooCommerce settings removes the entire shipping section far more cleanly than filtering fields one at a time.

The classic checkout snippet that works

The woocommerce_checkout_fields filter receives an array keyed by section: billing, shipping, account and order. Each section holds its fields. Unset what you do not want and return the array.

// Remove phone, company and address line 2 from the classic checkout.
// Put this in a site plugin, or your child theme's functions.php.
add_filter( 'woocommerce_checkout_fields', 'oc_simplify_checkout_fields' );

function oc_simplify_checkout_fields( $fields ) {

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

    // Shipping is a separate section with its own keys.
    unset( $fields['shipping']['shipping_company'] );
    unset( $fields['shipping']['shipping_address_2'] );

    return $fields; // <- the line everyone forgets
}

Field keys are prefixed by section, so billing phone is billing_phone, not phone.

The mistake that blanks your checkout. If you forget return $fields;, the filter returns null, WooCommerce assigns that as the entire field array, and your checkout renders as an empty page with a lone Place Order button. It looks like a catastrophic plugin conflict. It is a missing return statement.

Two more traps worth knowing before you paste this anywhere:

  • There are three other ways to change a checkout, and a snippet is only the right one for some jobs. CSS, hooks and template overrides each have a different ceiling, compared in how to customise the WooCommerce checkout page.
  • Do not edit plugin or theme files directly. Both get overwritten on update. Use a child theme or, better, a one file site plugin so the change survives a theme switch.
  • Removing a field does not remove its data. Existing orders keep their stored phone numbers, and any integration reading billing_phone will now receive an empty string rather than an error. Check your fulfilment and email flows.

Making a field optional instead of removing it

Usually the better move. The shopper who wants to give you a phone number still can, and you stop blocking the one who does not want to.

add_filter( 'woocommerce_checkout_fields', 'oc_relax_checkout_fields' );

function oc_relax_checkout_fields( $fields ) {

    $fields['billing']['billing_phone']['required'] = false;
    $fields['billing']['billing_company']['required'] = false;

    // Retitle it so the shopper knows it is genuinely optional.
    $fields['billing']['billing_phone']['label'] = 'Phone (for delivery updates)';

    return $fields;
}

WooCommerce appends its own "(optional)" suffix to non required labels, so you do not need to write it yourself.

Why the same snippet does nothing on the block checkout

This is the single biggest source of wasted afternoons on this topic, and almost no tutorial mentions it.

If your store uses the newer block checkout, the form is rendered by React from data supplied by the Store API, not by the PHP template. The classic woocommerce_checkout_fields filter still exists, but the block form ignores its required and hidden keys. The related woocommerce_default_address_fields filter has the same problem: the block address form calls it, but disregards required and hidden for most fields.

How to tell which checkout you have. Open your checkout page in the WordPress editor. If you see a single [woocommerce_checkout] shortcode block, you are on classic. If you see a Checkout block with an inspector sidebar full of toggles, you are on blocks. We wrote a fuller guide to the difference in block checkout versus classic checkout.

The three fields WooCommerce gives you real options for

WooCommerce core stores a required, optional or hidden setting for exactly three fields, as ordinary WordPress options:

  • woocommerce_checkout_phone_field
  • woocommerce_checkout_company_field
  • woocommerce_checkout_address_2_field

Each accepts required, optional or hidden. The block checkout reads these directly, which makes them the version stable way to control those three fields on a block store. On a block checkout you can also set them from the editor: select the Checkout block, open the inspector, and each of the three has a control.

For the remaining core address fields, the supported lever on blocks is the country locale filter, which flips required per country:

// Make last name optional for every country on a block checkout.
add_filter( 'woocommerce_get_country_locale', function( $locale ) {
    foreach ( $locale as $code => $rules ) {
        $locale[ $code ]['last_name']['required'] = false;
    }
    return $locale;
} );

And to genuinely hide a field on a block checkout, the reliable route is CSS, because the React form renders every field in its internal map regardless of the hidden key. That is not elegant, but it is the honest state of the platform in 2026.

Never hide a required field with CSS alone. Hiding the input does not stop WooCommerce validating it on the server. If the field is still required, the shopper submits the form, gets an error about a field they cannot see, and has no way to fix it. Make the field optional first, using the option for phone, company and address line 2, or the country locale filter for the rest, and only then hide it. A hidden required field is one of the few checkout mistakes that stops orders outright rather than merely costing you a few.

What the snippet does not do

Code that removes a field removes the field. It does not do the four things that actually decide whether a shorter checkout converts better:

  • Validation and error placement. Removing a required field is easy. Making the remaining errors appear next to the offending input, rather than as one lump at the top of the page, is the part that changes completion rates on a phone.
  • Layout. Deleting a field leaves a gap. Two half width fields that used to sit side by side now sit awkwardly. Nothing reflows for you.
  • Mobile. The keyboard covers 40 to 50% of a phone screen. Which field sits under it after your change is not something a snippet considers. We wrote about this in why your WooCommerce checkout breaks on mobile.
  • Surviving updates. Field keys are stable, but the surrounding template is not. Every WooCommerce major release is a chance for a hand rolled override to drift.

Doing it without code

If you would rather not maintain a snippet, this is exactly what a checkout plugin is for. In OptiCheckout, phone, company and address line 2 each get a three way control in the visual builder: required, optional or hidden. First and last name can be made optional the same way. You click, you see the result in the live preview, and there is nothing to re-apply after an update.

Country, town, postcode and street address stay required on purpose. Not as an artificial limit, but because they feed your shipping rates and tax. Hiding them would break your totals rather than shorten your form, so the field manager does not offer it.

See it on a real checkout

Every OptiCheckout template is rendered from the real plugin, not a screenshot. Open one and look at the field layout before you decide.

Field reference table

Field Key Safe to remove?
Phonebilling_phoneYes, check couriers first
Companybilling_companyYes, unless you sell B2B
Address line 2billing_address_2Yes, prefer optional
Last namebilling_last_nameOptional yes, removal risky
Order notesorder_commentsYes
Street addressbilling_address_1No, shipping and tax
Town or citybilling_cityNo, shipping and tax
Postcodebilling_postcodeNo, shipping and tax
Countrybilling_countryNo, orders will fail

Shipping section keys use the shipping_ prefix and follow the same rules.