Menu Close

WooCommerce: Filter By Order Status @ My Account Orders

default

Here’s a great customization that all store managers should implement on their WooCommerce website!

For some reason you can refine the backend orders table if you are an admin, but logged in customers can’t filter by order status under My Account > Orders!

This is pretty bad, especially if you run a store where customers place many orders and the My Account Orders tab is full of entries. It may be helpful for customers to search all “Pending” orders for example, or maybe access al their “Completed” ones to download their files again.

So, here’s the fix – you’re welcome!

Cool, uh? Here’s a super simple filter where, on click, customers can refine by order status and get e.g. only “Pending payment” orders.

PHP Snippet: Display Order Status Filters @ WooCommerce My Account > Orders Tab

/**
 * @snippet       Status Filters @ My Account Orders - WooCommerce
 * @how-to        Get CustomizeWoo.com FREE
 * @author        Rodolfo Melogli
 * @compatible    WooCommerce 8
 * @donate $9     https://businessbloomer.com/bloomer-armada/
 */

// ------------
// 1. Let orders query listen to URL parameter

add_filter( 'woocommerce_my_account_my_orders_query', 'bbloomer_my_account_orders_filter_by_status' );

function bbloomer_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', 'bbloomer_my_account_orders_filters' );

function bbloomer_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', 'bbloomer_my_account_orders_filter_by_status_pagination', 9999, 4 );
		   
function bbloomer_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;
}

View Source
Posted in WooCommerce Tips