How to add additional fields to the WooCommerce Checkout Block

This feature requires a minimum version of WooCommerce 8.9.0

The WooCommerce Checkout Block provides a powerful API for developers to add additional fields to collect information from customers during the checkout process. Whether you need to gather special delivery instructions, business details, or marketing preferences, additional checkout fields make it easy to extend your store’s functionality.

In this post, we’ll walk through the process of adding your own additional fields to your checkout form and show you practical examples you can implement right away.

Getting started

To add additional checkout fields, you’ll use the woocommerce_register_additional_checkout_field() function. This should be called after the woocommerce_init action to ensure WooCommerce is fully loaded.

Here’s the basic structure:

add_action( 'woocommerce_init', function() {
    if ( ! function_exists( 'woocommerce_register_additional_checkout_field' ) ) {
        return;
    }
    
    woocommerce_register_additional_checkout_field(
        array(
            'id'       => 'your-namespace/field-name',
            'label'    => __( 'Your Field Label', 'your-text-domain'),
            'location' => 'contact', // or 'address' or 'order'
            'type'     => 'text',    // or 'select' or 'checkbox'
            'required' => false,
        )
    );
});
PHP

Field locations: Where your fields appear

You can place your additional fields in three different locations:

WooCommerce checkout interface displaying contact information fields, delivery options, shipping address form, shipping and payment options.

Contact information (contact)

Fields here appear at the top of the checkout form alongside the email field. Data saved here becomes part of the customer’s account and will be visible in their “Account details” section.

woocommerce_register_additional_checkout_field(
    array(
        'id'       => 'my-plugin/marketing-opt-in',
        'label'    => __('Subscribe to our newsletter?', 'your-text-domain'),
        'location' => 'contact',
        'type'     => 'checkbox',
    )
);
PHP
WooCommerce checkout form displaying contact information fields, including an email address input and an optional newsletter subscription checkbox.

Address (address)

These fields appear in both the shipping and billing address forms. They’re saved to both the customer and the order, so returning customers won’t need to refill them.

woocommerce_register_additional_checkout_field(
    array(
        'id'       => 'my-plugin/delivery-instructions',
        'label'    => __('Special delivery instructions', 'your-text-domain'),
        'location' => 'address',
        'type'     => 'text',
    )
);
PHP
WooCommerce checkout form for entering shipping address, including fields for country, first name, last name, address, city, postcode, and optional special delivery instructions.

Order information (order)

Fields in this location appear in a separate “Order information” block and are saved only to the order, not the customer’s account. Perfect for order-specific details that don’t need to be remembered for future purchases.

woocommerce_register_additional_checkout_field(
    array(
        'id'       => 'my-plugin/gift-message',
        'label'    => __('Gift message', 'your-text-domain'),
        'location' => 'order',
        'type'     => 'text',
    )
);
PHP
Additional order information section with a text input for an optional gift message and a checkbox to add a note to the order.

Supported field types

The API supports three field types:

Text fields

Perfect for collecting short text input:

woocommerce_register_additional_checkout_field(
    array(
        'id'       => 'my-plugin/company-vat',
        'label'    => __('VAT Number', 'your-text-domain'),
        'location' => 'address',
        'type'     => 'text',
        'required' => true,
    )
);
PHP

Select dropdowns

Great for predefined options:

woocommerce_register_additional_checkout_field(
    array(
        'id'       => 'my-plugin/preferred-delivery-time',
        'label'    => __('Preferred delivery time', 'your-text-domain'),
        'location' => 'order',
        'type'     => 'select',
        'options'  => array(
            array(
                'value' => 'morning',
                'label' => __('Morning (9AM - 12PM)', 'your-text-domain')
            ),
            array(
                'value' => 'afternoon',
                'label' => __('Afternoon (12PM - 5PM)', 'your-text-domain')
            ),
            array(
                'value' => 'evening',
                'label' => __('Evening (5PM - 8PM)', 'your-text-domain')
            ),
        ),
    )
);
PHP

Checkboxes

Ideal for yes/no questions or opt-ins:

woocommerce_register_additional_checkout_field(
    array(
        'id'           => 'my-plugin/age-verification',
        'label'        => __('I confirm I am over 18 years old', 'your-text-domain'),
        'location'     => 'contact',
        'type'         => 'checkbox',
        'required'     => true,
        'error_message' => __('You must be over 18 to place this order.', 'your-text-domain'),
    )
);
PHP

Adding field attributes

You can enhance your fields with HTML attributes for better user experience:

