Custom Order Status (Woocommerce)

Thanks to the handy instructions at

I’m testing a solution to a problem we experience with our online store. I’ll be modifying the code from the above post a little bit, and I’ll walk through the implementation and effects.


Our website is built in WordPress. We use Woocommerce for our online store, and we use the IgniteWoo Gift Certificates Pro plugin to create and manage redemption of virtual gift certificates. The Webgility software Unify Enterprise pulls orders from Woocommerce and sends them to Quickbooks.

All orders are sent as Sales Receipts to Quickbooks, which throws an error when Gift Certificates are redeemed for a purchase, because the transaction amount is $0 (where the full purchase amount was discounted by the Gift Certificate amount).

Our workaround is to manually create the invoice in Quickbooks, where the Gift Certificate redemption is entered as a payment method with a negative amount, where the payment method is tied to (and reduces from) the Gift Certificates Payables liability account in Quickbooks.


Manually entering the orders into Quickbooks takes time. We would prefer to send only Gift Certificate redemption orders from Unify as Invoices, to avoid the $0 transaction rule, while all other web orders are sent as Sales Receipts. Unify allows three options for the rules governing the transaction types format:

-Same transaction type for all orders

-Different transaction type based on payment method

-Different transaction type based on order status.

Since our Gift Certificate Pro plugin will not allow a gift certificate redemption to be considered a payment method, we will need a custom order status. I’ll then set up Unify to use different transaction types based on order status – Pending = Sales Receipt, Custom Status= Invoice.


We have a dev site set up for this kind of testing. It’s a full copy of our entire website accurate from a couple of months ago. I use it to test plugin updates and any code updates.

I’ll modify the original code to create a custom status called “Gift Cert Redempt”, to be used only when a customer purchases items on our website using a gift certificate code. We’ll have to manually change the order status from “Processing” to “Gift Cert Redempt” after Unify throws the error message, and then re-pull the item into Unify, but it will be quicker than manually entering the invoice.

Since I’m only about three months into WordPress development, I’ll be annotating the code provided on the above link. The first step is to comment from the description at the above link:


I still don’t entirely understand everything that is happening here, so I’m going to narrate while I translate.

We begin with a function called “register_shipment_arrival_order_status” which contains no parameters – the () part – and inside that function is the function we are naming “register_post_status” which contains after the opening parentheses the arguments ‘wc-arrival-shipment and an array which contains, within parentheses, the key-value pairs describing the attributes of the custom order status we are adding.

Within the context of core WordPress development, register_post_status is an included function (we are not making a new thing here). We are creating a new function called register_shipment_arrival_order_status which contains no arguments, and when that function is called, it calls the core WordPress function register_post_status, which according to core documentation, expects a name and an array. The name is the first parameter (a string), then a comma, then the array, which we call array() and then stick some key-value pairs in there with hash rockets.


Yes, that’s actually legitimately called a hash rocket. Programmers are cool.

So the key value pairs break down like this:

Still have some unanswered questions. What’s _n_noop? There’s some WordPress documentation, but I don’t know if it really helps and this might be a rabbit hole I don’t need to go down right now.

Register plural strings in POT file, but don’t translate them.

Used when you want to keep structures with translatable plural strings and use them later.

Yes this indeed is not the hole I need to be going down. _n_noop does a thing, that’s all I need to know.

What about the parenthetical section just after the noop? That is some HTML. Oh, that is some HTML, which is comma delimited, so that is the plural strings referenced in noop? Sounds good. Moving on.

After we close the register_post_status function definition, we add an action with add_action which is also a function which accepts two parameters within parentheses:

Core WordPress Documentation describes this function. It hooks a function to an action. Hooks are a WordPress thing. I’m not quite there yet.

Actions are the hooks that the WordPress core launches at specific points during execution, or when specific events occur. Plugins can specify that one or more of its PHP functions are executed at these points, using the Action API.

Thing that does a thing, and when. Good enough for now.

Syntax for add_action arguments are ‘name of action’, ‘name of function to call’. So “when” to do the thing, and what to do. There are other available arguments but we’re not using them in this code here.


Fires after WordPress has finished loading but before any headers are sent.

Most of WP is loaded at this stage, and the user is authenticated. WP continues to load on the init hook that follows (e.g. widgets), and many plugins instantiate themselves on it for all sorts of reasons (e.g. they need a user, a taxonomy, etc.).

Because with WordPress, we are dynamic, not static. There is a “framework” for the page which is filled with content based on a query to the database. Yep. Cool.

So we have created a function, put a function in it, and told it what to do. Then we told WordPress when to do the thing. But there’s still a little more code to annotate!

We’ve got another function, some loops, and we add a filter. Here’s the next function without additional annotation:

We create a new function called add_awaiting_shipment_to_order_statuses with the parameter, in parentheses, the variable $order_statuses. Then we tell the function what it does.

First, it creates an array named $new_order_statuses. This occurs through the following line of code:

So that is a variable which contains an empty array.

Next line we have a foreach loop, which reads through each item of current order statuses (the $order_statuses variable), which is an array of key-value pairs. We remind the loop that the key-value pairs are $key => $status.

This is where we branch out from core WordPress and we’re in Woocommerce territory. While we use the core WordPress “custom post” function, Woocommerce is an ecommerce platform, so now we’re talking orders. Woo has an array of order status options and we are adding into it and it will display in the list when we’re in admin view (the back-end of the website. Code is the back-end back-end).

Here’s some Woocommerce documentation on wc_get_order_statuses.

It’s a function we get access to through the Woocommerce plugin, and it creates an array called $order_statuses containing the available order statuses.

So within the function where we are going to add the custom status, we loop through the $order_statuses array.

I’ll be honest with you, I’m not real sure what we’re doing. I thing we’re setting the key in the key-value pair in the $new_order_statuses array we just made as the status of each item in the $order_statuses array, which is flipping it, because I think in the original order status array we’re referencing the status is the value, but ok. Let’s move on.

So if the key is IDENTICAL to ‘wc-processing’, add in the new order status.  Oh, and a return statement, which is like hey please remember that u did a thing and don’t just walk off and leave it laying on the table.


So we’ve stuck into the array the custom order status we want to add. But we still gotta make it happen. We’ve not done the thing, we’ve just created two functions, or lists of instructions, which do the following:

  1. What is the thing? Sets the values for the custom post status (label, where it’s displayed, etc)
  2. Where does it go? Sticks it in the list of order statuses.

We added an action to call the first function when the page is loaded. Now we add another action. Luckily this one’s in core WordPress documentation and then I’m done exhaustively breaking this thing down.

Okay. add_filter is a core WordPress function which connects the second function we created to the Woocommerce Orders List. Because when we make a function we need to actually use it somewhere.

So I’m going to change the name of the order status to Gift Cert Redemption, stick the code (with comments because whatever and I might want to look at them later) right straight directly into Woocommerce.php through the plugin editor. It’s scary, but I’m testing it on the dev site first.


Once we can select a custom order status to indicate that an item is a Gift Certificate Redemption purchase, I’ll change Unify’s settings to push any orders with that status into QB as Invoices ,while all other statuses are Sales Receipts. Hopefully this will allow us to bypass the “Transaction can’t be $0” error message, and will make everybody in the back office happier.

Follow up of a sort is at this post.

Leave a Reply

Your email address will not be published. Required fields are marked *