Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting order data after successful checkout hook

In WooCommerce, I would like to send a request to an API once the customer has successfully checked out. Its basically a website where the client is selling online courses (Like udemy).

When the customer checks out, I would like to send an API request and enroll the user for that particular course. I have tried several WooCommerce hooks but none worked for me.

This is the code that I'm using:

add_action('woocommerce_checkout_order_processed', 'enroll_student', 10, 1);

function enroll_student($order_id)
{
    echo $order_id;
    echo "Hooked";
}

I am writing this code for a plugin and to make it easier, I am currently using Cash on Delivery method.

Can anyone point me out where I am going wrong because when I checkout I cant see the message "hooked" that I am printing nor the $order_id?

It takes me to the success page and doesn't show these two things that I am printing.

like image 950
Syed Haris Ali Ghaznavi Avatar asked Mar 01 '17 11:03

Syed Haris Ali Ghaznavi


3 Answers

Update 2 Only For Woocommerce 3+ (added restriction to execute the code only once)

add_action('woocommerce_thankyou', 'enroll_student', 10, 1);
function enroll_student( $order_id ) {
    if ( ! $order_id )
        return;

    // Allow code execution only once 
    if( ! get_post_meta( $order_id, '_thankyou_action_done', true ) ) {

        // Get an instance of the WC_Order object
        $order = wc_get_order( $order_id );

        // Get the order key
        $order_key = $order->get_order_key();

        // Get the order number
        $order_key = $order->get_order_number();

        if($order->is_paid())
            $paid = __('yes');
        else
            $paid = __('no');

        // Loop through order items
        foreach ( $order->get_items() as $item_id => $item ) {

            // Get the product object
            $product = $item->get_product();

            // Get the product Id
            $product_id = $product->get_id();

            // Get the product name
            $product_id = $item->get_name();
        }

        // Output some data
        echo '<p>Order ID: '. $order_id . ' — Order Status: ' . $order->get_status() . ' — Order is paid: ' . $paid . '</p>';

        // Flag the action as done (to avoid repetitions on reload for example)
        $order->update_meta_data( '_thankyou_action_done', true );
        $order->save();
    }
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

Related thread:

  • Get Order items and WC_Order_Item_Product in WooCommerce 3
  • How to get WooCommerce order details

The code is tested and works.


Updated (to get the product Id from Orders items as asked in your comment)

May be you could use woocommerce_thankyou hook instead, that will display on order-received page your echoed code, this way:

add_action('woocommerce_thankyou', 'enroll_student', 10, 1);
function enroll_student( $order_id ) {

    if ( ! $order_id )
        return;

    // Getting an instance of the order object
    $order = wc_get_order( $order_id );

    if($order->is_paid())
        $paid = 'yes';
    else
        $paid = 'no';

    // iterating through each order items (getting product ID and the product object) 
    // (work for simple and variable products)
    foreach ( $order->get_items() as $item_id => $item ) {

        if( $item['variation_id'] > 0 ){
            $product_id = $item['variation_id']; // variable product
        } else {
            $product_id = $item['product_id']; // simple product
        }

        // Get the product object
        $product = wc_get_product( $product_id );

    }

    // Ouptput some data
    echo '<p>Order ID: '. $order_id . ' — Order Status: ' . $order->get_status() . ' — Order is paid: ' . $paid . '</p>';
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

The code is tested and works.

Then you can use all class WC_Abstract_Order methods on the $order object.

Related:

  • How to get WooCommerce order details
  • Get Order items and WC_Order_Item_Product in WooCommerce 3
    • How to get Customer details from Order in WooCommerce?
like image 80
LoicTheAztec Avatar answered Oct 22 '22 16:10

LoicTheAztec


you can get the order items of an order by

   // Getting an instance of the order object

    $order = new WC_Order( $order_id );
    $items = $order->get_items();

   //Loop through them, you can get all the relevant data:

    foreach ( $items as $item ) {
        $product_name = $item['name'];
        $product_id = $item['product_id'];
        $product_variation_id = $item['variation_id'];
    }
like image 31
mujuonly Avatar answered Oct 22 '22 14:10

mujuonly


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. Replace add_action('woocommerce_thankyou', 'enroll_student', 10, 1); with

add_action('woocommerce_checkout_order_processed', 'enroll_student', 10, 1);

and remove meta code and checks. Updated code is

add_action('woocommerce_checkout_order_processed', 'enroll_student', 10, 1);
function enroll_student( $order_id ) {
// Getting an instance of the order object
$order = wc_get_order( $order_id );

if($order->is_paid())
   $paid = 'yes';
else
  $paid = 'no';

    // iterating through each order items (getting product ID and the product object) 
// (work for simple and variable products)
foreach ( $order->get_items() as $item_id => $item ) {

    if( $item['variation_id'] > 0 ){
        $product_id = $item['variation_id']; // variable product
    } else {
        $product_id = $item['product_id']; // simple product
    }

    // Get the product object
    $product = wc_get_product( $product_id );

}

// Ouptput some data
echo '<p>Order ID: '. $order_id . ' — Order Status: ' . $order->get_status() . ' — Order is paid: ' . $paid . '</p>';

}

like image 6
Nabeel Perwaiz Avatar answered Oct 22 '22 15:10

Nabeel Perwaiz