In this post, I look at all the different action hooks that fire when an WooCommerce order status changes. There are four hooks you can use:
woocommerce_order_status_$NAME
woocommerce_order_status_$FROM_to_$TO
woocommerce_order_status_changed
woocommerce_order_payment_status_changed
Read on for detailed example of how to use each one:
1. woocommerce_order_status_$NAME
This is the first action hook that fires when an order status is changed in WooCommerce.
To use it, simply replace $NAME
with the slug of the status name it is changing to.
For the default WooCommerce statuses, here is how the hook would look:
woocommerce_order_status_pending
– When an order status is changed to “Pending”woocommerce_order_status_processing
– When an order status is changed to “Processing”woocommerce_order_status_on-hold
– When an order status is changed to “On-hold”woocommerce_order_status_completed
– When an order status is changed to “Completed”woocommerce_order_status_cancelled
– When an order status is changed to “Pending”woocommerce_order_status_refunded
– When an order status is changed to “Refunded”woocommerce_order_status_failed
– When an order status is changed to “Failed”
You can also use it with any custom status you have created. For example, if we have created a “Shipped” custom status, the hook would look like:
woocommerce_order_status_shipped
The hook provides the Order ID ($order_id
), and Order object ($order
) as a parameters.
Example 1:
In this simple example, when an order status is changed to “Processing”, we will add an order note.
add_action( 'woocommerce_order_status_processing', 'add_processing_note', 10, 2 ); function add_processing_note( $order_id, $order) { // add a note $order->add_order_note( "Cash money!" ); }
Result:
2. woocommerce_order_status_$FROM_to_$TO
The woocommerce_order_status_$FROM_to_$TO
hook allows you to target more specific situations.
You must specify the order status that it is changing FROM, as well as the status it is changing TO.
For example, if you want run a function when the order status changes from “Processing” back to “Pending”, it would look like:
woocommerce_order_status_processing_to_pending
This hook also provides the Order ID, and Order object as parameters.
Example 2:
In this snippet, we will send an email when an order status is changed from “Completed” back to “Pending”.
add_action( 'woocommerce_order_status_completed_to_pending', 'completed_to_pending_email', 10, 2 ); function completed_to_pending_email($order_id, $order) { // 1. get some order data if you want $edit_order_url = $order->get_edit_order_url(); // 2. send an email wp_mail( "[email protected]", // recipient email "Something weird happened to Order #$order_id", //subject "Order #$order_id was changed from Completed to Pending. <a href=$edit_order_url>Check it out</a>", //message array('Content-Type: text/html; charset=UTF-8'), // email headers ); }
Result:
3. woocommerce_order_status_changed
The woocommerce_order_status_changed
hook fires on every possible order status change.
That means your custom function will also be triggered for every status change.
woocommerce_order_status_changed
provides three parameters to your function — the Order ID, ‘from’, and ‘to’ statuses.
Example 3:
We will copy the basic snippet from the first example and adapt it to use the woocommerce_order_status_changed
hook instead.
Using the provided $from
and $to
parameters, we can specify to add a note only if the order is going from “Pending” to “Processing”.
add_action( 'woocommerce_order_status_changed', 'add_processing_note_v2', 10, 3 ); function add_processing_note_v2( $order_id, $from, $to ) { // 3 parameters provided // 1. return if status is not changing from pending->processing if( $from!=='pending' && $to!=='processing' ) return; // 2. get order object $order = wc_get_order( $order_id ); // 3. add a note $order->add_order_note( "Cash money again!" ); }
Result:
Note:
Since this hook fires later than the woocommerce_order_status_
$NAME hook (from Example 1), our custom note (i.e. “Cash money again!”) is also added later.
The default WooCommerce note (i.e. “Order status changed from Pending payment to Processing”) is added before it. Compare this to Example 1, where the default note is added after.
4. woocommerce_order_payment_status_changed
The woocommerce_order_payment_status_changed
hook is fired only when an order is changed from “Pending” to a paid status (i.e. either “Processing” or “Completed”).
It provides two parameters, the order ID and order object
Example snippet
We will again add a custom order note as a basic use example.
add_action( 'woocommerce_order_payment_status_changed', 'add_payment_note', 10, 2 ); function add_payment_note( $order_id, $order ) { // add a note $order->add_order_note( "Cash money again, again!" ); }
Result:
Summary
When an order status changes in WooCommerce, there are four possible action hooks you can use depending on your needs. They are triggered in this order:
woocommerce_order_status_NAME
woocommerce_order_status_FROM_to_TO
woocommerce_order_status_changed
woocommerce_order_payment_status_changed
Hope this helps!
😁
Reference:
WooCommerce Code Reference