Black Friday & Cyber Monday SUPER SALE ALL WEEK:
Grab 40% OFF on plugins
Days
Hours
Minutes
Seconds

How to Use WooCommerce Order Hooks To Simplify Order Management ?

In this post, we will uncover how WooCommerce order hooks are used to perform actions or events during the various stages of an order lifecycle. These hooks allow developers to modify or add custom functionality at specific points in the process without directly editing the core files.

List of Order Hooks in Classic Checkout

1. Order Creation and Update Hooks

woocommerce_checkout_create_orderFired before the order is saved.
woocommerce_new_orderFired after the order is created.
woocommerce_checkout_order_createdFired after the order and its custom item meta are saved.
woocommerce_checkout_order_processedFired after the order is created but before payment is processed.

let’s explore how you can implement them to customize your store’s functionality.

  • woocommerce_checkout_create_order:

With this hook ‘woocommerce_checkout_create_order‘, you can access and modify the order and the checkout data before it is saved into the database. For example, you can modify the billing or shipping details, add custom order meta, apply discounts, or trigger custom actions.

add_action( 'woocommerce_checkout_create_order', 'custom_checkout_create_order', 10, 2 );

function custom_checkout_create_order( $order, $data ) {
    // Add your custom code here to manipulate the order before it is saved
    // For example, you can modify billing or shipping details:
    
    // Example: Set a custom billing city
    // $order->set_billing_city( 'Custom City' );
    
    // Example: Add a custom order note
    // $order->add_order_note( 'Custom order note' );
    
    // Example: Add a custom fee
    // $order->add_fee( 'Custom Fee', 10, true );
    
    // You can add any other logic to customize the order as needed
}
  • woocommerce_new_order:

This hook will perform an action just after the new order is created in WooCommerce, which happens after the checkout process is completed successfully. When the hook is triggered the order data will be already saved to the database. This might be used in many use cases such as sending order data to external API, sending order emails to customers or admins, and other post creation order actions etc.

add_action( 'woocommerce_new_order', 'custom_new_order_action', 10, 1 );
function custom_new_order_action( $order_id ) {
    $order = wc_get_order( $order_id );
    // Your custom code
}
  • woocommerce_checkout_order_created:

Use this hook for tasks that depend on saved order details. If your order details have custom field options, such as ‘Gift Wrapping,’ which are stored as metadata, this hook allows you to retrieve and use that metadata for sending it in order confirmation emails.

function after_order_placed( $order ) {
    // Loop through each item in the order.
    foreach ( $order->get_items() as $item_id => $item ) {
        // Get custom metadata for the item.
        $custom_meta = $item->get_meta( 'Custom Key' );

        // Perform actions with the custom metadata.
        if ( $custom_meta ) {
            // Example: Log the custom meta data for debugging.
            error_log( "Custom Meta for Item ID $item_id: $custom_meta" );
        }
    }
}
add_action( 'woocommerce_checkout_order_created', 'after_order_placed' );
  • woocommerce_checkout_order_processed:

This hook is used in scenarios where you want to perform action based on the order details just after an order is completed.

add_action('woocommerce_checkout_order_processed', 'reserve_inventory_on_order', 10, 3);

function reserve_inventory_on_order($order_id, $data, $order) {
    // Custom inventory logic here
}

2. Order Status Change Hooks:

Includes all hooks related to status changes (e.g., pending to processing).

woocommerce_update_orderFired whenever an order is updated (e.g., status, items, shipping/payment changes).
woocommerce_order_status_{$status_from}to{$status_to}Fired for specific status transitions, such as from “Pending” to “Processing.”
woocommerce_order_status_changedFired whenever the order status changes, regardless of the specific status.

Look into the hooks of order status changes with the sample code given below:

  • woocommerce_update_order: This hook is used for any kind of update to an order, like changing the order details, products, or status.
add_action( 'woocommerce_update_order', 'add_note_when_order_completed', 10, 1 );

/**
 * Adds a note to the order when the status changes to 'Completed'.
 *
 * @param int $order_id The ID of the updated order.
 * 
 * @return void
 */
function add_note_when_order_completed( $order_id ) {
    // Get the order object
    $order = wc_get_order( $order_id );
    
    // Check if the order status is 'completed'
    if ( $order->get_status() === 'completed' ) {
        // Add a note to the order
        $order->add_order_note( 'Order has been successfully completed.' );
    }
}
  • woocommerce_order_status_{$status_from}_to_{$status_to}: This is a dynamic hook which is flexible at transitions of order statuses. For example, when an order changes from “pending” to “processing”, the hook would be ‘woocommerce_order_status_pending_to_processing‘.
add_action( 'woocommerce_order_status_pending_to_processing', 'custom_action_on_pending_to_processing', 10, 1 );

function custom_action_on_pending_to_processing( $order_id ) {
    // Do something when the order status changes from "pending" to "processing"
    $order = wc_get_order( $order_id );
    $order->add_order_note( 'Order status changed from pending to processing.' );
}
  • woocommerce_order_status_changed: This is a more generic hook that fires every time an order’s status changes, regardless of which status it’s changing from or to.
add_action( 'woocommerce_order_status_changed', 'custom_order_status_changed', 10, 4 );

function custom_order_status_changed( $order_id, $old_status, $new_status, $order ) {
    // Check if the new status is 'completed'
    if ( 'completed' === $new_status ) {
        // Perform your custom actions here
        // Example: Log order ID when status changes to 'completed'
        error_log( 'Order #' . $order_id . ' status changed to completed.' );
    }
}

3. Payment and Thank You Hooks

