As an admin of your online store, you have the convenience of checking the order status for all products under WooCommerce > Orders in the status column. Conversely, customers can’t easily find or filter orders based on their status, like “Pending” or “Completed”. Especially if a customer wants to find a specific order quickly or check the status of all their pending orders in one go, then there are no such options provided in the front end.
This post helps customers to filter order status @ My Account Orders section.
Where to Add Custom Code in WooCommerce?
It is advisable to add the code snippets to the functions.php file of your child theme. Access the file directly from Appearance->Theme File Editor->Locating the child theme’s functions.php from the right sidebar. You can also access it from your theme’s directory file. Insert the following code snippet in functions.php. The alternative & easy option is to install & activate the Code Snippets plugin. You can then add the code as a new snippet via the plugin.
Solution: Filter WooCommerce Order Status @ My Account Orders Section
Imagine you run an online store where customers frequently place orders for various products. Now, your customers access their order history through the “My Account” page, where they can see a list of all their past orders but they can’t easily filter or sort their orders based on their status. The code snippet given below enables customers to conveniently search for specific order statuses, such as “Pending” or “Completed.”
// 1. Let orders query listen to URL parameter add_filter( 'woocommerce_my_account_my_orders_query', 'ts_my_account_orders_filter_by_status' ); function ts_my_account_orders_filter_by_status( $args ) { if ( isset( $_GET['status'] ) && ! empty( $_GET['status'] ) ) { $args['status'] = array( $_GET['status'] ); } return $args; } // ------------ // 2. Display list of filters add_action( 'woocommerce_before_account_orders', 'ts_my_account_orders_filters' ); function ts_my_account_orders_filters() { echo '<p>Filter by: '; $customer_orders = 0; foreach ( wc_get_order_statuses() as $slug => $name ) { $status_orders = count( wc_get_orders( [ 'status' => $slug, 'customer' => get_current_user_id(), 'limit' => -1 ] ) ); if ( $status_orders > 0 ) { if ( isset( $_GET['status'] ) && ! empty( $_GET['status'] ) && $_GET['status'] == $slug ) { echo '<b>' . $name . ' (' . $status_orders . ')</b><span class="delimit"> - </span>'; } else echo '<a href="' . add_query_arg( 'status', $slug, wc_get_endpoint_url( 'orders' ) ) . '">' . $name . ' (' . $status_orders . ')</a><span class="delimit"> - </span>'; } $customer_orders += $status_orders; } if ( isset( $_GET['status'] ) && ! empty( $_GET['status'] ) ) { echo '<a href="' . remove_query_arg( 'status' ) . '">All statuses (' . $customer_orders . ')</a>'; } else echo '<b>All statuses (' . $customer_orders . ')</b>'; echo '</p>'; } // ------------ // 3. My Account Orders Pagination fix add_filter( 'woocommerce_get_endpoint_url', 'ts_my_account_orders_filter_by_status_pagination', 9999, 4 ); function ts_my_account_orders_filter_by_status_pagination( $url, $endpoint, $value, $permalink ) { if ( 'orders' == $endpoint && isset( $_GET['status'] ) && ! empty( $_GET['status'] ) ) { return add_query_arg( 'status', $_GET['status'], $url ); } return $url; }
Output
When a customer goes to the “My Account” page and clicks on the “Orders” tab, they will see such filter by options right above the orders table:
- Filter by:
- Processing (X): This shows the number of orders that are currently being processed.
- On hold (X): Indicates the number of orders that are on hold.
- Completed (X): Displays the count of completed orders.
- All statuses (X): This option combines and shows the total count of orders, regardless of their current status.
Code Explanation
1. Let orders query listen to URL parameter
- The woocommerce_my_account_my_orders_query filter allows you to modify the arguments of the query used to retrieve orders on the My Account page.
- The function ts_my_account_orders_filter_by_status checks if the ‘status’ parameter is set in the URL and not empty.
- If a status parameter is found, it updates the query arguments to filter orders by that status.
2. Display list of filters
- The woocommerce_before_account_orders action is used to add content before the user’s order history on the My Account page.
- The function ts_my_account_orders_filters displays a list of order status filters.
- It loops through each order status and counts the number of orders for each status.
- It generates HTML links for each status filter.
- The currently selected status is highlighted, and a link for “All statuses” is provided.
- The count of orders for each status and the total count of all orders are displayed.
3. My Account Orders Pagination fix
- The woocommerce_get_endpoint_url filter is used to modify the URL for a given WooCommerce endpoint (in this case, ‘orders’).
- The function ts_my_account_orders_filter_by_status_pagination checks if the ‘status’ parameter is set in the URL and not empty.
- If a status parameter is found, it adds this status to the pagination URLs.
Filter By Multiple Order Statuses @WooCommerce My Account ‘Orders’ Tab
By default, WooCommerce’s My Account Orders section does not include the functionality to filter orders or filter orders based on multiple statuses simultaneously. But this customization helps users to track their order history efficiently using a filter and quickly find any issues or delays in the order fulfillment process. For example, the code helps the users to view orders that are “Processing” or “Completed” to track the progress of their purchases.
add_action('init', 'start_session', 1); function start_session() { if (!session_id()) { session_start(); } } // Filter orders by status add_filter('woocommerce_my_account_my_orders_query', 'ts_my_account_orders_filter_by_status'); function ts_my_account_orders_filter_by_status($args) { // Check if status filter is set in GET or session if (isset($_GET['status']) && !empty($_GET['status'])) { $_SESSION['ts_selected_status'] = $_GET['status']; $args['status'] = $_GET['status']; } elseif (isset($_SESSION['ts_selected_status']) && !empty($_SESSION['ts_selected_status'])) { $args['status'] = $_SESSION['ts_selected_status']; } return $args; } // Display status filters add_action('woocommerce_before_account_orders', 'ts_my_account_orders_filters'); function ts_my_account_orders_filters() { echo '<form method="get">'; echo '<p>Filter by: '; $customer_orders = 0; $selected_statuses = isset($_SESSION['ts_selected_status']) ? $_SESSION['ts_selected_status'] : array(); foreach (wc_get_order_statuses() as $slug => $name) { $status_orders = count(wc_get_orders(['status' => $slug, 'customer' => get_current_user_id(), 'limit' => -1])); if ($status_orders > 0) { $selected = in_array($slug, $selected_statuses) ? ' checked' : ''; echo '<input type="checkbox" name="status[]" value="' . $slug . '"' . $selected . '> ' . $name . ' (' . $status_orders . ')<span class="delimit"> - </span>'; $customer_orders += $status_orders; } } if (!empty($selected_statuses)) { echo '<a href="' . remove_query_arg('status') . '">Clear All</a>'; } echo '</p>'; echo '<input type="submit" value="Filter">'; echo '</form>'; } // Modify pagination links to include selected statuses add_filter('woocommerce_pagination_args', 'ts_modify_pagination_links'); function ts_modify_pagination_links($args) { // Add selected statuses to pagination links if (isset($_SESSION['ts_selected_status']) && !empty($_SESSION['ts_selected_status'])) { foreach ($args as $key => $value) { if ('add_args' === $key) { $args[$key]['status'] = implode(',', $_SESSION['ts_selected_status']); } } } return $args; }
When the customer visits the “My Account” page and navigates to the orders section they can select one or multiple statuses with the provided checkboxes representing different order statuses such as “Processing,” “On Hold,” “Completed,” etc. For example, if the customer selected “Processing” and “On Hold,” only orders that are in either of these statuses will be shown.
The output given below represents the scenario when a customer wants to review their orders that are either “Completed” or “Processing” to track the progress of their recent purchases.
Conclusion
The code snippets in this post helps customers filter their WooCommerce orders and also filter orders by multiple statuses on the “My Account” orders page. As an admin, instead of just using the default status column, you can also filter order status by multiple order statuses on the admin backend to manage orders effectively.
How to include the multiple status search in this code. To let the customer seach for review and processing status.
Hi Matsdent,
The post has been updated based on your requirement to filter multiple order statuses. Please refer to the code snippet under the heading “Filter By Multiple Order Statuses @WooCommerce My Account ‘Orders’ Tab”.
You’re great Saranya. I’ve been looking for this for a hole week.
Very much appreciate.
Hello Saranya again,
It was all good, working well, but sometimes this gives a critical error that crashes all web searches and this pops up on the snippet.
Hi Matsdent,
The code works perfectly well on my side in the updated WooCommerce Version( 8.5.1). Please try switching to a default WordPress theme and deactivating other plugins except WooCommerce to check if there is a theme/plugin conflict. And as your specific error line indicates the variable $selected_ statuses in some cases, is being treated as a string, but it must be an array type. You can use typecasting and explicitly set the $_SESSION[‘ts_selected_status’] to an array (array)$_SESSION[‘ts_selected_status’]. Please try this code and check whether this resolves your issue.
It`s work like a charm….. So usefull and geart… thank you
Hi Farhad, Thank you for your appreciation!