woocommerce_register_additional_checkout_field(
    array(
        'id'         => 'my-plugin/phone-number',
        'label'      => __('Alternative phone number', 'your-text-domain'),
        'location'   => 'contact',
        'type'       => 'text',
        'attributes' => array(
            'autocomplete' => 'tel',
            'pattern'      => '[0-9]{10}',
            'title'        => __('Please enter a 10-digit phone number', 'your-text-domain'),
            'placeholder'  => '1234567890',
        ),
    )
);
PHP

Validation and sanitization

To ensure data quality, you can add custom validation and sanitization:

add_action( 'woocommerce_init', function() {
    woocommerce_register_additional_checkout_field(
        array(
            'id'                => 'my-plugin/business-email',
            'label'             => __('Business Email', 'your-text-domain'),
            'location'          => 'contact',
            'type'              => 'text',
            'required'          => true,
            'sanitize_callback' => function( $value ) {
                return sanitize_email( $value );
            },
            'validate_callback' => function( $value ) {
                if ( ! is_email( $value ) ) {
                    return new WP_Error( 
                        'invalid_business_email', 
                        __('Please enter a valid business email address.', 'your-text-domain') 
                    );
                }
            },
        )
    );
});
PHP

You can also use WordPress action hooks for validation:

add_action( 'woocommerce_validate_additional_field', function( $errors, $field_key, $field_value ) {
    if ( 'my-plugin/business-email' === $field_key ) {
        if ( ! is_email( $field_value ) ) {
            $errors->add( 'invalid_business_email', __('Please enter a valid email address.', 'your-text-domain') );
        }
    }
}, 10, 3 );
PHP

Accessing field values

After checkout, you can retrieve the field values using helper methods:

use Automattic\WooCommerce\Blocks\Package;
use Automattic\WooCommerce\Blocks\Domain\Services\CheckoutFields;

$checkout_fields = Package::container()->get( CheckoutFields::class );
$order = wc_get_order( $order_id );

// Get a specific field value
$business_email = $checkout_fields->get_field_from_object( 
    'my-plugin/business-email', 
    $order, 
    'other' // Use 'billing' or 'shipping' for address fields
);

// Get all additional fields
$all_fields = $checkout_fields->get_all_fields_from_object( $order, 'other' );
PHP

Complete example

add_action( 'woocommerce_init', function() {
    if ( ! function_exists( 'woocommerce_register_additional_checkout_field' ) ) {
        return;
    }

    // Company information
    woocommerce_register_additional_checkout_field(
        array(
            'id'       => 'my-business-store/company-size',
            'label'    => __('Company size', 'your-text-domain'),
            'location' => 'contact',
            'type'     => 'select',
            'required' => true,
            'options'  => array(
                array( 'value' => '1-10', 'label' => __('1-10 employees', 'your-text-domain') ),
                array( 'value' => '11-50', 'label' => __('11-50 employees', 'your-text-domain') ),
                array( 'value' => '51-200', 'label' => __('51-200 employees', 'your-text-domain') ),
                array( 'value' => '200+', 'label' => __('200+ employees', 'your-text-domain') ),
            ),
        )
    );

    // Delivery preferences
    woocommerce_register_additional_checkout_field(
        array(
            'id'       => 'my-business-store/requires-appointment',
            'label'    => __('Delivery requires appointment', 'your-text-domain'),
            'location' => 'address',
            'type'     => 'checkbox',
        )
    );

    // Order-specific notes
    woocommerce_register_additional_checkout_field(
        array(
            'id'       => 'my-business-store/po-number',
            'label'    => __('Purchase Order Number', 'your-text-domain'),
            'location' => 'order',
            'type'     => 'text',
        )
    );
});
PHP

Next steps

You now have the foundation for adding additional checkout fields to your WooCommerce store using the checkout block. For more advanced functionality like conditional field visibility and complex validation rules, check out our complete API documentation.

The additional checkout fields API provides a robust foundation for customizing your checkout experience while maintaining compatibility with WooCommerce’s block-based checkout system. Start with simple fields and gradually add more sophisticated validation and conditional logic as your needs grow.

Next find out how to make your WooCommerce additional checkout fields conditionally visible

4 responses to “How to add additional fields to the WooCommerce Checkout Block”

  1. […] our previous post, we covered the basics of adding additional fields to the WooCommerce Checkout Block. Now let’s take it a step further and explore how to make those fields appear and disappear […]

  2. This is very helpful! Do you perhaps also know how to remove default fields from checkout using a similar method? I’m specifically wanting to hide address details dor virtual-only orders – this is pretty simple with the old checkout, but I haven’t found a solution for how to do it in the block-based checkout yet.

    1. Thank you for your kind words. I can’t provide a solution right now unfortunately as I’m currently on parental leave but one thing I’d highly suggest is jumping on the WooCommerce Community Slack workspace and asking in there. The other folks working on the checkout are super responsive and will help answer any queries.

Leave a Reply to Tom Cafferkey Cancel reply

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