I have a custom field on my WooCommerce single product. It sends to the cart fine, it displays on checkout fine, it shows in the order in the dashboard fine.
What I am now trying to do is set the value as a custom field in the order page so I am able to amend the text when I need to. For some reason when I submit the form this step isn’t working.
The code that i use in my functions.php
file:
// Add the field to the product add_action('woocommerce_before_add_to_cart_button', 'my_custom_checkout_field'); function my_custom_checkout_field() { echo '<div id="my_custom_checkout_field"><h3>'.__('My Field').'</h3>'; echo '<label>fill in this field</label> <input type="text" name="my_field_name">'; echo '</div>'; } // Store custom field function save_my_custom_checkout_field( $cart_item_data, $product_id ) { if( isset( $_REQUEST['my_field_name'] ) ) { $cart_item_data[ 'my_field_name' ] = $_REQUEST['my_field_name']; /* below statement make sure every add to cart action as unique line item */ $cart_item_data['unique_key'] = md5( microtime().rand() ); } return $cart_item_data; } add_action( 'woocommerce_add_cart_item_data', 'save_my_custom_checkout_field', 10, 2 ); // Render meta on cart and checkout function render_meta_on_cart_and_checkout( $cart_data, $cart_item = null ) { $custom_items = array(); /* Woo 2.4.2 updates */ if( !empty( $cart_data ) ) { $custom_items = $cart_data; } if( isset( $cart_item['my_field_name'] ) ) { $custom_items[] = array( "name" => 'My Field', "value" => $cart_item['my_field_name'] ); } return $custom_items; } add_filter( 'woocommerce_get_item_data', 'render_meta_on_cart_and_checkout', 10, 2 ); // Display as order meta function my_field_order_meta_handler( $item_id, $values, $cart_item_key ) { if( isset( $values['my_field_name'] ) ) { wc_add_order_item_meta( $item_id, "my_field_name", $values['my_field_name'] ); } } add_action( 'woocommerce_add_order_item_meta', 'my_field_order_meta_handler', 1, 3 ); /** THIS IS WHERE I'M STUCK **/ add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process'); function my_custom_checkout_field_process() { global $woocommerce; // Check if set, if its not set add an error. This one is only requite for companies if ($_POST['billing_company']) if (!$_POST['my_field_name']) $woocommerce->add_error( __('Please enter your XXX.') ); } // Update the user meta with field value add_action('woocommerce_checkout_update_user_meta', 'my_custom_checkout_field_update_user_meta'); function my_custom_checkout_field_update_user_meta( $user_id ) { if ($user_id && $_POST['my_field_name']) update_user_meta( $user_id, 'my_field_name', esc_attr($_POST['my_field_name']) ); } // Update the order meta with field value add_action('woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta'); function my_custom_checkout_field_update_order_meta( $order_id ) { if ($_POST['my_field_name']) update_post_meta( $order_id, 'My Field', esc_attr($_POST['my_field_name'])); }
Screenshot of what currently happens:
What I would like to happen:
Any help would be greatly appreciated.
Advertisement
Answer
Updated: compatibility with Woocommerce version 3+
You have missing the function to display this custom field value on the order edit page:
/** * Display field value on the order edit page */ add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 ); function my_custom_checkout_field_display_admin_order_meta( $order ){ $order_id = method_exists( $order, 'get_id' ) ? $order->get_id() : $order->id; echo '<p><strong>'.__('My Field Name').':</strong> ' . get_post_meta( $order_id, 'my_field_name', true ) . '</p>'; }
On the reference link below, you have all original wooThemes functional working code snippets. It’s an excellent fully functional tutorial.
Reference: [Customizing checkout fields using actions and filters][1]
Edit: Get a custom label displayed with your custom field value in Order item meta
To get a custom label like “MY field name” with your custom field value (in order items meta) instead of a slug like my_field_name, refer to this treads: