Order management is a very essential part of the success of a WooCommerce store. Although WooCommerce has such types of default order statuses as Pending payment, Processing, and Completed, they do not always apply to any business model. Custom order statuses enable you to build custom workflows to suit your operations with tracking shipment steps, pre-order management, and complicated fulfillment processes.
This comprehensive guide walks you through everything you need to know about creating, implementing, and managing custom order statuses in WooCommerce, using both code-based methods and plugins.

A custom order status in WooCommerce is a user-defined status that helps track specific stages of an order beyond the default options provided by WooCommerce. Custom statuses allow store owners to create additional workflow stages that reflect their unique business processes.
By default, WooCommerce includes seven standard order statuses:
| Status | Description | When It’s Used |
| Pending Payment | Order received, no payment initiated | The customer hasn’t completed payment |
| Processing | Payment received, stock reduced, awaiting fulfillment | Order ready for shipping |
| On Hold | Awaiting payment confirmation | Manual payment methods (bank transfer) |
| Completed | Order fulfilled and delivered | No further action required |
| Cancelled | Cancelled by admin or customer | Stock returned to inventory |
| Refunded | Full refund issued by admin | Customer reimbursed |
| Failed | Payment failed or declined | Payment gateway rejection |
These default statuses work well for simple stores. Still, businesses with complex workflows—such as those involving multiple shipment stages, quality checks, or custom manufacturing—often need additional statuses to accurately track order progress.
Custom order statuses offer significant benefits for both store owners and customers:
Streamlined Order Management:
Custom statuses let you organize orders according to your specific workflow. For example, a furniture store might need statuses like “In Production,” “Quality Check,” and “Ready for Delivery” before marking an order as “Completed.”
Better Filtering and Sorting:
With custom statuses, you can filter orders by specific stages, making it easier to identify which orders need attention. This is especially useful for stores processing hundreds of orders daily.
Improved Business Insights:
Custom statuses enable detailed reporting on specific workflow stages. You can analyze how long orders spend in each stage and identify bottlenecks in your fulfillment process.
Scalable Processes:
As your business grows or changes, custom order statuses allow you to adapt your order management without overhauling your entire system.
Better Communication:
More descriptive order statuses keep customers informed about exactly where their order is in the fulfillment process, reducing “Where is my order?” inquiries.
Enhanced Trust:
Transparent order tracking builds customer confidence. When customers see their order progressing through meaningful stages, they feel more assured about their purchase.
Reduced Support Tickets:
Clear status updates mean fewer customers reaching out for order updates, freeing your support team for more complex issues.
Understanding how WooCommerce handles order status transitions helps you design effective custom statuses:
[Order Placed]
↓
[Pending Payment] → [Failed] (if payment fails)
↓
[On Hold] (manual payment) OR [Processing] (automatic payment)
↓
[Processing]
↓
[Completed] OR [Cancelled] OR [Refunded]
Key transition points:
Custom statuses typically insert into this flow between Processing and Completed, though they can be placed anywhere depending on your needs.
The most flexible way to add custom order statuses is through code. This method gives you complete control over the status behavior and doesn’t require additional plugins.
First, you need to register your new order status with WordPress. Add the following code to your theme functions.php file or a custom plugin:
/**
* Register Custom Order Status
*/
function register_custom_order_status() {
register_post_status( 'wc-awaiting-shipment', array(
'label' => 'Awaiting Shipment',
'public' => true,
'show_in_admin_status_list' => true,
'show_in_admin_all_list' => true,
'exclude_from_search' => false,
'label_count' => _n_noop(
'Awaiting Shipment <span class="count">(%s)</span>',
'Awaiting Shipment <span class="count">(%s)</span>'
)
) );
}
add_action( 'init', 'register_custom_order_status' );
Code Explanation:
| Parameter | Purpose |
| ‘wc-awaiting-shipment‘ | Unique identifier (must start with wc- and be max 20 characters) |
| ‘label‘ | Human-readable name displayed in admin |
| ‘public‘ | Makes status publicly accessible |
| ‘show_in_admin_status_list‘ | Displays in the order status filter dropdown |
| ‘show_in_admin_all_list‘ | Shows orders with this status in the “All” orders list |
| ‘exclude_from_search‘ | Whether to exclude from search results |
| ‘label_count‘ | Format for displaying count in admin |
Registering the status isn’t enough, you must also add it to WooCommerce’s order status dropdown menu:
/**
* Add Custom Order Status to Dropdown
*/
function add_custom_order_status_to_dropdown( $order_statuses ) {
$new_order_statuses = array();
foreach ( $order_statuses as $key => $status ) {
$new_order_statuses[ $key ] = $status;
// Insert custom status after 'Processing'
if ( 'wc-processing' === $key ) {
$new_order_statuses['wc-awaiting-shipment'] = 'Awaiting Shipment';
}
}
return $new_order_statuses;
}
add_filter( 'wc_order_statuses', 'add_custom_order_status_to_dropdown' );
This code inserts your custom status right after “Processing” in the dropdown menu. You can modify the position by changing ‘wc-processing‘ to any other status key.
To enable bulk updating orders to your custom status, add:
/**
* Add Custom Status to Bulk Actions
*/
function add_custom_status_to_bulk_actions( $bulk_actions ) {
$bulk_actions['mark_awaiting-shipment'] = 'Change status to Awaiting Shipment';
return $bulk_actions;
}
add_filter( 'bulk_actions-edit-shop_order', 'add_custom_status_to_bulk_actions' );
Add custom styling to make your status visually distinct in the orders list:
/**
* Add Custom Status Styling
*/
function add_custom_status_styling() {
echo '<style>
.order-status.status-awaiting-shipment {
background: #f39c12;
color: #fff;
}
</style>';
}
add_action( 'admin_head', 'add_custom_status_styling' );
Here’s the complete code for adding a custom “Awaiting Shipment” status:
/**
* WooCommerce Custom Order Status: Awaiting Shipment
* Add this code to your theme's functions.php or a custom plugin
*/
// Step 1: Register the custom order status
function register_awaiting_shipment_order_status() {
register_post_status( 'wc-awaiting-shipment', array(
'label' => 'Awaiting Shipment',
'public' => true,
'show_in_admin_status_list' => true,
'show_in_admin_all_list' => true,
'exclude_from_search' => false,
'label_count' => _n_noop(
'Awaiting Shipment <span class="count">(%s)</span>',
'Awaiting Shipment <span class="count">(%s)</span>'
)
) );
}
add_action( 'init', 'register_awaiting_shipment_order_status' );
// Step 2: Add to order status dropdown
function add_awaiting_shipment_to_order_statuses( $order_statuses ) {
$new_order_statuses = array();
foreach ( $order_statuses as $key => $status ) {
$new_order_statuses[ $key ] = $status;
if ( 'wc-processing' === $key ) {
$new_order_statuses['wc-awaiting-shipment'] = 'Awaiting Shipment';
}
}
return $new_order_statuses;
}
add_filter( 'wc_order_statuses', 'add_awaiting_shipment_to_order_statuses' );
// Step 3: Add to bulk actions
function add_awaiting_shipment_to_bulk_actions( $bulk_actions ) {
$bulk_actions['mark_awaiting-shipment'] = 'Change status to Awaiting Shipment';
return $bulk_actions;
}
add_filter( 'bulk_actions-edit-shop_order', 'add_awaiting_shipment_to_bulk_actions' );
// Step 4: Add custom styling
function add_awaiting_shipment_styling() {
echo '<style>
.order-status.status-awaiting-shipment {
background: #f39c12;
color: #fff;
}
</style>';
}
add_action( 'admin_head', 'add_awaiting_shipment_styling' );
Email notifications about the changes in the status of an order to custom status are among the most demanded features. Here’s how to implement it:
You can trigger existing WooCommerce emails (like the “Processing” email) when transitioning to your custom status:
/**
* Trigger Processing Email for Custom Status Transition
*/
function trigger_email_on_custom_status( $order_id, $old_status, $new_status, $order ) {
if ( $new_status === 'awaiting-shipment' ) {
// Get the email class
$email_class = WC()->mailer()->get_emails()['WC_Email_Customer_Processing_Order'];
// Trigger the email
if ( $email_class ) {
$email_class->trigger( $order_id );
}
}
}
add_action( 'woocommerce_order_status_changed', 'trigger_email_on_custom_status', 10, 4 );
For a fully custom email, create a new email class:
/**
* Custom Email for Awaiting Shipment Status
*/
function send_custom_status_email( $order_id, $old_status, $new_status, $order ) {
if ( $new_status === 'awaiting-shipment' ) {
$to = $order->get_billing_email();
$subject = 'Your order is being prepared for shipment';
$message = sprintf(
'Hi %s, your order #%s is now being prepared for shipment. We\'ll notify you when it\'s on its way!',
$order->get_billing_first_name(),
$order->get_order_number()
);
$headers = array( 'Content-Type: text/html; charset=UTF-8' );
wp_mail( $to, $subject, $message, $headers );
}
}
add_action( 'woocommerce_order_status_changed', 'send_custom_status_email', 10, 4 );

