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 use wc_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. Use array_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:

WooCommerce loyalty message

If not, they’ll see nothing 🙂

Published by Beka Rice

Beka leads product direction for SkyVerge, focusing on new features for our plugins and Jilt. She spends a lot of time on research and interviews, but likes to write so she has an excuse to spend more time jamming out to anything from The Clash to Lady Gaga.

25 Comments

  1. Thanks Beka, Just what I was looking for. Very well explained.

  2. 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,

  3. 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?

  4. 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.

  5. 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.

  6. 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.

  7. 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?

  8. 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.

  9. 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

  10. 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

  11. 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.

  12. 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

  13. 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?

  14. Is there way to show that logged in user can see only his/her recent order.
    Currently order is visible to every one.

  15. 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

  16. hi beka
    how to show orders for one user?

  17. 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!

Hmm, looks like this article is quite old! Its content may be outdated, so comments are now closed.