
September 08, 2026
11 min read
By Kokil Thapa | Last reviewed: September 2026
Most store owners need more than the default billing and shipping boxes at checkout. WooCommerce Custom Checkout Fields with Validation lets you collect VAT numbers, delivery notes, gift messages, or Nepal-specific details like PAN without breaking the order flow. The work sits in theme or plugin code on WooCommerce eCommerce builds, not in page builders alone. This guide walks through field registration, server-side validation, sanitization, admin visibility, and the mistakes I see on production florist and grocery stores.
woocommerce_checkout_fields, validate on woocommerce_checkout_process, sanitize on woocommerce_checkout_posted_data, and save via woocommerce_checkout_update_order_meta. Always validate server-side—client-side JavaScript alone is not enough for WooCommerce Custom Checkout Fields with Validation.What Are WooCommerce Custom Checkout Fields and Why Do You Need Validation?
Checkout fields are an associative array grouped into billing, shipping, order, and custom sections. WooCommerce renders them from that array. You change labels, add inputs, or hide defaults through filters—not by editing core templates when a hook exists.
Validation matters because checkout is where money moves. A missing PAN on a B2B invoice, an invalid phone for SMS alerts, or a blank delivery slot breaks fulfilment. On stores like international WooCommerce florist projects, custom fields often carry date and message data that must be correct before payment.
Put logic in a custom plugin or child theme functions.php. Child themes work for single-store tweaks. Plugins survive theme switches—better for client handoffs on WordPress store maintenance.
How Do You Register Custom Checkout Fields in WooCommerce?
Use the woocommerce_checkout_fields filter. Each field needs a key, type, label, and priority. Place business-only fields in the order group or a custom section.
Minimal field registration example
Create wp-content/plugins/my-store-checkout-fields/my-store-checkout-fields.php:
<?php
/**
* Plugin Name: My Store Checkout Fields
* Requires Plugins: woocommerce
* Requires at least: 7.1
* WC requires at least: 11.1
*/
defined( 'ABSPATH' ) || exit;
add_filter( 'woocommerce_checkout_fields', 'mscf_add_checkout_fields' );
function mscf_add_checkout_fields( $fields ) {
$fields['order']['billing_pan'] = [
'type' => 'text',
'label' => __( 'PAN / VAT Number', 'mscf' ),
'placeholder' => __( '9-digit PAN', 'mscf' ),
'required' => false,
'class' => [ 'form-row-wide' ],
'priority' => 25,
'custom_attributes' => [
'maxlength' => '9',
'pattern' => '[0-9]{9}',
],
];
$fields['order']['delivery_note'] = [
'type' => 'textarea',
'label' => __( 'Delivery instructions', 'mscf' ),
'required' => true,
'class' => [ 'form-row-wide' ],
'priority' => 30,
];
return $fields;
} The required flag adds HTML5 validation. WooCommerce also checks empties on required fields. Custom rules still need explicit PHP validation—covered next.
Field types and layout classes
- text, email, tel, number, textarea, select, checkbox, radio — supported natively.
- form-row-first / form-row-last — two columns on desktop.
- form-row-wide — full width.
- priority — controls order within the section; lower numbers appear first.
For Nepal NPR stores, pair custom fields with WooCommerce localization for NPR so labels and currency stay consistent.
How Do You Add Server-Side Validation to WooCommerce Checkout Fields?
Hook woocommerce_checkout_process. Read $_POST, validate, and call wc_add_notice() on failure. WooCommerce stops order creation when error notices exist.
add_action( 'woocommerce_checkout_process', 'mscf_validate_checkout_fields' );
function mscf_validate_checkout_fields() {
$pan = isset( $_POST['billing_pan'] )
? wp_unslash( $_POST['billing_pan'] )
: '';
if ( $pan !== '' && ! preg_match( '/^[0-9]{9}$/', $pan ) ) {
wc_add_notice(
__( 'PAN must be exactly 9 digits.', 'mscf' ),
'error'
);
}
$note = isset( $_POST['delivery_note'] )
? wp_unslash( $_POST['delivery_note'] )
: '';
if ( trim( $note ) === '' ) {
wc_add_notice(
__( 'Delivery instructions are required.', 'mscf' ),
'error'
);
}
if ( strlen( $note ) > 500 ) {
wc_add_notice(
__( 'Delivery note cannot exceed 500 characters.', 'mscf' ),
'error'
);
}
} Test regex patterns in a regex tester before deploying. Match Nepal PAN rules to your accountant's spec—not every store needs PAN at checkout.
Sanitize posted data before save
Filter woocommerce_checkout_posted_data to normalize values early:
add_filter( 'woocommerce_checkout_posted_data', 'mscf_sanitize_posted_data' );
function mscf_sanitize_posted_data( $data ) {
if ( isset( $data['billing_pan'] ) ) {
$data['billing_pan'] = sanitize_text_field( $data['billing_pan'] );
}
if ( isset( $data['delivery_note'] ) ) {
$data['delivery_note'] = sanitize_textarea_field( $data['delivery_note'] );
}
return $data;
} WordPress sanitization functions strip unsafe input. See the WordPress sanitization handbook for field-type mapping.
Where Should Custom Checkout Field Logic Live—Theme, Plugin, or ACF?
Three common approaches exist. Pick based on maintainability, not speed alone.
| Approach | Best for | Validation control | Risk on theme change |
|---|---|---|---|
| Custom plugin | Client stores, multi-site reuse | Full PHP hooks | Low |
| Child theme functions.php | Single-store tweaks | Full PHP hooks | Medium—lost if parent theme breaks |
| ACF / field UI plugins | Non-dev content teams | Limited unless extended | Depends on plugin |
For pure checkout fields, code beats UI plugins. ACF shines on product or page meta—not checkout POST handling. Read ACF vs custom fields comparison for context. On agency builds I default to a small dedicated plugin named after the store.
How Do You Save and Display Custom Checkout Fields on Orders and Emails?
After validation, persist values as order meta. Then surface them in admin, emails, and optionally the REST API.
Save to order meta
add_action(
'woocommerce_checkout_update_order_meta',
'mscf_save_checkout_fields',
10,
2
);
function mscf_save_checkout_fields( $order_id, $data ) {
if ( ! empty( $data['billing_pan'] ) ) {
update_post_meta(
$order_id,
'_billing_pan',
sanitize_text_field( $data['billing_pan'] )
);
}
if ( ! empty( $data['delivery_note'] ) ) {
update_post_meta(
$order_id,
'_delivery_note',
sanitize_textarea_field( $data['delivery_note'] )
);
}
} WooCommerce 11.x still uses post meta for orders on many installs. HPOS (High-Performance Order Storage) uses WC_Order->update_meta_data() instead—check your store setting under WooCommerce → Settings → Advanced → Features.
Show fields in admin order screen
add_action(
'woocommerce_admin_order_data_after_billing_address',
'mscf_display_admin_order_fields',
10,
1
);
function mscf_display_admin_order_fields( $order ) {
$pan = $order->get_meta( '_billing_pan' );
if ( $pan ) {
echo '<p><strong>' . esc_html__( 'PAN:', 'mscf' ) . '</strong> '
. esc_html( $pan ) . '</p>';
}
$note = $order->get_meta( '_delivery_note' );
if ( $note ) {
echo '<p><strong>' . esc_html__( 'Delivery note:', 'mscf' )
. '</strong> ' . esc_html( $note ) . '</p>';
}
} Include the same values in transactional emails via woocommerce_email_order_meta_fields. Fulfilment teams on WooCommerce florist stores rely on email copies when admin access is limited.
How Do You Conditionally Show or Require Checkout Fields?
Business rules often depend on cart contents, shipping zone, or user role. Use woocommerce_checkout_fields with cart inspection—not JavaScript toggles alone.
add_filter( 'woocommerce_checkout_fields', 'mscf_conditional_pan_field' );
function mscf_conditional_pan_field( $fields ) {
$needs_pan = false;
foreach ( WC()->cart->get_cart() as $item ) {
$product = $item['data'];
if ( $product && $product->is_taxable() ) {
$needs_pan = true;
break;
}
}
if ( isset( $fields['order']['billing_pan'] ) ) {
$fields['order']['billing_pan']['required'] = $needs_pan;
if ( ! $needs_pan ) {
unset( $fields['order']['billing_pan'] );
}
}
return $fields;
} Mirror the same rule in woocommerce_checkout_process. Mismatched UI and validation confuses buyers and support staff.
Block checkout for specific shipping methods
Local pickup might need a phone number. Express delivery might need a time slot. Read WC()->session->get('chosen_shipping_methods') inside both the filter and the validation hook.
For payment-specific rules, see WooCommerce custom payment gateway development. Gateway callbacks and checkout fields should agree on required data.
What Advanced Patterns Work for WooCommerce 11.1 in 2026?
Modern stores need more than static text boxes. These patterns appear on production builds I maintain.
- Nonce-safe AJAX validation — validate PAN or coupon eligibility before submit using
wp_ajax_handlers with nonces. Improves UX; still keep server validation on submit. - Block checkout compatibility — Block-based checkout uses different extension points. Classic checkout hooks above remain standard for most custom stores on WooCommerce 11.1.
- HPOS-safe meta — Use
$order->update_meta_data()and$order->save()when custom order tables are enabled. - REST exposure — Mobile apps reading orders need meta registered for the REST API. See WooCommerce REST API for mobile apps.
- Export and reporting — Prefix meta keys with
_for internal fields; document keys for CSV export plugins.
HPOS-compatible save snippet
add_action( 'woocommerce_checkout_create_order', 'mscf_hpos_save_fields', 10, 2 );
function mscf_hpos_save_fields( $order, $data ) {
if ( ! empty( $data['billing_pan'] ) ) {
$order->update_meta_data(
'_billing_pan',
sanitize_text_field( $data['billing_pan'] )
);
}
if ( ! empty( $data['delivery_note'] ) ) {
$order->update_meta_data(
'_delivery_note',
sanitize_textarea_field( $data['delivery_note'] )
);
}
} Official reference: the WooCommerce customise checkout fields documentation covers core field keys. Cross-check hook names against the WooCommerce hooks code reference when upgrading major versions.
Testing checklist before go-live
- Submit with all fields empty—confirm required errors appear.
- Submit malformed PAN, phone, or email—confirm regex messages.
- Complete a valid order—confirm admin and email display.
- Test logged-in and guest checkout.
- Test with caching and page-speed plugins enabled.
- Re-test after WooCommerce or WordPress updates on staging first.
Run through testing and optimization before peak season. Dashain order spikes expose weak validation fast on Nepal stores.
Compare platform trade-offs in Magento vs Shopify vs WooCommerce if checkout complexity pushes you toward another stack. Shopify's model differs—see Shopify checkout extensions for custom fields.
On multi-vendor builds, vendor-specific fields need namespace prefixes to avoid meta collisions. Read WooCommerce multi-vendor marketplace setup before adding global checkout fields.
For order workflow after checkout, tie fields into custom order notifications and refund workflows so ops teams see the same data everywhere.
I've shipped similar patterns on Laravel and WooCommerce grocery stores where delivery zones and notes drive fulfilment. The principle is identical: collect once, validate server-side, display everywhere downstream.
Bulk catalog work stays separate—use CSV product import for SKUs, not checkout fields. Keep checkout code in its own plugin for clean ongoing maintenance.
Key Takeaways
- Register fields with
woocommerce_checkout_fields; never edit WooCommerce core templates. - Validate on
woocommerce_checkout_process—HTML5requiredalone is insufficient. - Sanitize via
woocommerce_checkout_posted_databefore values reach order meta. - Save with order meta APIs compatible with HPOS when custom tables are enabled.
- Display the same values in admin, emails, and exports so fulfilment teams stay aligned.
- Package logic in a dedicated plugin so theme changes do not wipe custom checkout rules.
People Also Ask
Can I add custom checkout fields without a plugin?
Yes. Add code to your child theme's functions.php using the same hooks. A small custom plugin is safer for client handoffs because it survives theme updates and keeps checkout logic isolated from design changes.
Does WooCommerce validate custom fields automatically?
Only basic checks apply—mainly the required flag and type hints like email. Format rules, cross-field logic, and business constraints need custom PHP in woocommerce_checkout_process.
Will custom checkout fields work with WooCommerce Blocks checkout?
Classic hook-based fields target the traditional shortcode checkout. Block checkout uses the Cart and Checkout blocks with different extension APIs. Confirm which checkout your theme renders before deploying custom field code.
How do I show custom checkout field values on the thank-you page?
Hook woocommerce_thankyou or woocommerce_order_details_after_order_table. Read order meta with $order->get_meta() and output escaped values so customers see what was captured.
Ship Checkout Fields That Survive Production Traffic
WooCommerce Custom Checkout Fields with Validation is straightforward when you follow the hook chain: register, sanitize, validate, save, display. Skipping server-side validation is the mistake that creates refund calls and manual order fixes. Start with one required field, test guest and logged-in flows, then expand. Need checkout fields built for a Nepal or international store on WooCommerce 11.1? Contact us or review our WooCommerce portfolio work to see how custom checkout data feeds real fulfilment workflows.
Frequently Asked Questions
0 Comments
Leave a comment
Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

