Introduction
In WooCommerce development, you often need to add extra information to orders, such as internal reference numbers, special customer requests, or tracking codes. Storing this information in custom order fields and displaying it in the admin order details page (within a meta box) is standard practice. This guide explains how to implement this securely and maintainably using official WooCommerce action and filter hooks.
Core Concepts & Steps
The process involves two main steps:
- Add a custom field input: Create a form field within the order details edit page (typically inside the "Order Data" meta box) for admin input.
- Save and display the field value: Securely save the admin input and display it in an appropriate location on the order details page.
We'll use two core WooCommerce hooks: woocommerce_admin_order_data_after_order_details and woocommerce_process_shop_order_meta.
Complete Implementation Code
Add the following code to your theme's functions.php file or a custom plugin. Using a child theme or custom plugin is recommended for update safety.
/**
* Add custom field to the admin order details meta box.
*
* @param WC_Order $order Current order object.
*/
function add_custom_order_field_to_admin($order) {
$custom_field_value = $order->get_meta('_my_custom_field', true);
echo '<div class="order_data_column">';
echo '<h4>Custom Information <span>(Optional)</span></h4>';
woocommerce_wp_text_input(array(
'id' => '_my_custom_field',
'label' => 'Internal Reference / Note:',
'value' => $custom_field_value,
'wrapper_class' => 'form-field-wide',
'description' => 'For internal use only, e.g., special project ID.'
));
echo '</div>';
}
add_action('woocommerce_admin_order_data_after_order_details', 'add_custom_order_field_to_admin');
/**
* Save the custom field value.
*
* @param int $order_id Order ID.
*/
function save_custom_order_field($order_id) {
if (!current_user_can('edit_shop_orders')) {
return;
}
if (isset($_POST['_my_custom_field'])) {
$order = wc_get_order($order_id);
$custom_field_value = sanitize_text_field($_POST['_my_custom_field']);
$order->update_meta_data('_my_custom_field', $custom_field_value);
$order->save();
}
}
add_action('woocommerce_process_shop_order_meta', 'save_custom_order_field', 10, 1);
/**
* (Optional) Display the saved field value elsewhere in the admin.
*/
function display_custom_field_on_order_admin($order) {
$custom_field_value = $order->get_meta('_my_custom_field', true);
if (!empty($custom_field_value)) {
echo '<div class="order_data_column" style="width:100%; margin-top:20px;">';
echo '<h4>Internal Reference</h4>';
echo '<p><strong>Reference / Note:</strong> ' . esc_html($custom_field_value) . '</p>';
echo '</div>';
}
}
add_action('woocommerce_admin_order_items_after_line_items', 'display_custom_field_on_order_admin');
Code Explanation & Best Practices
1. Adding the Field
- Hook:
woocommerce_admin_order_data_after_order_detailsruns after the "Order Data" meta box, making it ideal for adding fields. - Data Retrieval: Use
$order->get_meta('_my_custom_field', true)to fetch saved values. This is the recommended method for WooCommerce CRUD objects. - Field Creation: The
woocommerce_wp_text_input()helper function generates a text input consistent with the admin UI. Thewrapper_class: 'form-field-wide'parameter makes the field full-width.
2. Saving the Field
- Hook:
woocommerce_process_shop_order_metatriggers when the order is saved. - Security Check: Always verify permissions with
current_user_can('edit_shop_orders'). - Data Sanitization & Storage: Check if the field is submitted with
isset(), sanitize input usingsanitize_text_field(), then save using$order->update_meta_data()and$order->save().
3. (Optional) Displaying the Value
The third function shows how to display the saved value as read-only text elsewhere on the order details page. You can adjust the hook and HTML as needed.
Advanced Usage & Extensions
- Field Types: WooCommerce provides other helper functions:
woocommerce_wp_textarea_input()for textareas,woocommerce_wp_select()for dropdowns, andwoocommerce_wp_checkbox()for checkboxes. - Data Retrieval: Use
$order->get_meta('_my_custom_field')anywhere to access the saved value. - Naming Convention: Prefix custom field keys with an underscore (e.g.,
_my_custom_field). This often indicates a "protected" field that may be hidden in default exports, aligning with WooCommerce conventions.
Important Notes
- Backup: Always back up your site before editing
functions.php. - Plugin Approach: For complex features or cross-theme use, encapsulate the code in a custom plugin.
- Data Export: To include this field in CSV order exports, you may need additional filters like
woocommerce_shop_order_export_column_names. - Field Key: Replace
_my_custom_fieldwith your own descriptive, unique key.
By following these steps and best practices, you can robustly add and manage custom fields for WooCommerce orders, seamlessly extending admin functionality.