peanut
peanut

Reputation: 41

What hook to use once order is created in Woocommerce 3

I have created the following plugin, which is supposed to send a POST HTTP request to an external server when a Woocommerce order is created. However, this is not happening: no request received on the external server, nothing is showing up in wp-content/debug.log (I do have define( 'WP_DEBUG_LOG', true ); in wp-config.php). What am I doing wrong?

<?php
/**
 * Plugin Name: MyPlugin
 */


function my_hook($order_id) {
    $url = "https://example.com/do_something";
    $data = wp_remote_post($url, array(
        'headers'     => array(
            'Authorization' => "Token my_token",
            'Content-Type'  => 'application/json; charset=utf-8',
        ),
        'body'        => json_encode(array('order_id' => $order_id)),
        'method'      => 'POST',
        'data_format' => 'body',
    ));
}
add_action(
    'woocommerce_new_order',
    'my_hook'
);

?>

Upvotes: 4

Views: 5505

Answers (3)

LoicTheAztec
LoicTheAztec

Reputation: 254483

Since WooCommerce 4.3.0 the correct hook to be used is woocommerce_checkout_order_created, to send a POST HTTP request to an external server when an order is created. So your code is going to be:

add_action( 'woocommerce_checkout_order_created', 'my_hooked_function_callback', 10 );

function my_hooked_function_callback( $order ) {

    $url = "https://example.com/do_something";

    $data = wp_remote_post( $url, array(
        'headers'     => array(
            'Authorization' => "Token my_token",
            'Content-Type'  => 'application/json; charset=utf-8',
        ),
        'body'        => json_encode( array( 
           'order_id' => $order->get_id() 
        ) ),
        'method'      => 'POST',
        'data_format' => 'body',
    ) );
}

Code goes in functions.php file of the active child theme (or active theme). It should works.

This hook is located inside create_order() method for WC_Checkout Class.

Note: The code will not work for manual created orders via admin.


Additional notes:

  • To update order meta data once order is created you will use instead the action hook woocommerce_checkout_update_order_meta, with 2 available arguments: $order_id and $data (the posted data).
  • To update order data or meta data before order is created you will use instead the action hook woocommerce_checkout_create_order with 2 available arguments: $order and $data (the posted data).
  • To update order items data or meta data before order is created you will use instead the action hook woocommerce_checkout_create_order_line_item with 2 available arguments: $item, $cart_item_key, $values, $order.

Related: How to debug in WooCommerce 3+

Upvotes: 4

H A&#223;d&#248;&#181;
H A&#223;d&#248;&#181;

Reputation: 3065

Short answer use woocommerce_checkout_order_processed.

Rather than woocommerce_thankyou hook, woocommerce_checkout_order_processed hook is the relevant hook. woocommerce_checkout_order_processed hook will be called only once and you will not need to add meta for each product and make additional calls to keep check for code to run only once. As, woocommerce_thankyou can be called multiple times that is each time thankyou page loads.

Source: https://stackoverflow.com/a/72195252/3261332

Upvotes: 0

Diego
Diego

Reputation: 1716

If you go inside class-wc-checkout you will find the create_order function which trigger these hooks just before ending:

        /**
         * Action hook to adjust order before save.
         *
         * @since 3.0.0
         */
        do_action( 'woocommerce_checkout_create_order', $order, $data );

        // Save the order.
        $order_id = $order->save();

        /**
         * Action hook fired after an order is created used to add custom meta to the order.
         *
         * @since 3.0.0
         */
        do_action( 'woocommerce_checkout_update_order_meta', $order_id, $data );

        /**
         * Action hook fired after an order is created.
         *
         * @since 4.3.0
         */
        do_action( 'woocommerce_checkout_order_created', $order );

Maybe you just have to use one of those?

Upvotes: 2

Related Questions