
Show customer order history in the WooCommerce order detail page
When managing orders in WooCommerce, sometimes you need more context: has this customer ordered before? How often? Do they usually cancel? Having that information visible can help you make better decisions.
In this article, I’ll show you how to add a custom metabox to the order edit screen, displaying all other orders from the same customer, with the most important fields: ID (with link), Order Number, Date, Status, and Total. All of this with a simple snippet—no plugins needed.
What we’re building
At the end of this tutorial, when viewing a WooCommerce order placed by a registered user, you’ll see a box like this on the right sidebar:
|----------------------------------------------------------| | ID | Order No. | Date | Status | Total | |-------|-----------|------------|-------------|-----------| | #123 | 123 | 2024-12-10 | Completed | $50.00 | | #100 | 100 | 2024-10-02 | Cancelled | $30.00 | | #91 | 91 | 2024-09-15 | Processing | $75.99 |
The snippet
Paste this code into your child theme’s functions.php
file or into a custom plugin:
<?php add_action( 'add_meta_boxes', 'addCustomerOrderHistoryMetabox' ); function addCustomerOrderHistoryMetabox() { add_meta_box( 'customer_order_history', 'Customer Order History', 'renderCustomerOrderHistoryMetabox', 'shop_order', 'side', 'default' ); } function renderCustomerOrderHistoryMetabox( $post ) { $order = wc_get_order( $post->ID ); $customerId = $order->get_customer_id(); if ( ! $customerId ) { echo '<p>This order has no assigned customer.</p>'; return; } $customerOrders = wc_get_orders( [ 'customer_id' => $customerId, 'exclude' => [ $order->get_id() ], 'limit' => -1, 'orderby' => 'date', 'order' => 'DESC', 'return' => 'ids' ] ); if ( empty( $customerOrders ) ) { echo '<p>This customer has no other orders.</p>'; return; } echo '<table style="width: 100%; font-size: 12px;">'; echo '<thead><tr> <th>ID</th> <th>Order No.</th> <th>Date</th> <th>Status</th> <th>Total</th> </tr></thead><tbody>'; foreach ( $customerOrders as $orderId ) { $pastOrder = wc_get_order( $orderId ); $orderLink = get_edit_post_link( $pastOrder->get_id() ); $orderIdHtml = '<a href="' . esc_url( $orderLink ) . '">#' . esc_html( $pastOrder->get_id() ) . '</a>'; $orderNumber = $pastOrder->get_order_number(); $orderDate = $pastOrder->get_date_created() ? $pastOrder->get_date_created()->date( 'Y-m-d' ) : '-'; $orderStatus = wc_get_order_status_name( $pastOrder->get_status() ); $orderTotal = $pastOrder->get_formatted_order_total(); echo '<tr> <td>' . $orderIdHtml . '</td> <td>' . esc_html( $orderNumber ) . '</td> <td>' . esc_html( $orderDate ) . '</td> <td>' . esc_html( $orderStatus ) . '</td> <td>' . $orderTotal . '</td> </tr>'; } echo '</tbody></table>'; }
Code Explanation
add_meta_box
: Adds a custom metabox to the order edit screen.get_customer_id()
: Retrieves the user ID who placed the current order (if registered).wc_get_orders()
: Fetches all other orders from the same customer, excluding the current one.get_order_number()
: Returns the actual order number, which may differ from the ID if you’re using plugins like Sequential Order Numbers.get_edit_post_link()
: Provides the admin URL to edit the selected order.get_date_created()
: Gets the order’s creation date (formatted for display).wc_get_order_status_name()
: Converts the internal status slug (completed
,cancelled
, etc.) to a readable label like “Completed” or “Cancelled”.get_formatted_order_total()
: Displays the order total with currency formatting.- Simple HTML Table: Keeps the UI clean and compact inside the admin sidebar.
Final result
This metabox gives you quick insight into the customer’s behavior—whether they’re a frequent buyer, a new client, or someone who often cancels. A small improvement that can really help in stores where customer history matters (like custom products, returns, or support-heavy shops).