Black Friday & Cyber Monday SUPER SALE ALL WEEK:
Grab 40% OFF on plugins
Days
Hours
Minutes
Seconds

How to Filter WooCommerce Orders by Multiple Order Statuses?

One of our customers recently asked us this question for their WooCommerce Orders page in admin: Is there a way to select multiple statuses in the order backend?

Although WooCommerce store owners may not need to do this on a regular basis, but this would definitely help some of them.

This post will explain how to show WooCommerce orders with different statuses in one view. In the 2nd half of this post, we will also check how to exclude one or multiple statuses when all orders are being displayed.

The default behaviour of WooCommerce is that you can either view All orders, or orders for any one status. But you cannot view orders of different statuses together, like Pending & Refunded orders. Or you cannot exclude orders of a status in the All view.

WooCommerce Orders in Admin
Default WooCommerce Orders page view

Part 1: Filter WooCommerce Orders to show orders of multiple statuses in one view

There are multiple ways to look for a solution for this. It could either be via a plugin, or by adding a multi-select dropdown of order status with a code snippet. Or a crude way, simply add the status you want in the URL.

It’s definitely not the best way, but it works. I may come back later to this post & update it to include a multi-select dropdown of WooCommerce order statuses.

Let’s look at the code first.

/**
 * Handle filters for including additional WooCommerce statuses
 *
 * @param array $query_vars Query vars.
 * @return array
 */
function ts_woocommerce_include_order_status( $query_vars ) {
    global $typenow;

    /**
     * Using wc_get_order_types() instead of 'shop_order' as other order types could be added by other plugins
     */
    if ( in_array( $typenow, wc_get_order_types( 'order-meta-boxes' ), true ) ) {
        if ( isset( $_GET['include_status'] ) && '' != $_GET['include_status'] && isset( $query_vars['post_status'] ) ) {
            $include_status = explode( ',', $_GET['include_status'] );
            $q_post_status[] = $query_vars['post_status'];
            $query_vars['post_status'] = array_merge( $q_post_status, $include_status );
        }
    }

    return $query_vars;
}

add_filter( 'request', 'ts_woocommerce_include_order_status', 20, 1 );

We are doing a few things in the above snippet.

First, we attach our function to the request filter of WordPress.

Because we want our code to run only for the WooCommerce Orders page, we do that by making sure that the $typenow variable is present in the array returned from wc_get_order_types() function. In this case, $typenow is set to shop_order. That is the post_type of the orders that are created by WooCommerce.

include_status is the GET variable wherein you should pass other order statuses that you wish to be displayed. Multiple order statuses can be passed comma separated. You should first filter the order by any 1 order status that you wish to see. Let’s say you filtered by pending orders.

WooCommerce Orders with Pending status
WooCommerce Orders with Pending status

If you want to see the Refunded orders along with the Pending orders, that isn’t possible. However, if you add the above code snippet in your child theme’s functions.php, and then if you change the URL of the Orders page to the below link in your browser:

<your_store_url>/wp-admin/edit.php?post_status=wc-pending&post_type=shop_order&include_status=wc-refunded

you shall see that the Pending as well as Refunded orders will show up.

WooCommerce orders with status as Pending & Refunded being shown
WooCommerce orders with status as Pending & Refunded are shown

In the include_status parameter, you can also pass multiple order statuses which are comma separated. So if you want to view Pending, Refunded & Delivered orders, you can do so by changing the URL as below:

<your_store_url>/wp-admin/edit.php?post_status=wc-pending&post_type=shop_order&include_status=wc-refunded,wc-delivered

It’s important to note that Delivered is a custom status that I have added in my test WooCommerce install. It’s slug is wc-delivered. The status is added with the Custom Order Status plugin.

When you open the above link, you will see the orders with those 3 statuses:

WooCommerce orders with status as Pending, Refunded & Delivered being shown
WooCommerce orders with status as Pending, Refunded & Delivered being shown

The comma in the URL gets replaced with %2C due to URL encoding.

