woocommerce_order_status_changed

WooCommerce fires this action when an order changes status, passing the order ID, previous status, new status, and current order object to callbacks.

Quick Reference

TypeAction hook
AreaOrders
Arguments$order_id (int), $old_status (string), $new_status (string), $order (WC_Order)
SourceWooCommerce code reference

How It Works

The action fires during the order's status transition handling. Status values such as processing and completed are plain status slugs without the wc- prefix. Registering four accepted arguments lets your callback inspect both states and the order object.

PHP Example

add_action( 'woocommerce_order_status_changed', function ( $order_id, $old_status, $new_status, $order ) {
    if ( 'completed' === $new_status ) {
        $order->add_order_note( 'Order reached completed status.' );
    }
}, 10, 4 );

This adds a private order note whenever an order transitions into completed. If the same order later leaves and re-enters that status, another note will be added.

Add the code to a site-specific plugin or a child theme's functions.php file, then test it on a staging site.

Common Pitfalls

This is a status-transition hook, not a general new-order event. WooCommerce runs it when an order has a previous status to change from. If you need to respond to order creation itself, use an event intended for that stage instead.

An order can enter completed more than once, and staff can change statuses manually. For notifications, fulfillment integrations, or other external effects, guard against running the same operation twice. Also, completed describes the order's fulfillment status and should not be treated as proof that a particular payment was captured.

Compatibility

This action concerns WooCommerce orders rather than a particular checkout page. It can run for admin-driven and programmatic changes, so callbacks must not assume a customer is viewing the store. For custom order metadata, use $order->get_meta() and $order->update_meta_data(), followed by $order->save(), to remain compatible with High-Performance Order Storage (HPOS).