WooCommerce Order Statuses: Remove Core Order Statuses and Add a Custom One

In this post we will work mostly with «wc_order_statuses» filter hook that allows to add, remove or change order of WooCommerce statuses.

#WooCommerce, #noplugins, #orders  /   15

I think my posts is a good way to track my working activity. When I work with a specific task for a client – after the task is complete I create a blog post about it.

And currently I want to share with you a small tutorial about managing order statuses in WooCommerce.

Removing Core Order Statuses #

Here I want to say one thing — please do it carefully!

When you remove core order status, make sure, that there are no products with that status, that your WooCommerce shop doesn’t use that status anywhere, otherwise it can lead to errors. For example if you do not plan to make refunds via website, you may turn off «Refunded» status with no problems.

Be careful with core order statuses

All the code from this post you can insert to your current theme functions.php file.

 * Removing core order statuses
 * @param array $wc_statuses_arr Array of all order statuses on the website
function misha_remove_order_statuses( $wc_statuses_arr ){
	// Processing
	if( isset( $wc_statuses_arr['wc-processing'] ) ) { // if exists
		unset( $wc_statuses_arr['wc-processing'] ); // remove it from array
	// Refunded
	if( isset( $wc_statuses_arr['wc-refunded'] ) ){
		unset( $wc_statuses_arr['wc-refunded'] );
	// On Hold
	if( isset( $wc_statuses_arr['wc-on-hold'] ) ){
		unset( $wc_statuses_arr['wc-on-hold'] );
	// Failed
	if( isset( $wc_statuses_arr['wc-failed'] ) ){
		unset( $wc_statuses_arr['wc-failed'] );
	// Pending payment
	if( isset( $wc_statuses_arr['wc-pending'] ) ){
		unset( $wc_statuses_arr['wc-pending'] );
	// Completed
	//if( isset( $wc_statuses_arr['wc-completed'] ) ){
	//    unset( $wc_statuses_arr['wc-completed'] );
	// Cancelled
	//if( isset( $wc_statuses_arr['wc-cancelled'] ) ){
	//    unset( $wc_statuses_arr['wc-cancelled'] );
	return $wc_statuses_arr; // return result statuses
add_filter( 'wc_order_statuses', 'misha_remove_order_statuses' );

After using this order status action hook, you may see the result on order edit page in admin area:

How to remove core order statuses in WooCommerce

But as I said before, it will lead to problems in most cases. So, be careful.

Custom Order Statuses #

 * Register new status with ID "wc-misha-shipment" and label "Awaiting shipment"
function misha_register_awaiting_shipment_status() {
	register_post_status( 'wc-misha-shipment', array(
		'label'		=> 'Awaiting shipment',
		'public'	=> true,
		'show_in_admin_status_list' => true, // show count All (12) , Completed (9) , Awaiting shipment (2) ...
		'label_count'	=> _n_noop( 'Awaiting shipment <span class="count">(%s)</span>', 'Awaiting shipment <span class="count">(%s)</span>' )
	) );
add_action( 'init', 'misha_register_awaiting_shipment_status' );
 * Add registered status to list of WC Order statuses
 * @param array $wc_statuses_arr Array of all order statuses on the website
function misha_add_status( $wc_statuses_arr ) {
	$new_statuses_arr = array();
	// add new order status after processing
	foreach ( $wc_statuses_arr as $id => $label ) {
		$new_statuses_arr[ $id ] = $label;
		if ( 'wc-completed' === $id ) { // after "Completed" status
			$new_statuses_arr['wc-misha-shipment'] = 'Awaiting shipment';
	return $new_statuses_arr;
	// if order status order doesn't matter for you you can remove lines 21-32 and uncomment the following 35-36
	// $wc_statuses_arr['wc-misha-shipment'] = 'Awaiting shipment';
	// return $wc_statuses_arr;
add_filter( 'wc_order_statuses', 'misha_add_status' );
Custom order status in WooCommerce

Change Order Statuses Order #

 * Change statuses order in dropdown list
 * @param array $wc_statuses_arr Array of all order statuses on the website
function misha_change_statuses_order( $wc_statuses_arr ){
	$new_statuses_arr = array(
		'wc-processing' => $wc_statuses_arr['wc-processing'], // 1
		'wc-completed' => $wc_statuses_arr['wc-completed'], // 2
		'wc-cancelled' => $wc_statuses_arr['wc-cancelled'], // 3
		'wc-refunded' => $wc_statuses_arr['wc-refunded'], // 4
		'wc-failed' => $wc_statuses_arr['wc-failed'], // 5
		'wc-pending' => $wc_statuses_arr['wc-pending'], // 6
		'wc-on-hold' => $wc_statuses_arr['wc-on-hold'] // 7
	return $new_statuses_arr;
add_filter( 'wc_order_statuses', 'misha_change_statuses_order' );
The new order of statuses in dropdown list

WooCommerce Order Status Manager — Plugin alternative #

I know that there is a plugin alternative, it is WooCommerce Order Status Manager, so, if the code above is a little complicated for you, try the plugin then, but it costs $49 – $149.

But as I know this plugin doesn’t allow to remove core order statuses.

Only the best of WordPress

Subscribe to this weekly newsletter to receive the latest blog posts by email.I respect your privacy. Your email is safe with me.

Comments 15

  • Emmett Brosnan January 11, 2017 at 12:34

    Very Handy – thanks.

  • Hi Misha,
    This is a great article and really helped me add some order statuses. Is there any way to get the new statuses in the ‘Bulk Action’ menu?

  • Please provide the hook of the custom order

  • please check this line add_action(custom hook for your plugin,’mysite_woocommerce_order_complete’,10,1);

    mysite_woocommerce_order_complete this is my function name

  • Hi!

    Thanks for the great tutorial. I added the source code in my functions.php of the child theme in WordPress but nothing happens, all options are still available. Is there any change to how this works in the recently released WooCommerce 3? Because I had some renamed before in my functions.php and that has stopped working as well since upgrading to WC3.



  • Hi, thank you for this tutorial.
    Could you help me, how to I remove an order status when there are only “downloadable products” in the order.

    I have a custom order status called “dispatch” which I manually trigger to go to the Logistics department once Accounts can confirm that payment was made successfully. But I do not want this status option in the backend when the order contain only downloadable products.

    Thank you

    • Hey,

      I didn’t test this code, but try it out:

      // you didn't mention when we need to change the order status
      // I suppose when the order is created
      add_action( 'woocommerce_new_order', 'misha_change_status_if', 1  );
      function misha_change_status_if( $order_id ){
      	// initiate the order
      	$order = wc_get_order( $order_id );
      	// let's suppose by default that all products are downloadable
      	$only_downloadable_products = true;
      	// loop through all products
      	foreach ($order->get_items() as $product_id => $product_data) {
      		// WC_Product object
      		$product = $product_data->get_product();
      		if ( !$product->is_downloadable() ) { // not downloadable
      			$only_downloadable_products = false; 
      	if( $only_downloadable_products == true ) {
      		$order->update_status('YOUR STATUS');
  • hello, thank you very much for this tutorial but I have a question. let’s say I want to show certain statuses for orders that are being shipped by a certain shipping company.
    for example if an order is shipped by company ‘x’ then statuses are a, b and c. if an order is shipped by company ‘y’ then statuses are 1,2 and 3. can I do that?

Leave your question or feedback

Please, enter a comment
Please, enter a name
Incorrect email