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 ofwoocommerce_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 inWC_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.
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
Pdo Were Rows Affected During Execute Statement
Simple PHP Echo Code Not Working
PHP Include File in Webroot from File Outside Webroot
Printing Content of a Xml File Using Xml Dom
How to Search Array for Multiple Values in PHP
Sending/Displaying a Base64 Encoded Image
How to Pass an Array of Pdo Parameters Yet Still Specify Their Types
What Means Call to a Member Function on Boolean and How to Fix
Convert PHP Array String into an Array
Using Return in Ternary Operator
Multiple Http Get Parameters with the Same Identifier
How to Do a Curl Request to the Same Server