Show Customer Notes and Private Order Notes on the WooCommerce Orders List
The WooCommerce admin orders list is dense, but two pieces of information are missing from the default columns: the customer note left during checkout, and any private notes your team has added to the order. To see either, you have to open the order. For stores processing dozens or hundreds of orders a day, that’s a real cost.
The snippet below adds two new columns to the orders list: Customer note (the message customers type at checkout) and Private note (internal notes added by your team, excluding system-generated ones). Each cell shows a small icon when the order has a note, and the full text appears on hover. The dash – shows for orders with no notes. Works on both High-Performance Order Storage (HPOS) and the legacy shop_order post type.
/**
* Add a "Customer note" column to the WooCommerce orders list.
* Shows a hover tooltip with the checkout note when present.
*/
add_filter('manage_woocommerce_page_wc-orders_columns', 'carticy_add_customer_note_column', 10);
add_filter('manage_shop_order_posts_columns', 'carticy_add_customer_note_column', 10);
function carticy_add_customer_note_column($columns)
{
$columns['customer_note'] = __('Customer note', 'woocommerce');
return $columns;
}
add_action('manage_woocommerce_page_wc-orders_custom_column', 'carticy_show_customer_note_column', 10, 2);
add_action('manage_shop_order_posts_custom_column', 'carticy_show_customer_note_column', 10, 2);
function carticy_show_customer_note_column($column, $order)
{
if ('customer_note' !== $column) {
return;
}
if (is_numeric($order)) {
$order = wc_get_order($order);
}
$note = $order ? $order->get_customer_note() : '';
if (!empty($note)) {
echo '<span class="note-on tips" data-tip="' . esc_attr(wc_sanitize_tooltip($note)) . '">' . esc_html__('Yes', 'woocommerce') . '</span>';
} else {
echo '<span class="na">–</span>';
}
}
Pair it with the private notes column below. The two snippets are independent, so you can install just one if you only need that side.
/**
* Add a "Private note" column showing internal notes
* (excludes system-generated notes like "Order status changed").
*/
add_filter('manage_woocommerce_page_wc-orders_columns', 'carticy_add_private_note_column', 10);
add_filter('manage_shop_order_posts_columns', 'carticy_add_private_note_column', 10);
function carticy_add_private_note_column($columns)
{
$columns['private_note'] = __('Private note', 'woocommerce');
return $columns;
}
add_action('manage_woocommerce_page_wc-orders_custom_column', 'carticy_show_private_note_column', 10, 2);
add_action('manage_shop_order_posts_custom_column', 'carticy_show_private_note_column', 10, 2);
function carticy_show_private_note_column($column, $order)
{
if ('private_note' !== $column) {
return;
}
$order_id = is_numeric($order) ? $order : $order->get_id();
$notes = wc_get_order_notes(array(
'order_id' => $order_id,
'type' => 'internal',
));
// Exclude system notes so the column only shows real human-added notes
$human_notes = array_filter($notes, function ($note) {
return $note->added_by !== 'system';
});
if (empty($human_notes)) {
echo '<span class="na">–</span>';
return;
}
$tip = array_reduce($human_notes, function ($carry, $note) {
return $carry . esc_html($note->content) . ' — ' . esc_html($note->added_by) . "\n\n";
}, '');
echo '<span class="note-on dashicons dashicons-welcome-write-blog tips" data-tip="' . esc_attr(wc_sanitize_tooltip($tip)) . '"></span>';
}
Why the Double Filter Set
WooCommerce stores can run on two different order storage backends. HPOS uses dedicated database tables and surfaces an admin page at admin.php?page=wc-orders. Legacy stores use the WordPress posts table and surface the list at edit.php?post_type=shop_order. Each backend uses a different set of filter/action names, so each snippet registers itself twice. If you’re sure your store is HPOS-only, you can drop the manage_shop_order_posts_* and manage_shop_order_posts_custom_column pairs, but leaving them in is harmless and makes the code portable.
Filtering Out System Notes
WooCommerce adds an internal note every time an order changes status, gets refunded, has tracking added, or hits a payment hook. If you displayed every internal note, the column would mostly show automated chatter. The added_by !== 'system' filter strips those out so the column only shows notes a real person typed.
Verification
- Add either or both snippets to your child theme’s
functions.phpor a custom plugin - Place a test order on the frontend and leave a note in the “Order notes” field at checkout
- Open the order in admin and add an internal note from the order notes panel
- Go to WooCommerce > Orders and confirm both new columns appear with icons on the test order
- Hover the icons and confirm the note content appears in the tooltip
Need Help?
Learn how to add custom code to WordPress or reach out for custom development help.
About the Author
More Code Snippets
-
Reorder the Columns on the WooCommerce Orders List
Put your WooCommerce orders list columns in whatever order works…
-
Set the Default Country on WooCommerce Checkout
Pre-fill the WooCommerce checkout country (and optionally state) dropdown with…
-
Bulk Delete Expired Unused WooCommerce Coupons (Batched, Safe)
One-time bulk cleanup utility for stores with thousands of expired,…