Part 2: Filter WooCommerce Orders to hide orders of one or more statuses in the All view

By default, you are presented with a view where WooCommerce orders of all statuses are shown on the Orders page.

WooCommerce Orders in Admin

I have created below code snippet that allows you to pass a variable in the URL, exclude_status. In the exclude_status variable, you can pass the slug of the status that you wish to exclude from being displayed on the Orders page in the All view. Here is the code:

/**
 * Handle filters for excluding WooCommerce statuses from All orders view
 *
 * @param array $query_vars Query vars.
 * @return array
 */
function ts_woocommerce_exclude_order_status( $query_vars ) {
    global $typenow;

    /**
     * Using wc_get_order_types() instead of 'shop_order' as other order types could be added by other plugins
     */
    if ( in_array( $typenow, wc_get_order_types( 'order-meta-boxes' ), true ) ) {
        if ( isset( $_GET['exclude_status'] ) && '' != $_GET['exclude_status'] && isset( $query_vars['post_status'] ) ) {
            $exclude_status = explode( ',', $_GET['exclude_status'] );
            foreach ( $exclude_status as $value ) {
                if ( ( $key = array_search( $value, $query_vars['post_status'] ) ) !== false ) {
                    unset( $query_vars['post_status'][$key] );
                }
            }
        }
    }

    return $query_vars;
}

add_filter( 'request', 'ts_woocommerce_exclude_order_status', 20, 1 );

When the above code is added in your child theme’s functions.php file, and then if you change the URL of your WooCommerce Orders page to the one below:

<your_store_url>/wp-admin/edit.php?post_type=shop_order&exclude_status=wc-pending

Then the orders with Pending status will not be displayed in the default view of All orders:

Excludes Pending orders from being displayed from all orders view
Excludes Pending orders from being displayed from all orders view

You can also specify multiple order statuses to exclude. They need to be separated by comma. Expanding on the above example, if you want to hide Pending & Delivered orders from the All view, then you can change your Orders page URL to:

<your_store_url>/woocommerce/wp-admin/edit.php?post_type=shop_order&exclude_status=wc-pending,wc-delivered

The Orders page will no longer show Pending & Delivered orders on the All view:

Excludes Pending & Delivered orders from being displayed from all orders view
Excludes Pending & Delivered orders from being displayed from all orders view

Part 3: Hide orders of one or more statuses in the All view for HPOS Compatible Order Table

To hide orders of one or more statuses in the All view for an HPOS Compatible Order Table, you can use the following code snippet.

function ts_woocommerce_exclude_order_status( $query_vars ) {
global $typenow;
/**
* Using wc_get_order_types() instead of 'shop_order' as other order types could be added by other plugins
*/
	if ( isset( $_GET['exclude_status'] ) && '' != $_GET['exclude_status'] && isset( $query_vars['status'] ) ) {
	$exclude_status = explode( ',', $_GET['exclude_status'] );
		foreach ( $exclude_status as $value ) {
			if ( ( $key = array_search( $value, $query_vars['status'] ) ) !== false ) {
				unset( $query_vars['status'][$key] );
			}
		}
	}


return $query_vars;
}

add_filter( 'woocommerce_order_list_table_prepare_items_query_args', 'ts_woocommerce_exclude_order_status', 20, 1 );

Include order statuses such as on hold or completed that you wish to hide as given in the URL below.

<your_store_url>/wp-admin/edit.php?post_type=shop_order&exclude_status=wc-on-hold,wc-completed

Output

The output shows that when the URL is edited with certain order statuses, then it hides such order statuses and displays only the remaining order statuses in the orders table.

How to Filter WooCommerce Orders by Multiple Order Statuses? - Tyche Softwares

Here is a reference of the default WooCommerce order statuses & their respective slugs.

  • Pending payment – wc-pending
  • Failed – wc-failed
  • Processing – wc-processing
  • Completed – wc-completed
  • On-Hold – wc-on-hold
  • Cancelled – wc-cancelled
  • Refunded – wc-refunded

