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.phpfile 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).




