Skip to main content

Custom Checkout Fields

Overview​

Custom Checkout Fields adds fields to WooCommerce's checkout: a delivery instruction, a VAT number, a purchase-order reference, a date the customer needs the order by. Each field declares where it belongs, whether it is required, how it is validated, and the conditions under which it appears at all.

The values are stored against the order in the module's own table and shown wherever the order is — the admin order screen, the customer's order detail page, and the order emails.

A layout can be saved so the arrangement of the checkout form is itself a stored, switchable thing rather than a set of individual field positions.

It is for stores that need to collect something WooCommerce's checkout does not ask for.

Availability​

ItemValue
Module keycheckout
TierPremium
Entitlement keycheckout
Admin tabcheckout
Enabled optionaiowc_module_enabled_checkout (off until turned on)
REST namespaceaiowc/v1

Enabling the module creates the three tables below, seeds the defaults and schedules the cleanup job.

registerHooks() performs no licence check of its own; the module registry applies the entitlement gate centrally before calling it.

Settings​

Stored in the bundled option row aiowc_co_settings. The defaults are produced by a method rather than declared as a constant, because one of them is JSON-encoded at runtime.

Stored keyDefaultMeaning
field_positions["billing","shipping","order"]The sections fields may be placed in, stored as a JSON string.
enable_field_validationtrueWhether the module's own validation rules are applied.
enable_conditional_logictrueWhether conditional rules are evaluated.

Fields​

FieldMeaning
field_keyThe stable key the value is stored under.
labelThe label shown to the customer.
field_typeThe control used. Defaults to text.
placeholderPlaceholder text for the control.
requiredWhether checkout refuses to proceed without it.
sectionbilling, shipping or order. Defaults to billing.
positionWhere within that section the field sits. Defaults to after_billing_form.
priorityThe order fields appear in.
optionsThe choices, for a field type that has them. Stored as JSON.
conditional_rulesWhen the field is shown. Stored as JSON.
validation_rulesHow a submitted value is checked. Stored as JSON.
enabledWhether the field is on the form at all.

Layouts​

A layout is a named, stored arrangement of the checkout form, with is_active deciding which one is in force — and no layout is active by default, so a store that has not chosen one gets the field-by-field positions rather than a layout.

Validation​

Validation runs on woocommerce_after_checkout_validation, so a value that fails is reported with the rest of WooCommerce's own checkout errors rather than in a separate pass. The module also exposes POST /checkout/validate for checking a value before submission, which is what allows the form to report a problem as the customer types.

Admin screen​

The Checkout tab defines the fields — creating, editing, deleting and reordering them — manages layouts, and edits the module's settings. An overview endpoint backs a summary of what is configured, and each field's collected values can be inspected from the same screen.

REST API endpoints​

All routes are on aiowc/v1 and answer with the { success, data, message } envelope. Every route requires manage_woocommerce except /checkout/validate.

MethodPathPurpose
GET/checkout/fieldsEvery field definition.
POST/checkout/fieldsCreate a field.
GET/checkout/fields/{id}One field.
PATCH / PUT /POST/checkout/fields/{id}Update a field. All three verbs are registered.
DELETE/checkout/fields/{id}Delete a field.
GET/checkout/fields/{id}/valuesThe values collected for one field.
POST/checkout/fields/reorderReorder the fields.
GET/checkout/overviewA summary of the configured checkout.
GET / PATCH / PUT / POST/checkout/settingsRead and write the module's settings.
POST/checkout/validateValidate a value before submission. Nonce, rate-limited.

These sit under /checkout/, while the separate Multi-Step Checkout module owns /checkout/steps/ and its own step routes, so neither shadows the other.

WooCommerce integration​

HookWhat the module does
woocommerce_checkout_fieldsAdds the configured fields to the checkout form.
woocommerce_billing_fields / woocommerce_shipping_fieldsPlaces fields inside those two sections.
woocommerce_before_checkout_form / _after_checkout_formRenders fields positioned outside the standard sections.
woocommerce_after_checkout_validationApplies the validation rules alongside WooCommerce's own.
woocommerce_checkout_create_orderStores the submitted values against the order.
woocommerce_admin_order_data_after_billing_address / _shipping_addressShows the values on the admin order screen.
woocommerce_order_details_after_order_tableShows them on the customer's order page.
woocommerce_email_after_order_tableAdds them to the order emails.
wp_enqueue_scripts, wp_footerLoads the conditional-logic and validation assets.

Database schema​

TableHolds
{prefix}aiowc_checkout_fieldsThe field definitions: key, label, type, placeholder, required flag, section and position, priority, options, conditional and validation rules as JSON, enabled flag.
{prefix}aiowc_checkout_layoutsNamed form layouts, one of which may be active, with the arrangement stored as its configuration.
{prefix}aiowc_checkout_field_valuesOne row per value collected: the field, the order, and the value.

The fields table is named aiowc_checkout_fields. The separate Multi-Step Checkout module keeps its own field table under an msc_ prefix, so the two never share a row.

Background jobs​

HookIntervalWork
aiowc_checkout_field_cleanupdailyDeletes collected values whose field definition no longer exists.

The job runs on Action Scheduler, in the aiowc group.

Action hooks for integrators​

HookFired when
aiowc_track_eventThe module is enabled or disabled.

The module exposes no filter for adding a field type or a validation rule.

Entitlement limits​

checkout is an on/off grant with no cap on the number of fields, layouts or stored values.

Health check​

The module reports a warning when its tables are missing or WooCommerce is inactive, and otherwise reports that it is functioning normally. A disabled module reports that it is disabled.

Known gaps​

  • Two modules filter woocommerce_checkout_fields — this one and Multi-Step Checkout. With both enabled they both modify the same field array, and nothing coordinates the result or warns that both are active.
  • No layout is active by default, so the layout feature does nothing until one is explicitly chosen — which is easy to read as the feature not working.
  • There is no filter for field types or validation rules, so anything the module does not already implement requires modifying it.
  • Deleting a field deletes the values collected under it, including those belonging to completed orders, so what a past customer entered is lost with the definition. There is no confirmation of that consequence and no export first.
  • Trashing an order does not remove its checkout field values; permanently deleting it does. That is deliberate — a trashed order can be restored, and these values cannot be recovered once deleted, so removing them on trash would destroy data the store still believes it has. Emptying the trash deletes them.

Changed on 2026-09-13​

This page previously recorded that deleting an order did not remove its checkout field values — the repository had a delete-by-order method with no caller, and the cleanup job only removed values orphaned by a deleted field, which is a different question. Permanent order deletion now removes them, for orders in wp_posts and orders in the HPOS tables alike. It is named rather than silently dropped because this page published it, and because it changes what a data-retention answer should say.