In case you need no-code solution, there is a number of plugins that will help you to create your own order statuses easily:
| Plugin | Price | Key Features |
| WooCommerce Order Status Manager | — | Official extension, email integration, reports |
| YITH WooCommerce Custom Order Status | — | Custom icons, colors, and extensive customization |
| Custom Order Status by Addify | — | Automation rules, email notifications |
| Automated Order Status Controller | — | Time-based automation, conditions |
| Custom Order Status for WooCommerce (Tyche) | — | Basic functionality, admin emails |
The closest integration is offered by the official WooCommerce Order Status Manager plugin:
Features:
Setup Process:
Follow these best practices to ensure your custom statuses work effectively:
Do:
Don’t:
Keep it Simple:
Do not create too personal statuses. The higher the statuses the more complicated the working process will be and the staff is likely to be confused.
Map Your Process:
Before creating statuses, map your entire order fulfillment process. Identify only the stages that truly need tracking.
Consider Customer Impact:
Only expose statuses that provide meaningful information to customers. Internal statuses (like “Awaiting Manager Approval”) might not need customer visibility.
Here are practical examples of custom statuses for different business types:
| Status | Use Case |
| Awaiting Shipment | Order packed, waiting for carrier pickup |
| Shipped | The package was handed to the carrier |
| Out for Delivery | Package with a local delivery driver |
| Delivered | Confirmed delivery |
| Status | Use Case |
| In Production | Item being manufactured |
| Quality Check | Verifying print quality |
| Ready to Ship | Passed QC, awaiting shipment |
| Status | Use Case |
| Preparing | Kitchen preparing order |
| Ready for Pickup | Order ready, awaiting driver |
| Out for Delivery | Driver en route |
| Delivered | Customer received the order |
| Status | Use Case |
| Awaiting Curation | Items being selected |
| Packing | Box being assembled |
| Shipped | In transit to the customer |
Problem: Your custom status doesn’t show in the dropdown.
Solutions:
Problem: Orders vanish when changed to custom status.
Solutions:
Problem: Email notifications don’t trigger for custom status.
Solutions:
Problem: Custom status orders don’t appear in WooCommerce reports.
Solutions:
Automate status transitions based on specific conditions:
/**
* Automatically set custom status after payment
*/
function auto_set_custom_status_after_payment( $order_id ) {
$order = wc_get_order( $order_id );
// Check if order contains specific product category
foreach ( $order->get_items() as $item ) {
$product = $item->get_product();
if ( has_term( 'custom-made', 'product_cat', $product->get_id() ) ) {
$order->update_status( 'wc-in-production', 'Order moved to production queue.' );
return;
}
}
}
add_action( 'woocommerce_payment_complete', 'auto_set_custom_status_after_payment' );
/**
* Auto-complete orders after 14 days in 'Shipped' status
*/
function auto_complete_shipped_orders() {
$orders = wc_get_orders( array(
'status' => 'wc-shipped',
'date_modified' => '<' . ( time() - 14 * DAY_IN_SECONDS ),
'limit' => -1,
) );
foreach ( $orders as $order ) {
$order->update_status( 'completed', 'Auto-completed after 14 days.' );
}
}
add_action( 'woocommerce_scheduled_sales', 'auto_complete_shipped_orders' );
Custom order statuses transform WooCommerce from a standard e-commerce platform into a tailored order management system that matches your exact business workflow. Whether you implement them through code or plugins, custom statuses provide:
Begin with mapping your current order process, finding the gaps in the default statuses and only the custom statuses that will add value are implemented. Always use a staging environment to test thoroughly before rolling out to production and also do not forget to configure proper email notifications to keep customers informed.
With custom order statuses properly configured, you’ll have a more organized store, happier customers, and better insights into your business operations.

Hassan Tahir wrote this article, drawing on his experience to clarify WordPress concepts and enhance developer understanding. Through his work, he aims to help both beginners and professionals refine their skills and tackle WordPress projects with greater confidence.