Create a Custom Order Status

In this tutorial I am going to show you how to add a new order status in WooCommerce programmatically. I am not a big fan of using plugins when it is just enough to deal with a couple lines of code.

When registering a status, we are using register_post_status() function which makes as think that WooCommerce order are custom post types and WooCommerce order statuses are just post statuses. Obviously.

I can prove that with a screenshot of WordPress database if you wish. Under post_status column for order post types you can find statuses like wc-pending, wc-processing, wc-on-hold, wc-completed, wc-cancelled, wc-refunded, wc-failed.

Enough talk, let’s create a custom status now.

/*
 * Register a custom order status
 *
 * @author Misha Rudrastyh
 * @url https://rudrastyh.com/woocommerce/order-statuses.html
 */
add_action( 'init', 'misha_register_awaiting_shipping_status' );

function misha_register_awaiting_shipping_status() {

	register_post_status(
		'wc-misha-shipping',
		array(
			'label'		=> 'Awaiting shipping',
			'public'	=> true,
			'show_in_admin_status_list' => true,
			'label_count'	=> _n_noop( 'Awaiting shipping (%s)', 'Awaiting shipping (%s)' )
		)
	);

}

// Add registered status to list of WC Order statuses
add_filter( 'wc_order_statuses', 'misha_add_status_to_list' );

function misha_add_status_to_list( $order_statuses ) {

	$order_statuses[ 'wc-misha-shipping' ] = 'Awaiting shipping';
	return $order_statuses;

}

As a result you may immediately find the new status appeared on edit order page.

add a custom order status in WooCommerce

Now let’s break it down in details.

Let’s take a look at register_post_status() parameters first.

register_post_status(
	'wc-misha-shipping',
	array(
		'label'		=> 'Awaiting shipping',
		'public'	=> true,
		'show_in_admin_status_list' => true,
		'label_count'	=> _n_noop( 'Awaiting shipping (%s)', 'Awaiting shipping (%s)' )
	)
);
show_in_admin_status_list

Everything is clear with register_post_status(), right? Let’s jump to the next part of the code.

Filter hook wc_order_statuses allows you to change the array of statuses before they are going to be displayed anywhere on the website. It also allows you to remove any of the default order statuses which is not recommended and can be done only with caution. Or you can change the statuses order!

For example, if you would like our custom status to be displayed just before “Completed” status, you can use this code:

function misha_add_status_to_list( $order_statuses ) {

	$new = array();

	foreach ( $order_statuses as $id => $label ) {
		
		if ( 'wc-completed' === $id ) { // before "Completed" status
			$new[ 'wc-misha-shipping' ] = 'Awaiting shipping';
		}
		
		$new[ $id ] = $label;

	}

	return $new;
	
}
change the custom order status ordering

Please read my another tutorial where I show how to add a custom order status to bulk actions.

Misha Rudrastyh

Misha Rudrastyh

Hey guys and welcome to my website. For more than 10 years I've been doing my best to share with you some superb WordPress guides and tips for free.

Need some developer help? Contact me

Follow me on X