Adding the order statuses in the URL directly isn’t the best approach. But the idea of this post is to show how the objective can be achieved.

Now, let’s look into the other approach for filtering orders by order statuses in WooCommerce. This method will create a custom dropdown filed to the WooCommerce Orders page in the WordPress admin interface.

4. Create a Dropdown field to Filter Order Statuses in WooCommerce

When a store owner sells products, it’s well known that the orders placed will go through several stages before being delivered. Tracking all orders can be challenging. In case, if you want to filter order statuses based on multiple parameters apart from just the order status, then utilizing the dropdown is an easy option to do it.

The code given below helps store owners to categorize and organize orders more effectively using the ‘Filter by Status’ field. For instance, they can filter orders by statuses such as ‘Pending,’ ‘Shipped,’ ‘Refunded,’ and more, making it easier to track the progress of orders.

// Add a custom dropdown filter to filter orders by status
function ts_custom_status_dropdown_filter() {
    global $typenow;

    if ('shop_order' === $typenow) {
        $order_statuses = wc_get_order_statuses();

        echo '<select name="order_status" class="postform">';
        echo '<option value="">Filter by Status</option>';

        foreach ($order_statuses as $status_key => $status_label) {
            $selected = isset($_GET['order_status']) && $_GET['order_status'] === $status_key ? 'selected' : '';
            echo '<option value="' . esc_attr($status_key) . '" ' . $selected . '>' . esc_html($status_label) . '</option>';
        }

        echo '</select>';
    }
}

// Hook the custom filter to 'restrict_manage_posts' action
add_action('restrict_manage_posts', 'ts_custom_status_dropdown_filter');


// Modify the query to filter orders by selected status
function ts_filter_orders_by_status($query) {
    global $pagenow, $typenow;

    if ('edit.php' === $pagenow && 'shop_order' === $typenow && isset($_GET['order_status']) && $_GET['order_status'] !== '') {
        // Get the selected status from the dropdown
        $selected_status = sanitize_text_field($_GET['order_status']);

        // Modify the query to include only orders with the selected status
        $query->set('post_status', $selected_status);
    }
}

// Hook the query modification to 'pre_get_posts' action
add_filter('pre_get_posts', 'ts_filter_orders_by_status');

Output

After applying the code, you’ll see a new dropdown field on the WooCommerce Orders page labeled “Filter by Status”  showing the list of order status as shown in the image below.

How to Filter WooCommerce Orders by Multiple Order Statuses? - Tyche Softwares

Once you’ve selected a status from the dropdown, the code will modify the query and display only the list of orders that match the selected status. For example, if you select “Processing” from the dropdown, only orders in the “Processing” status will be shown in the list.

How to Filter WooCommerce Orders by Multiple Order Statuses? - Tyche Softwares

The below image shows that the admin has selected the status ”on hold” from the dropdown field and thus only orders with that status is displayed in the status column.

How to Filter WooCommerce Orders by Multiple Order Statuses? - Tyche Softwares

Similarly, you can see the order status such as  “Cancelled” or any other status defined in your WooCommerce settings.

How to Filter WooCommerce Orders by Multiple Order Statuses? - Tyche Softwares

Code Explanation

Step 1: Adding the Dropdown Filter to WooCommerce Orders Page

  • The first function, custom_status_dropdown_filter(), is responsible for enhancing the user interface of the WooCommerce Orders page.
  • This function is hooked to the restrict_manage_posts action using add_action, ensuring it’s activated when the page is loaded.
  • When the user is on the WooCommerce Orders page, a custom dropdown filter labeled “Filter by Status” is displayed.

Step 2: Generating Dropdown Options

  • Within this dropdown, the function dynamically generates a list of order statuses, including “Processing,” “Completed,” and any other custom statuses defined in your WooCommerce settings.
  • The list of statuses is retrieved using the wc_get_order_statuses() function.

Step 3: User Selection and Filtering

  • As a user, you can select a specific order status from the dropdown.
  • The selected status is visually indicated with the ‘selected’ attribute in the dropdown menu.
  • This allows you to filter orders based on the chosen status.

