All WooCommerce orders go to either “processing“, “completed“, “on-hold” and other default order statuses based on the payment method and product type.
Sometimes these statuses are not enough. For example, you might need to mark certain orders in a different way for tracking, filtering, exporting purposes. Or you might want to disable default emails by bypassing the default order status changes.
Either way, creating a custom order status is quite easy. And today we’ll see which PHP snippet you need in order to make this work!

PHP Snippet: Create a Custom WooCommerce Order Status
/**
* @snippet Custom WooCommerce Order Status
* @how-to businessbloomer.com/woocommerce-customization
* @author Rodolfo Melogli, Business Bloomer
* @compatible WooCommerce 8
* @community https://businessbloomer.com/club/
*/
add_filter( 'woocommerce_register_shop_order_post_statuses', 'bbloomer_register_custom_order_status' );
function bbloomer_register_custom_order_status( $order_statuses ) {
// Status must start with "wc-"!
$order_statuses['wc-custom-status'] = array(
'label' => 'Custom Status',
'public' => false,
'exclude_from_search' => false,
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true,
'label_count' => _n_noop( 'Custom Status <span class="count">(%s)</span>', 'Custom Status <span class="count">(%s)</span>', 'woocommerce' ),
);
return $order_statuses;
}
add_filter( 'wc_order_statuses', 'bbloomer_show_custom_order_status_single_order_dropdown' );
function bbloomer_show_custom_order_status_single_order_dropdown( $order_statuses ) {
$order_statuses['wc-custom-status'] = 'Custom Status';
return $order_statuses;
}
Hi Rodolfo,
thanks for the code! However I can’t get it to work in the bulk actions dropdown. Using WP6.6 and Woo 9.1.2. I’ve tried a bunch of other codes I found as well (and on multiple websites), but none shows up in the dropdown. I guess something has changed in the new Woocommerce. Can you please have a look at it? Thanks!
I don’t think anything has changed there to be honest. If you temporarily revert to Woo 8, does this work (you can use the WP Rollback plugin for that)?
Hi, there! Thank you so much for this. I was able to successfully add two custom statuses. How do I get WooCommerce to understand that my custom_order_status with label ‘Etsy Order Open’ is a WooCommerce “processing” order? My label works beautifully but instead of showing me that I have an order open to fulfill it is treating it as “completed.” What am I missing?
Awesome! What do you mean here exactly:
Hey Rodolfo,
It is not on WP version 6.3.1. Can you help please?
Hey Ali, thanks so much for your comment! I just retested this on the latest version of WooCommerce and it still works. Unfortunately this looks like custom troubleshooting work and I cannot help here via the blog comments. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding! ~R
Thank you it works but I can’t make a second order status! It doesn’t seem to take!
odd
Definitely odd!
Hi
thanks for your code, we try to run this code using php 7.4 and Woocomerece 7.1 but we always got syntax error is their is any changes in code to run correctly
thanks
Syntax error on which line, please?
Fatal error: Uncaught Error: Argument 1 passed to Automattic\WooCommerce\Blocks\Domain\Services\DraftOrders::register_draft_order_status() must be of the type array, null given
Sorry, I need more context. Please share the whole code you wrote + the page or the moment where you get the Fatal Error, so that I can double check.
Also, it seems to be a problem with WooCommerce Blocks, so I definitely need more information. Thank you!
Hi, thank you. This works (january 2022).
What I am looking for is that the customer can place an order and can choose if the order is concept or definitive.
Idea is that a customer can place an order but has the ability to mark it as ‘concept’ so he can add or change the order later. When he marks it as ‘concept’ the custom order status is given to that order*.
So later on he can login in his account and change the amount of a certain product, add products etc.. and decide to make the order final.
* For the shopowner this custom order status means that the order should not be processed yet.
Thanks for your comment Edwin! I also have a tutorial for https://www.businessbloomer.com/woocommerce-edit-orders/, see if that helps a little
Great, I’ll look in to that.
Thank you
Hi,
Great code, using it. Works most all of the time, BUT sometimes there is an issue.
I using it for new orders. When new order comes in, status changes to “custom status”, that’s great, but 1 of 10 or 20 order not changing status, it comes with default status “processing” :/ maybe there is some thoughts, what it could be. There is no conection with this issue and payment manager (credit card, bank transfer etc..), it looks like randomly sometimes not changing staus.
Weird. Is it always you placing new orders? Could it be the cache?
Hi Rudolfo,
Thank you for your post. It was extremely helpful. The code works perfectly as it is. Then I wanted to change it. I wanted to set “Awaiting Confirmation” as default status. But the issue is when I tried replacing wc-custom-status with wc-awaiting-confirmation. It doesn’t work. Changing to this doesn’t work and status shows as processing. Also, it doesn’t get set as default status either. I later changed wc-awaiting-confirmation with wc-ac and it worked perfectly. Any insights?
No idea, it depends on your order status ID, which is a custom one
Hi,
Some of my products require a questionnaire to be filled out before shipping.
Could I analise if the order contains any products have a “Requires Questionare” Tag I will make and give them a specific custom order status if they do?
Hey Ari, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!
Hi, Thanks for the code. I’ve written the same comments over at your Sending Custom Emails for New orders post as well.
But maybe here is a better place, since Emails are successful, just that the Order Status workings is odd.
Use Case :
1) For Preorders (Stock Status) – Auto triggered, to Set Preorder Pending using On-hold Emails (With this On-hold emails should not be sent out at all)
2) Preorders Paid – Manual Triggered from Order Management.
It seems that your above code is good for Case 1, with some tweaks.
But Am trying to achieve the simpler Case 2.
** Am I right to say I can just remove your : 3) Assign Status at Checkout process?
** Separately I’ll like to use this whole coding for Case 1, but need to tweak as in only for Preorders (Stock Status), and stop Default Onhold emails from sending out. (Confusing for Customers with so many initial Emails out just an order)
Thanks!
Like to add that I have solved the simpler use case — Preorder Paid.
I’m still hoping you could help to tweak for Preorder Pending Use Case.
Thanks!
Hi Faustine, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!
Hello,
Is there a way to set the color of the status when checking orders? https://prnt.sc/r2i85k
Would be pretty cool to separate it!
Hey Georgi, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!
Hi,
I had a question,
I created a new client state called “budgets” and also a new tab created for “budgets”, it made me crazy to find how to filter orders with budget status.
I want to show in that new tab only orders with “budget” status. ¿Is this possible?
I have personalized my website with many code of your website, I take the opportunity to thank you infinitely
Thank you
a greeting
Hi Frank, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!
I notice under woocommerce plugin, there is no ‘delivery” order status and “delivery” email notification. Is this necessary to send done “delivery” email notification to customer and update “delivery” order status after delivery is done?
You would use the “Completed” for that reason. Otherwise you need to define a custom order status and custom email notifications
Hi, your code works perfect but it is not added the order prices in woocommerce homepage summary. Like if order amount is $10 and when order is in process status the summary display $10 but when i change status the wocommerce summary show 0$.
Screenshot?
Thanks you save my life
Cool!
Hello Rodolfo!
Thank you so much for the great article!
I would like to ask a question.
Will it be possible to automatically change the order status by product category?
For example…
When category A product A was paid, I would like to put the status as “completed.”
But when product A of category B was paid, we would like to put as “on-hold” status.
Or by the other way, “bbloomer_thankyou_change_order_status” can only function in specified category.
Kind regards.
Hi DT, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!
Hi Rodolfo!
This looks great, exactly what I was looking for.
Just a small additional question; is it possible to add a custom order status to order from specific countries? I’m based in the EU, so i need a custom order status for order from U.S. & Canada for the logistic party to pick it up.
Hopefully, there’s a way… I’ve tried everything. Thank you in advance. 🙂
Kind Regards,
Jeroen Feron
Hello Jeroen, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!
Hi
I am new to Woocommerce, but I am familiar with PHP
I want to set status=on hold on all new orders IF customer wrote an order note.
so i imagine that the logic should look something like this
Thank You 🙂
would this do the trick???? (youre welcome to copy)
Hey Michael, thanks for your comment! Did you test it?
It works great, TYVM for this. Can this code be used to do two or more custom order status’?
Excellent! Yes it can 🙂
Hi, every thing seems to be working correctly. But I am facing with this strange thing, that if order has this new custom status and I change the status to “Processing” then the email for processing status is not sent. But if the status is “Pending” and you change to “Processing” then everything works correctly. Do you have any ideas about this issue?
Hello Kipras, thanks so much for your comment! Unfortunately this looks like custom troubleshooting work and I cannot help here via the blog comments. Thanks a lot for your understanding! ~
Hi Rodolfo,
following your code, i had an issue with admin order list page. When i open this page i can’t see previous orders anymore because of the ‘wc_order_statuses’ filter, with your structure.
I had to set my code like this in order to work:
Thanks!
Thanks 🙂
Good day,
Pls how can i set custom order status for a particular payment gateway, example i want all orders made using a particular payment gateway to be in waiting payment status or pending quote status uisng the yith woocommerce request quote plugin..
Please how can i do this?
Hey Chris, thanks so much for your comment! Yes, this is possible – unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R
Is it possible to use a snippet:
When shipping an order:
If
order has balance outstanding ($ owing)
then
update status to custom status: account receivable
send different email than status completed email. eg ac-rec invoice
— Moving from Drupal.. so its a bit of a learning curve.
Cheers for the tips!
Hey Crab, thanks so much for your comment! Yes, this is possible – unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding! ~R
Hi
Great tip, thanks very much. One question, is it possible to have two custom statuses, by doing a modification of your code?
Reason for asking; we want to use the commerce engine primarily for quotes. by having two statuses we would have one for “quote in progress” and quote sent. Both without sending any mails (which is great).
Thanks!
Hey Knut, thanks so much for your comment! Yes, this is possible – just add another $order_statuses[‘another-status’] array to the same function 🙂
Hi!
Great guide and contribution!
How can i add so that it only changes to this order-status for product with a specific custom field?
For example:
Custom field name is “Paymentdetails” and value is “teacher”
Best regards
Adam
Hey Adam, thanks for your comment! I suggest you take a look at “conditional logic”: https://businessbloomer.com/conditional-logic-woocommerce-tutorial/ and https://businessbloomer.com/woocommerce-conditional-logic-ultimate-php-guide/. Let me know 🙂
Hi Rodolfo
cam across your excellent mod here this morning. Have but one question.
is it possible to add another custom status with no mail sending?
Reason for asking, we’ll use woocommerce primarily for quotes, with the quote plugin. Thus it would be practical to have two custom statuses, one for quote in progress, and another for quote completed.
Thanks!
Hey Knut, thanks for your comment! Yes, of course, you can 🙂
The code removes “Processing” and “Complete” from the quick-view when clicking the “eye”. Any fix for that?
Hey Bjornen, thanks for your comment. Screenshot please?
Hi,
Can we have more than one custom status from same function ? pl advice.
Thanks
Hey Kumar – yes you can 🙂 But I can’t share this here – thanks for the understanding.
This article was super helpful! We use woocommerce for our sales and checkouts for out website. With so many backend details it’s hard to know what changes what, unless your an expert!
Cool 🙂
It worked on single order page drop down. Thanks.
Is there is way it also can work on order page (dropdown Bulk Actions)
Hey Mark – thanks so much for your comment! Part #2 does that already 🙂
Hi ,
It’s visible only inside single order page. It doesn’t display (drop down) on order page .
Pl check and advice.
Fixed 🙂
It Worked . But all new orders are getting custom status . How do we keep it on manual basis? I want to keep as processing Status for all new orders.
Also – Moment I removed Snippet from function file . All orders with custom status disappeared from order management page .
Pl check
Hey Kumar 🙂
1) Just delete snippet part #3
2) Reactivate the snippet – change the order status to e.g. Processing – disable the snippet
Hope this helps 🙂
Was Waiting for This .. Can i change keyword from custom to SHIPPED ?
Pl advice. Thanks.
Of course Kumar! Just change all “custom status” occurrences to “shipped” 🙂