Getting Order Data After Successful Checkout Hook

Getting order data after successful checkout hook

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?

WooCommerce successful order hook

On successful paid orders for all payment gateways others than Bank wire, cheque or Cash on delivery, you can use dedicated woocommerce_payment_complete hook located in WC_Order payment_complete() method instead of more generic hook woocommerce_thankyou, like:

add_action( 'woocommerce_payment_complete', 'action_payment_complete', 10, 2 );
function action_payment_complete( $order_id, $order ) {
// Here add your code
}

Note that you can use defined $order_id and $order function arguments. Also this hook is only triggered once, avoiding repetitions.


For Bank wire (bacs), Cheque (cheque) or Cash on delivery (cod) payment methods, As the shop manager confirm manually that order is paid by changing order status, you can use the dedicated hook woocommerce_order_status_changed as follows.

add_action( 'woocommerce_order_status_changed', 'bacs_cheque_cod_payment_complete', 10, 4 );
function bacs_cheque_cod_payment_complete( $order_id, $old_status, $new_status, $order ) {
// 1. For Bank wire and cheque payments
if( in_array( $order->get_payment_method(), array('bacs', 'cheque')
&& in_array( $new_status, array('processing', 'completed')
&& ! $order->get_date_paid('edit') ) {
// Do something
}

// 2. For Cash on delivery payments
if( 'cod' === $order->get_payment_method() && 'completed' === $new_status ) {
// Do something
}
}

Note that you can use defined $order_id and $order function arguments. Also this hook will be triggered once, on order status change, avoiding repetitions.


Related: After a successful payment, What hook is triggered in Woocommerce

Fetching order data in new order hook

This woocommerce_new_order action hook is used to alter the create_order() function. So you better use woocommerce_thankyou action hook that will trigger your custom email notification when order has been created:

// Tested on WooCommerce versions 2.6+ and 3.0+
add_action( 'woocommerce_thankyou', 'new_order_custom_email_notification', 1, 1 );
function new_order_custom_email_notification( $order_id ) {
if ( ! $order_id ) return;

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

$with_tax = $order->get_total();
$tax = $order->get_total_tax();
$without_tax = $with_tax - $tax;

$to = "test@example.com";
$subject = "New order";
$content = "
New order {$order_id}
With tax: {$with_tax}
Without tax: {$without_tax}
Tax: {$tax}
";

wp_mail($to, $subject, $content);
}

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

Code is tested and works.

Using woocommerce_checkout_order_processed action hook instead of woocommerce_thankyou action hook is also a good alternative, may be even better. You have just to replace:

add_action( 'woocommerce_thankyou', 'new_order_custom_email_notification', 1, 1 );

By:

add_action( 'woocommerce_checkout_order_processed', 'new_order_custom_email_notification', 1, 1 );

Similar working Answer: Woocommerce - How to send custom emails based on payment type



The woocommerce_checkout_order_processed hook (located in WC_Checkout process_checkout() method that could be convenient too for this purpose.

The source code of WC_Checkout process_checkout() method is interesting to get a view on the purchase flow.

Hook woocommerce_checkout_order_processed order items issue

do_action on woocommerce_checkout_order_processed passes exactly three args, third of which is the $order itself. So try using that instead:

function wc_function($order_id, $posted_data, $order) {
$items = $order->get_items();
foreach ($items as $item_line_id => $item) {
// Insert data in my custom table
}
}

WooCommerce get order id and order key at order-received endpoint

add_action( 'woocommerce_thankyou', 'woocommerce_thankyou_redirect', 4 );

function woocommerce_thankyou_redirect( $order_id ) {

//$order_id. // This contains the specific ID of the order
$order = wc_get_order( $order_id );
$order_key = $order->get_order_key();

wp_redirect( 'redirection here with parameters' );
exit;
}

Try this code snippet.

Display a success custom notice after Placing an Order in WooCommerce

You can't display a "success" notice on checkout page once you submit an order (place an order)… You can do that in Order Received (thankyou) page. Also in your code, $order_id is not defined…

So the right hook is woocommerce_before_thankyou using wc_print_notice() function instead:

add_action( 'woocommerce_before_thankyou', 'success_message_after_payment' );
function success_message_after_payment( $order_id ){
// Get the WC_Order Object
$order = wc_get_order( $order_id );

if ( $order->has_status('processing') ){
wc_print_notice( __("Your payment has been successful", "woocommerce"), "success" );
}
}

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

Sample Image


Addition: Display a custom html message instead of a Woocommerce notice

Just replace the code line:

wc_print_notice( __("Your payment has been successful", "woocommerce"), "success" );

with for example this:

echo '<p class='cudtom-message"> . __("Your payment has been successful", "woocommerce"), "success" ) . '</p>';

You can add your own html as you like around the text message.



Related Topics



Leave a reply



Submit