The WooCommerce checkout page is the highest-stakes form on any store — friction here directly reduces conversion rates. Default WooCommerce checkout includes billing and shipping sections with about fifteen fields each, many of which are irrelevant for digital products or stores that only ship domestically. Removing unnecessary fields (like company name or a second address line) shortens the form and reduces customer effort. Adding custom fields — such as a delivery note, a gift message, or a VAT number — is equally straightforward via the woocommerce_checkout_fields filter, which gives you access to the entire checkout field array. Fields are grouped into four sections: billing, shipping, account, and order. Each field entry is an associative array specifying the type, label, placeholder, required flag, priority (which controls display order), and CSS class. The priority value determines rendering order within a section — lower numbers appear first. WooCommerce also provides dedicated action hooks for adding custom fields to specific locations without restructuring the whole array: woocommerce_before_order_notes, woocommerce_after_order_notes, and woocommerce_review_order_before_submit are the most commonly used. Saving custom field data requires hooking into woocommerce_checkout_process for validation and woocommerce_checkout_update_order_meta for persistence. This article builds on the custom checkout field guide and focuses specifically on modifying the existing field set. Combine it with the thank-you page guide to display the saved field values on the order confirmation screen.
Problem: The default WooCommerce checkout form has too many fields for your store’s needs, is missing a custom field, and has suboptimal field ordering — all of which increase checkout friction.
Solution: Use the woocommerce_checkout_fields filter to remove unwanted fields, add a custom one, and adjust priorities to reorder:
add_filter( 'woocommerce_checkout_fields', 'ha_customise_checkout_fields' );
function ha_customise_checkout_fields( $fields ) {
// Remove unnecessary billing fields
unset( $fields['billing']['billing_company'] );
unset( $fields['billing']['billing_address_2'] );
unset( $fields['billing']['billing_state'] );
// Make billing phone optional instead of required
$fields['billing']['billing_phone']['required'] = false;
// Reorder: move billing_email before billing_phone (lower priority = earlier)
$fields['billing']['billing_email']['priority'] = 15;
$fields['billing']['billing_phone']['priority'] = 20;
// Add a custom "Delivery note" field to the order section
$fields['order']['ha_delivery_note'] = [
'type' => 'textarea',
'label' => __( 'Delivery note', 'woocommerce' ),
'placeholder' => __( 'Any instructions for the courier (optional)', 'woocommerce' ),
'required' => false,
'class' => [ 'form-row-wide' ],
'priority' => 5,
];
return $fields;
}
// Save the custom field to order meta
add_action( 'woocommerce_checkout_update_order_meta', 'ha_save_delivery_note' );
function ha_save_delivery_note( $order_id ) {
if ( ! empty( $_POST['ha_delivery_note'] ) ) {
update_post_meta(
$order_id,
'_ha_delivery_note',
sanitize_textarea_field( wp_unslash( $_POST['ha_delivery_note'] ) )
);
}
}
// Display the field value in the admin order screen
add_action( 'woocommerce_admin_order_data_after_billing_address', 'ha_display_delivery_note_in_admin' );
function ha_display_delivery_note_in_admin( $order ) {
$note = get_post_meta( $order->get_id(), '_ha_delivery_note', true );
if ( $note ) {
echo '<p><strong>' . esc_html__( 'Delivery note', 'woocommerce' ) . ':</strong> '
. esc_html( $note ) . '</p>';
}
}
NOTE: Field priorities in WooCommerce use increments of 10 by default (10, 20, 30, …), so inserting a field between two existing fields is as simple as setting its priority to a value between them, such as 15. The class array controls the CSS grid width — form-row-wide spans the full width, form-row-first and form-row-last place two fields side by side. Always sanitise custom field input with sanitize_text_field() or sanitize_textarea_field() before saving to the database — see the sanitisation guide for the full reference.