WooCommerce – Get the number of orders by a given customer

I need to find that a particular customer has done business with that store previously.

To achieve that I need to find the number of orders by a given customer.

Read More

How can I achieve that?

I tried Googling, but did not find any solution.

Related posts

4 comments

  1. Just drop in the user id and you’ll get your total number of orders:

    $numorders = wc_get_customer_order_count( $userid );
    

    To go a step further for my own purposes, I use this code to get the number of a customer’s non-cancelled orders since I don’t want to count failed order attempts:

    // Get TOTAL number of orders for customer
    $numorders = wc_get_customer_order_count( $userid );
    
    // Get CANCELLED orders for customer
    $args = array(
        'customer_id' => $userid,
        'post_status' => 'cancelled',
        'post_type' => 'shop_order',
        'return' => 'ids',
    );
    $numorders_cancelled = 0;
    $numorders_cancelled = count( wc_get_orders( $args ) ); // count the array of orders
    
    // NON-CANCELLED equals TOTAL minus CANCELLED
    $num_not_cancelled = $numorders - $numorders_cancelled;
    
  2. Modifying @MarkPraschan Code, which works well for me without throwing any notice, as i got 2 notice about undefined variable $user_id and i’m not passing the code through a function. Using below code worked for me (which gets the number of order transaction minus canceled orders);

    $current_user = wp_get_current_user();
    $numorders = wc_get_customer_order_count( $current_user->ID );
    // Get CANCELLED orders for customer
    $args = array(
        'customer_id' => $current_user->ID,
        'post_status' => 'cancelled',
        'post_type' => 'shop_order',
        'return' => 'ids',
    );
    $numorders_cancelled = 0;
    $numorders_cancelled = count( wc_get_orders( $args ) ); // count the array of orders
    
    // NON-CANCELLED equals TOTAL minus CANCELLED
    $num_not_cancelled = $numorders - $numorders_cancelled;
    

    if you intend to display both completed and non completed orders, you will use the first two line of the above code, which is;

    $current_user = wp_get_current_user();
    $numorders = wc_get_customer_order_count( $current_user->ID );
    

    Tested and working on;
    WP = v4.9.9
    WC = v3.5.3

  3. I know this is an old question, but thought I’d share my code/info anyways.

    The customer will be connected to the order via the postmeta key _customer_user in the wp_postmeta table.

    You can lookup all orders with the status completed and processing for a specific user ID with the following query, where 279 is the user ID:

    SELECT COUNT(p.ID)
    FROM wp_posts AS p
    INNER JOIN wp_postmeta AS m ON m.post_id = p.ID AND m.meta_key = '_customer_user' AND m.meta_value = 279
    WHERE p.post_status IN ('wc-completed', 'wc-processing') AND p.post_type = 'shop_order'
    

    When translated into PHP code that can be used on any WP installation simply by placing the code at the bottom of your theme functions.php file.

    This example displays the total orders for a customer on the order page in the back-end of WordPress, directly below the customer selection/dropdown. For instance if you need to know if this is the first order a customer has placed/done you can display a message. Obviously you will want to change the order status filter to something that suits your needs. Doing a direct query like below is more efficient I believe.

    // Hook into the order back-end WooCommerce > Orders > [Edit]
    // The output will be placed under the dropdown to choose/connect a customer to the order
    add_action('woocommerce_admin_order_data_after_order_details', 'f4d_customer_order_count');
    function f4d_customer_order_count($order){
        global $wpdb;
        // Retrieve customer ID based on current order
        $customerId = $order->get_customer_id();
        // When the order was placed by a guest, just return
        if($customerId===0) return;
        // When the order is connected to a user/customer, query the total orders
        // Database tables we will use in our query (also grab the table prefix)
        $postsTable = $wpdb->prefix.'posts';
        $postsMetaTable = $wpdb->prefix.'postmeta';
        // Filter orders by specific status
        $orderStatusFilter = array('wc-completed', 'wc-processing');
        // Connect the array into a string that is compatible with our query (IN() query statement)
        $orderStatusFilter = "'".implode("','", $orderStatusFilter)."'";
        // Only get the single variable from the database
        $totalOrders = $wpdb->get_var("
        SELECT COUNT(p.ID) 
        FROM $postsTable AS p
        INNER JOIN $postsMetaTable AS m ON m.post_id = p.ID AND m.meta_key = '_customer_user' AND m.meta_value = $customerId 
        WHERE p.post_status IN ($orderStatusFilter) AND p.post_type = 'shop_order'");
        echo '<p class="form-field form-field-wide wc-customer-order-count">';
        if($totalOrders===1){
            // When this is the first order, display a message to our admin to give a first time offer
            echo '<span style="color:white;background-color:red;padding:20px;">FIRST TIME OFFER</span>';
        }else{
            // Otherwise just display the total orders the customer has placed in the past
            echo '<span>'.esc_html__( 'Total Orders', 'super-forms' ) . ': '.$totalOrders.'</span>';
        }
        echo '</p>';
    }
    

    If you need a list format of multiple customers/users, then you can use the $wpdb->get_results() instead of $wpdb->get_var() and loop over the results (table rows).

  4. Found a way.

    $args = [
        'author' => 'id',
        'post_status' => 'any',
        'post_type' => 'shop_order'
    ];
    
    $query = new WP_Query($args);
    
    $orderCountByCustomer = $query->found_posts;
    

Comments are closed.