I'm using the following code to save the value of a hidden input field having as attribute name "custom_form_data":
add_action('woocommerce_checkout_update_order_meta', 'save_custom_form_data_to_order');
function save_custom_form_data_to_order($order_id) {
if (isset($_POST['custom_form_data'])) {
$custom_form_data = sanitize_text_field($_POST['custom_form_data']);
update_post_meta($order_id, 'custom_form_data', $custom_form_data);
}
}
But the submitted value is not saved to the database. I Checked on wp_postmeta
and wp_wc_orders_meta
tables.
Why is woocommerce_checkout_update_order_meta
hook not working?
This can be related to 2 different things:
Note that High-Performance Order Storage (HPOS) is now enabled by default.
If HPOS is enabled, you need to use instead a compatible hook, like:
add_action('woocommerce_checkout_create_order', 'save_custom_form_data_to_order');
function save_custom_form_data_to_order( $order ) {
if ( isset($_POST['custom_form_data']) ) {
$order->update_meta_data( 'custom_form_data', sanitize_text_field($_POST['custom_form_data']) );
}
}
Or you could use alternatively the following (requires using the save()
method):
add_action('woocommerce_checkout_order_created', 'save_custom_form_data_to_order');
function save_custom_form_data_to_order( $order ) {
if ( isset($_POST['custom_form_data']) ) {
$order->update_meta_data( 'custom_form_data', sanitize_text_field($_POST['custom_form_data']) );
$order->save();
}
}
With HPOS, WordPress Post meta functions doesn't work any more as WooCommerce orders use custom database tables for better performances.
So HPOS requires to use WC_Data
, WC_Abstract_Order
or WC_Order
methods on the WC_Order
object.
So to get/read the value from your custom field, you will use something like:
$order = wc_get_order( $order_id ); // If needed get the WC_Order object
$value = $order->get_meta('custom_form_data'); // Get custom field value
Note that Checkout Blocks is now enabled by default, and only allows very few customizations.
The following action hooks won't work when using Checkout Blocks:
woocommerce_checkout_create_order
(compatible with HPOS)woocommerce_checkout_update_order_meta
woocommerce_checkout_order_created
(compatible with HPOS)The alternative is to switch back to legacy classic Checkout (shortcode).