How Do I Add Custom Fields to a WooCommerce Subscription?
How It Works
WooCommerce's checkout field hooks (woocommerce_checkout_fields and the associated save/display hooks) work regardless of whether the cart contains a subscription product. The extra step for subscriptions is deciding whether the custom field's value is a one-time thing (only relevant to the initial order) or something that should persist and be visible on every future renewal order too.
// Save a custom field's value onto the subscription itself, not just
// the initial order, so it's accessible on every future renewal.
add_action( 'woocommerce_checkout_update_order_meta', function( $order_id ) {
if ( ! isset( $_POST['custom_reference_field'] ) ) {
return;
}
$value = sanitize_text_field( $_POST['custom_reference_field'] );
update_post_meta( $order_id, '_custom_reference_field', $value );
foreach ( wcs_get_subscriptions_for_order( $order_id ) as $subscription ) {
$subscription->update_meta_data( '_custom_reference_field', $value );
$subscription->save();
}
} );
Things Easy to Miss
- Saving the value only on the initial order, then finding it's not accessible from renewal orders later, since a renewal order doesn't automatically inherit the parent order's custom meta.
- Not displaying the saved value anywhere useful, like the subscription's admin screen or the customer's My Account view, after going through the trouble of capturing it.
- Skipping sanitization and validation on the field, the same as any checkout field — this matters as much here as anywhere else user input reaches the database.
- Forgetting the field for the resubscribe and switch flows, which are separate checkout-adjacent processes that might not carry the same custom field logic unless explicitly handled.
Implementing It Properly
- Decide explicitly whether the field's value needs to persist to the subscription itself or is only relevant to the specific order it was entered on.
- If it needs to persist, save it onto the subscription's own meta, not just the parent order's, so every renewal can reference it.
- Display the value somewhere admins and customers can actually see it — the subscription admin screen, order emails, or My Account, depending on who needs it.
- Test the field's behavior through resubscribe and switch flows if those are relevant to your store, not just the initial checkout.
Need custom checkout fields built and properly wired through to renewals? See custom WooCommerce development.