Step 4: Modifying the Query for Order Retrieval

  • The second function, filter_orders_by_status($query), focuses on modifying the query used to retrieve orders from the database.
  • It is hooked to the pre_get_posts action using add_filter, ensuring it takes effect before orders are fetched.

Step 5: Detecting User’s Status Selection

  • This function checks whether a user has selected a status in the dropdown filter.
  • It ensures that the selected status is not empty and has been sanitized for security using sanitize_text_field().

Step 6: Adapting the Query

  • If a status is selected, the code alters the query using the set() method.
  • It adjusts the query to retrieve only those orders that match the selected status, effectively filtering the displayed orders.

Conclusion

This post covers all about filtering order statuses via the URL method and using the code snippet. Similarly, filtering specific delivery details of orders is done effectively using the Order Delivery Date Pro for WooCommerce plugin.

How to Filter WooCommerce Orders by Multiple Order Statuses? - Tyche Softwares

It helps admins search, view, and sort orders and their delivery details quickly. You can also look at specific order details as per the requirement using the filter option on the WooCommerce orders page.

Browse more in: WooCommerce Tutorials, Code Snippets, WooCommerce How Tos

Share It:

Subscribe
Notify of
15 Comments
Newest
Oldest
Inline Feedbacks
View all comments
Herb
4 months ago

Hi, concerning the code for hiding certain statuses from the all orders list, does this code work with the the HPOS configuration?

4 months ago
Reply to  Herb

Hi Herb,
The post has been updated as per your request to work with HPOS configuration as well. Please check the code under the heading ‘Part 3: Hide orders of one or more statuses in the All view for HPOS Compatible Order Table’

6 months ago

Strangely, the URL works without the need for adding a filter…. any explanation as to why?!?
Simply typing the URL into the browser works perfectly!

/wp-admin/edit.php?post_status=wc-processing&post_type=shop_order&include_status=wc-m2m-processing%2Cwc-on-hold%2Cwc-to-be-booked%2Cwc-ready-to-ship-tuf%2Cwc-ready-to-ship%2Cwc-ordered-out
6 months ago
Reply to  Gino

Hi Gino, It might be because WooCommerce and WordPress can understand and use URL parameters on their own.
Sometimes, they can figure out the filtering you want from the URL without needing extra code, like your custom dropdown.
But remember, this can work differently depending on your website setup, theme, and other plugins. So, it’s good that it’s working now, but it’s a good idea to check in different situations and web browsers to be sure it always works as expected.

Arvin
2 years ago

Hey there
First of all, thanks! It works perfectly.
Second, do you know how to sort the orders, so it first shows all orders with status X and then followed by Y?
Let´s say you have a “normal” order status and an “Urgent” order status, with must be expedited first; hence it would make sense first to show all urgent orders and then the normal ones.
I have tried to add the parameter &orderby=date&order=desc to the URL with no luck

Last edited 2 years ago by Arvin
Abbas
3 years ago

Worked great for me.. couldn’t find anywhere else in the whole wide world. Thank you very much.

6 months ago
Reply to  Abbas

I’m glad to hear that it worked for you, Abbas! If you have any more questions or need further assistance in the future, feel free to ask. 

M.Hrn
3 years ago

Hi, thank you for this great post. Do you have any idea, how to include two payment methods? I mean: How create URL to list for example all orders with bacs and paypal method together? The parts of the URL is

_shop_order_payment_method=cod

and

_shop_order_payment_method=paypal

but how can I put them together to see orders with payment method COD together with orders with payment method PAYPAL? Is there any way of include too? Thank you for any tips. Regards M.H.

6 months ago
Reply to  M.Hrn

I’m not sure whether your requirement to get orders based on the payment method can be done with the URL method. But the other alternative option is that the same can be done on the Orders page on the Admin side by creating a column for payment methods and filtering certain payment methods of orders.

15
0
Would love your thoughts, please comment.x
()
x