
There are several reasons you might want to get all WooCommerce orders for a customer in your shop. For example, you may want to find out if they’ve ever purchased a product, or do something as simple as count the number of orders they’ve placed with you.
Since orders are a custom post type, you can use get_posts to query orders, which is a pretty standard WP query that most developers are familiar with and can use. There are a couple things you should note though:
- Most of the time, people query
shop_order
as the post type. You want to usewc_get_order_types()
for the post type instead, as this will ensure that you have all order types available in the shop. Plugins can create their own order types, so this is a must for future-proofing your code. - The
post_status
is also something that’s easy to mess up. Order statuses (processing, completed, etc), are post statuses, so you can’t just used ‘publish’. You also don’t want to hard-code the core WooCommerce statuses, as plugins may have added additional ones. Usearray_keys( wc_get_order_statuses() )
for post statuses instead.
If we want to query orders for a customer, we can check for the _customer_user
meta key (the customer id) in the order, and we’ll get orders that match our customer’s id.
Let’s say we want to get orders for a logged-in customer. The 'meta_key' => '_customer_user'
will be used as part of our query, and we’ll set 'meta_value' => get_current_user_id()
.
$customer_orders = get_posts( array( 'numberposts' => -1, 'meta_key' => '_customer_user', 'meta_value' => get_current_user_id(), 'post_type' => wc_get_order_types(), 'post_status' => array_keys( wc_get_order_statuses() ), ) );
Let’s go through a complete sample that will get the customer orders, count them, and display a notice to our loyal customers on the account page who’ve placed 5 or more orders.
Use Case: Welcome Message for Repeat Customers
Let’s get our current user:
$customer = wp_get_current_user();
And determine what number of orders indicates a “loyal” customer:
$loyal_count = 5;
We’ll then use our query above to get all of the WooCommerce orders for our customer.
As a final step, let’s build a welcome notice for the customer to show on the account page, and only show it if they’ve placed our minimum number of orders:
// Text for our "thanks for loyalty" message $notice_text = sprintf( 'Hey %1$s 😀 We noticed you\'ve placed more than %2$s orders with us – thanks for being a loyal customer!', $customer->display_name, $loyal_count ); // Display our notice if the customer has at least 5 orders if ( count( $customer_orders ) >= $loyal_count ) { wc_print_notice( $notice_text, 'notice' ); }
Now to complete it, let’s put all of this together and add it to the My Account page:
function wc_get_customer_orders() { // Get all customer orders $customer_orders = get_posts( array( 'numberposts' => -1, 'meta_key' => '_customer_user', 'meta_value' => get_current_user_id(), 'post_type' => wc_get_order_types(), 'post_status' => array_keys( wc_get_order_statuses() ), ) ); $customer = wp_get_current_user(); // Order count for a "loyal" customer $loyal_count = 5; // Text for our "thanks for loyalty" message $notice_text = sprintf( 'Hey %1$s 😀 We noticed you\'ve placed more than %2$s orders with us – thanks for being a loyal customer!', $customer->display_name, $loyal_count ); // Display our notice if the customer has at least 5 orders if ( count( $customer_orders ) >= $loyal_count ) { wc_print_notice( $notice_text, 'notice' ); } } add_action( 'woocommerce_before_my_account', 'wc_get_customer_orders' );
If the customer has placed more than 5 orders in the shop, a thank you message will be displayed:
If not, they’ll see nothing 🙂
Thanks Beka, Just what I was looking for. Very well explained.
Could this function be used to display a message if there are no orders? Like “No orders at this time? Could you write an example please?
Thanks,
Sure, instead of checking:
if ( count( $customer_orders ) >= $loyal_count )
you could check for no orders:
if ( ! count( $customer_orders ) )
hi.
how would we check for customers that arent logged in. Anyway to determine the number of orders based on the email used for payment?
You could probably change the meta key to billing email instead of the customer and work from there 🙂
Hi
Nice post, i have a question:
I wonder if there so you can see the last order created by customer and place the order button again, something like the easyorder dominos pizza, this page show a button like same
Hawain PIZZA
ORDER AGAIN
and redirects directly to the cart , I have no knowledge of php but I’ve tried to learn and do but can not find the way.
if I could help I would appreciate it a lot
thanks
This is present on the “View order” page already 🙂 While logged in as a customer, look at a completed order. You’ll see “Order again” as a button once an order is completed.
Hello there,
Is there a way to retrieve the total money spent by a user in all orders? THis way we can show a message to the customer with the total money spent and possibly reward the customer somehow.
Thanks.
Yep, WooCommerce has a way to do this — check out the customer list report as an example.
Hi thanks for the hint, very useful. However i have done a quick test putting in the my-orders.php this:
And the sum only seems to take into account the decimals of the last order. For example in an order with the following totals:
#BE14268 March 8, 2016 Completed 168.21 € for 2 items
#BE14267 March 8, 2016 Completed 401.78 € for 5 items
#BE14266 March 8, 2016 Completed 86.96 € for 1 item
#BE14265 March 8, 2016 Completed 401.78 € for 5 items
The total shown by the test is: 1056.21, so it only takes the decimals of the last order.
Any dea of why this strange behaviour?
Thanks.
hmm not something I’ve seen. Maybe it’s the
wc_price()
part? can you replicate it on a completely vanilla install with just WC? definitely odd behavior.Hi ,this post was great that give me a basic concept of listing orders of specific user.
But ,how can I use this code in my web site and where to put it? in my theme or my wc plugin files?
Doesn’t this take cancelled orders into account as well?
They way it’s currently written uses all order statuses —
'post_status' => array_keys( wc_get_order_statuses() ),
You could limit this to use your own array of statuses instead if you wanted to include / exclude certain ones.
Hello Beka and thank you for this tutorial, really great.
However i try to achieve something and as i am not a coder, it’s quite hard for me.
I have specific” thank you” pages depend of product user purchased. I want to display on this thank you page the name of the product he just baught and specific cross sell products.
I was thinking to use your code to display the last purchase of the current login user
Thank you
Hi Richard, that’s no easy feat. I’d recommend checking out this plugin that lets you change the thank you page based on what’s purchased.
Hi Beka, i really love this so thank you
i was wondering if it could be set so it only count the order if it has a value above 00.00 i do not want the items that user get free to count
Hi Beka. First, thanks for the great post!
Is there a way to show on the “new order” e-mail that I get when a customer makes a new order how many orders this customer has? Should I just use the code “$customer_orders” on the e-mail body?
Or should I use something like:
// Get all customer orders
$customer_orders = get_posts( array(
‘numberposts’ => -1,
‘meta_key’ => ‘_customer_user’,
‘meta_value’ => get_current_user_id(),
‘post_type’ => wc_get_order_types(),
‘post_status’ => array_keys( wc_get_order_statuses() ),
) );
$customer = wp_get_current_user();
You could do it, but not quite as straightforward. You don’t have access to the customer directly in the email; you only have access to the order the email is for (depending on which action you hook into), so you’d have to get the customer data from the order instead. Using the
$order->billing_email
as the meta to query for could probably work.Hi Beka,
Nice tutorial.
This will give the loyal customer with order count. But can you please help me to find loyal customer whose total purchase is $100 till now.
Thanks in Advance
Sweety
Where exactly do we write this? I never understood the “code” thing in pages. I am a computer tech myself but these templates allowed me to make this page without using a single line of code. Where do I write this code and where do I get the results in?
Is there way to show that logged in user can see only his/her recent order.
Currently order is visible to every one.
hello Beka
Is there a way to show that recent order will visible only for that user who is placed order.
currently Recent order is visible for everyone
hi beka
how to show orders for one user?
Hi Beka,
Instead of comparing count against loyal_count, is there a way to display the total number of orders instead?
” You have placed a total of x orders” ..
Thanks!