Occasionally you may need to add a custom WooCommerce order status to your website to manage orders more efficiently for your specific needs. While WooCommerce orders are a type of WordPress post, the orders require a different subset of statuses depending on the stage they are in during the order process. It ships with 8 different status, which are listed below:
- Pending payment
- Processing
- On hold
- Completed
- Cancelled
- Refunded
- Failed
- Draft
While these statuses will suit the majority of stores, there may come a time where you will need to add one or more custom statuses to your own store. This is where this post comes in, and we will talk about the different ways to add the statuses below.
Plugins
It shouldn’t surprise you that there are several plugins specifically to solve this problem. While a plugin will be the go to solution for most people, there are benefits of not installing another plugin that does just one job. Let’s look at the plugin options below:
Custom Order Status Manager for WooCommerce – Fee. The plugin options provide an easy to use interface as well as custom colours and icons for the custom statuses. The status can also appear on emails.
WooCommerce Order Status Manager – Premium. Similar to above, the plugin options provide an easy to use interface as well as custom colours and icons for the custom statuses. The status can also appear on emails. With free plugins available, there are better options
Custom Order Statuses for WooCommerce – Free. While this plugin doesn’t offer the options of icons and colours for the custom status, it does integrate with emails and custom email content.
Custom Order Status – premium. Similar tot he second plugin on this list, it offers similar features, but at a premium price. Best to use a free option where possible.
Add a custom WooCommerce order status using a code snippet
More advanced users may prefer to add a custom WooCommerce order status using a PHP code snippet. This reduces loading additional files and can generally result in more ability to customise the custom order status. Another benefit is that it is only a relatively small snippet.
/*
* Snippet: How to add a custom WooCommerce order status 2024
* Author: John Cook
* URL: https://wcsuccessacademy.com/?803
* Tested with WooCommerce 8.8.2
*/
add_action( 'init', 'wcsuccess_partial_fulfilled' );
function wcsuccess_partial_fulfilled() {
register_post_status(
'wc-partial-fulfill',
array(
'label' => 'Partially fulfilled',
'public' => true,
'show_in_admin_status_list' => true,
'label_count' => _n_noop( 'Partially fulfilled (%s)', 'Partially fulfilled (%s)' )
)
);
}
// Add registered status to list of WC Order statuses
add_filter( 'wc_order_statuses', 'wcsuccess_add_status_to_list' );
function wcsuccess_add_status_to_list( $order_statuses ) {
$new = array();
foreach ( $order_statuses as $id => $label ) {
if ( 'wc-cancelled' === $id ) { // after "Completed" status
$new[ 'wc-partial-fulfill' ] = 'Partially fulfilled';
}
$new[ $id ] = $label;
}
return $new;
}
When registering the custom status three key points must be maintained. First, it must be prefixed with wc-,second, it must not exceed 20 characters in total length, and third, it must use alpha numerical characters and dashes only.
Once added you will see the new status in the order ediit screen, however, it won’t be visible on the order list screen as a bulk action. To add it as a bulk action option, we need to add some more code to first display it as an option, then to save the status and display a success or failure message. Add the following snippets to your child theme functions.php file.
First, add the bulk action dropdown. Even though it has been added, it won’t do anything just yet,
/*
* Snippet: How to add a custom WooCommerce order status 2024
* Author: John Cook
* URL: https://wcsuccessacademy.com/?803
* Tested with WooCommerce 8.8.2
* "Add bulk dropdown"
*/
add_filter( 'bulk_actions-edit-shop_order', 'wcsuccess_register_bulk_action' ); // edit-shop_order is the screen ID of the orders page
function wcsuccess_register_bulk_action( $bulk_actions ) {
$bulk_actions[ 'mark_partial-fulfill' ] = 'Change status to partially fulfilled'; // <option value="mark_awaiting_shipping">Change status to awaiting shipping</option>
return $bulk_actions;
}
Now we need to fire the bulk action and save the changes. Add the following snippet to your child theme functions.php file
/*
* Snippet: How to add a custom WooCommerce order status 2024
* Author: John Cook
* URL: https://wcsuccessacademy.com/?803
* Tested with WooCommerce 8.8.2
* "Add bulk action"
*/
add_action( 'handle_bulk_actions-edit-shop_order', 'wcsuccess_bulk_process_custom_status', 20, 3 );
function wcsuccess_bulk_process_custom_status( $redirect, $doaction, $object_ids ) {
if( 'mark_partial-fulfill' === $doaction ) {
// change status of every selected order
foreach ( $object_ids as $order_id ) {
$order = wc_get_order( $order_id );
$order->update_status( 'wc-partial-fulfill' );
}
// do not forget to add query args to URL because we will show notices later
$redirect = add_query_arg(
array(
'bulk_action' => 'marked_partial-fulfill',
'changed' => count( $object_ids ),
),
$redirect
);
}
return $redirect;
}
Finally, it’s a good idea to display a message for when the action is successful. The following will display a message notifying the bulk action was successful and the number of orders changed.
/*
* Snippet: How to add a custom WooCommerce order status 2024
* Author: John Cook
* URL: https://wcsuccessacademy.com/?803
* Tested with WooCommerce 8.8.2
* "Add admin notice on save"
*/
add_action( 'admin_notices', 'wcsuccess_custom_order_status_notices' );
function wcsuccess_custom_order_status_notices() {
if(
isset( $_REQUEST[ 'bulk_action' ] )
&& 'marked_partial-fulfill' == $_REQUEST[ 'bulk_action' ]
&& isset( $_REQUEST[ 'changed' ] )
&& $_REQUEST[ 'changed' ]
) {
// displaying the message
printf(
'<div id="message" class="updated notice is-dismissible"><p>' . _n( '%d order status changed.', '%d order statuses changed.', $_REQUEST[ 'changed' ] ) . '</p></div>',
$_REQUEST[ 'changed' ]
);
}
}
The complete code is as follows:
/*
* Snippet: How to add a custom WooCommerce order status 2024
* Author: John Cook
* URL: https://wcsuccessacademy.com/?803
* Tested with WooCommerce 8.8.2
*/
// Register the new status
add_action( 'init', 'wcsuccess_partial_fulfilled' );
function wcsuccess_partial_fulfilled() {
register_post_status(
'wc-partial-fulfill',
array(
'label' => 'Partially fulfilled',
'public' => true,
'show_in_admin_status_list' => true,
'label_count' => _n_noop( 'Partially fulfilled (%s)', 'Partially fulfilled (%s)' )
)
);
}
// Add registered status to list of WC Order statuses
add_filter( 'wc_order_statuses', 'wcsuccess_add_status_to_list' );
function wcsuccess_add_status_to_list( $order_statuses ) {
$new = array();
foreach ( $order_statuses as $id => $label ) {
if ( 'wc-cancelled' === $id ) { // after "Completed" status
$new[ 'wc-partial-fulfill' ] = 'Partially fulfilled';
}
$new[ $id ] = $label;
}
return $new;
}
// add bulk action to dropdown
add_filter( 'bulk_actions-edit-shop_order', 'wcsuccess_register_bulk_action' ); // edit-shop_order is the screen ID of the orders page
function wcsuccess_register_bulk_action( $bulk_actions ) {
$bulk_actions[ 'mark_partial-fulfill' ] = 'Change status to partially fulfilled'; // <option value="mark_awaiting_shipping">Change status to awaiting shipping</option>
return $bulk_actions;
}
// save bulk actions
add_action( 'handle_bulk_actions-edit-shop_order', 'wcsuccess_bulk_process_custom_status', 20, 3 );
function wcsuccess_bulk_process_custom_status( $redirect, $doaction, $object_ids ) {
if( 'mark_partial-fulfill' === $doaction ) {
// change status of every selected order
foreach ( $object_ids as $order_id ) {
$order = wc_get_order( $order_id );
$order->update_status( 'wc-partial-fulfill' );
}
// do not forget to add query args to URL because we will show notices later
$redirect = add_query_arg(
array(
'bulk_action' => 'marked_partial-fulfill',
'changed' => count( $object_ids ),
),
$redirect
);
}
return $redirect;
}
// Add an admin notice
add_action( 'admin_notices', 'wcsuccess_custom_order_status_notices' );
function wcsuccess_custom_order_status_notices() {
if(
isset( $_REQUEST[ 'bulk_action' ] )
&& 'marked_partial-fulfill' == $_REQUEST[ 'bulk_action' ]
&& isset( $_REQUEST[ 'changed' ] )
&& $_REQUEST[ 'changed' ]
) {
// displaying the message
printf(
'<div id="message" class="updated notice is-dismissible"><p>' . _n( '%d order status changed.', '%d order statuses changed.', $_REQUEST[ 'changed' ] ) . '</p></div>',
$_REQUEST[ 'changed' ]
);
}
}
Add the code to the child theme functions.php file or your PHP code snippets plugin and change the fields where necessary
I have been working with WordPress and WooCommerce since 2012 and have developed a deep knowledge of the content management system. Since 2012, I have developed several plugins and designed dozens of websites utilising different frameworks, CMS’s and programming languages. I am proficient in PHP, Python, Java, C, C++, R and JavaScript with limited experience in Go, Kotlin and Swift.
Educationally, I have a Master’s degree in cyber security a Bachelor’s (Hons, First Class) in Applied Research and a Graduate Certificate in Data Science. I’m currently undertaking PhD studies investigating IoT cybersecurity. I recently graduated with First Class Honours and Masters of Information Technology, receiving the Executive Dean’s Award for studies undertaken in the 2021 and 2022 academic years. I have worked in the information technology industry for the past 11 years primarily as a software/web developer specific to design, optimisation, network management and security. My research interests are in the areas of Internet of Things (IoT), 5G and Beyond Networks, information security for wireless networks and software development.
Google Scholar ID: https://scholar.google.com.au/citations?user=0KvpwNEAAAAJ&hl=en
ORCID: https://orcid.org/0000-0001-8113-1296
Stay In Touch