woocommerce_payment_completeFired when the payment is completed for specific order statuses.
woocommerce_thankyouDisplayed after the order is placed (though not recommended for all payment methods).

This hook ‘woocommerce_payment_complete‘ gets triggered once a payment for an order is successfully completed. But the hook is triggered only if the orders are in certain statuses such as on-hold, processing, completed, Failed before the payment is completed.

add_action( 'woocommerce_payment_complete', 'ts_complete' );

function ts_complete( $order_id ) {
	
	$order = wc_get_order( $order_id );
	// do anything
	
}

This hook ‘woocommerce_thankyou‘ is typically used to customize the order confirmation experience on the thank you page, add upsell/cross-sell options, and send custom thank you messages via emails.This hook gets triggered once a payment for an order is successfully completed. But the hook is triggered only if the orders are in certain statuses such as on-hold, processing, completed, Failed before the payment is completed.

add_action( 'woocommerce_thankyou', 'custom_thank_you_message', 10, 1 );

function custom_thank_you_message( $order_id ) {
    $order = wc_get_order( $order_id );
    echo '<h2>Thank You for Your Purchase!</h2>';
    echo '<p>Your order number is: ' . $order->get_order_number() . '</p>';
}

List of Order Hooks in Blocks Checkout

While some traditional classic checkout hooks, such as woocommerce_new_order, woocommerce_update_order, woocommerce_payment_complete, and woocommerce_thankyou, are common, they might also work with the new checkout blocks. Since the new checkout blocks use more API-based interactions (via the REST API), hooks like woocommerce_store_api_checkout_order_processed are unique to this block-based system.

1. Order Creation and Update Hooks

woocommerce_new_orderFired when a new order is created
woocommerce_update_order Fired multiple times when the order is updated

a. Order is Created or Updated Manually in the WordPress Admin

To differentiate whether the action is from the admin, you can check the nonce in the request. If the nonce is valid, the action comes from the admin.

add_action( 'woocommerce_new_order', 'ts_create_or_update_order', 25, 2 );
add_action( 'woocommerce_update_order', 'ts_create_or_update_order', 25, 2 );

function ts_create_or_update_order( $order_id, $order ) {
    if ( isset( $_REQUEST[ '_wpnonce' ] ) && wp_verify_nonce( $_REQUEST[ '_wpnonce' ], "update-order_{$order_id}" ) ) {
        // Do your stuff (e.g., log the order creation or update)
    }
}

b. Order Created or Updated via REST API

To check if the hook is coming from the REST API, you can check if REST_REQUEST is defined.

add_action( 'woocommerce_new_order', 'ts_create_or_update_order_restapi' );
add_action( 'woocommerce_update_order', 'ts_create_or_update_order_restapi' );

function ts_create_or_update_order_restapi( $order_id ) {
    if ( defined( 'REST_REQUEST' ) ) {
        // Do your stuff when order is created/updated via API
    }
}

2. Block Checkout-Specific Hook

woocommerce_store_api_checkout_order_processedSpecific to Block Checkout and this hook is triggered when checkout orders are processed via REST API.
add_action( 'woocommerce_store_api_checkout_order_processed', 'ts_handle_block_checkout_order', 10, 2 );

function ts_handle_block_checkout_order( $order_id, $data ) {
    $order = wc_get_order( $order_id );

    // Example: Log order ID and total amount
    error_log( 'Block Checkout Order Processed - Order ID: ' . $order_id );
    error_log( 'Order Total: ' . $order->get_total() );

    // Add any custom logic here, such as sending notifications or updating order metadata
}

3. Order Status Change Hooks

The below hooks are same as Classic Checkout hooks, but could be fired at different stages due to the Block Checkout flow.

woocommerce_update_orderFired whenever an order is updated (e.g., status, items, shipping/payment changes).
woocommerce_order_status_{$status_from}to{$status_to}Fired for specific status transitions, such as from “Pending” to “Processing.”
woocommerce_order_status_changedFired whenever the order status changes, regardless of the specific status.

4. Payment and Thank You Hooks

woocommerce_payment_completeFired when payment for the order is completed
woocommerce_thankyouTriggered when the order is complete

Common Hooks to Be Used Both in Classic and Checkout Blocks

1. Order Deletion Hooks

woocommerce_before_delete_order or woocommerce_before_trash_orderTriggered before the order is deleted or moved to trash.
woocommerce_delete_order or woocommerce_trash_orderFired when the order is deleted or moved to trash.

When an order is deleted, depending on whether it is moved to trash or it is permanently deleted these hooks will be used.

add_action( 'woocommerce_before_trash_order', 'ts_trash_order' );

function ts_trash_order( $order_id ) {
    if( isset( $_REQUEST[ '_wpnonce' ] ) && wp_verify_nonce( $_REQUEST[ '_wpnonce' ], 'bulk-orders' ) ) {
        // Do your stuff when order is moved to trash
    }
}

2. Order Refund Hooks

To handle actions specific to refunds, certain hooks are triggered, including:

woocommerce_order_fully_refunded or woocommerce_order_partially_refundedTrigerred specifically related to full or partial refunds.
woocommerce_update_ordertriggered whenever an order is updated, not necessarily due to a refund.
woocommerce_order_refundedfires when a refund is processed, which could be partial or full.

If you aim to use hooks dedicatedly to add custom content in cart and checkout pages, then refer to the the visual cart page hooks and the visual checkout page hooks guide that can be used to optimize cart and checkout layouts.

Browse more in: Code Snippets, WooCommerce How Tos, WooCommerce Tutorials

Share It:

Subscribe
Notify of
0 Comments
Newest
Oldest
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x