WooCommerce new order action - get order information
You can use $order_id
as a parameter for your woocommerce_new_order
callback and get the order details from the $order_id
.
Example:
// define the woocommerce_new_order callback
function create_invoice_for_wc_order( $order_id ) {
// get order details data...
$order = new WC_Order( $order_id );
var_dump($order);
};
References:
http://hookr.io/actions/woocommerce_new_order/
https://docs.woothemes.com/wc-apidocs/class-WC_Order.html
How to get WooCommerce order details
WOOCOMMERCE ORDERS IN VERSION 3.0+
Since Woocommerce mega major Update 3.0+ things have changed quite a lot:
- For
WC_Order
Object, properties can't be accessed directly anymore as before and will throw some errors. - New
WC_Order
andWC_Abstract_Order
getter and setter methods are now required on theWC_Order
object instance. - Also, there are some New classes for Order items:
WC_Order_Item
class,WC_Order_Item_Product
class,WC_Order_Item_Tax
class,WC_Order_Item_Shipping
class,WC_Order_Item_Coupon
class,WC_Order_Item_Fee
class.
- Additionally,
WC_Data
Abstract class allow to access Order and order items data usingget_data()
,get_meta_data()
andget_meta()
methods.
Related:
• How to get Customer details from Order in WooCommerce?
• Get Order items and WC_Order_Item_Product in WooCommerce 3
So the Order items properties will not be accessible as before in a foreach
loop and you will have to use these specific getter and setter methods instead.
Using some WC_Order
and WC_Abstract_Order
methods (example):
// Get an instance of the WC_Order object (same as before)
$order = wc_get_order( $order_id );
$order_id = $order->get_id(); // Get the order ID
$parent_id = $order->get_parent_id(); // Get the parent order ID (for subscriptions…)
$user_id = $order->get_user_id(); // Get the costumer ID
$user = $order->get_user(); // Get the WP_User object
$order_status = $order->get_status(); // Get the order status (see the conditional method has_status() below)
$currency = $order->get_currency(); // Get the currency used
$payment_method = $order->get_payment_method(); // Get the payment method ID
$payment_title = $order->get_payment_method_title(); // Get the payment method title
$date_created = $order->get_date_created(); // Get date created (WC_DateTime object)
$date_modified = $order->get_date_modified(); // Get date modified (WC_DateTime object)
$billing_country = $order->get_billing_country(); // Customer billing country
// ... and so on ...
For order status as a conditional method (where "the_targeted_status" need to be defined and replaced by an order status to target a specific order status):
if ( $order->has_status('completed') ) {
// Do something
}
Get and access to the order data properties (in an array of values):
// Get an instance of the WC_Order object
$order = wc_get_order( $order_id );
$order_data = $order->get_data(); // The Order data
$order_id = $order_data['id'];
$order_parent_id = $order_data['parent_id'];
$order_status = $order_data['status'];
$order_currency = $order_data['currency'];
$order_version = $order_data['version'];
$order_payment_method = $order_data['payment_method'];
$order_payment_method_title = $order_data['payment_method_title'];
$order_payment_method = $order_data['payment_method'];
$order_payment_method = $order_data['payment_method'];
## Creation and modified WC_DateTime Object date string ##
// Using a formated date ( with php date() function as method)
$order_date_created = $order_data['date_created']->date('Y-m-d H:i:s');
$order_date_modified = $order_data['date_modified']->date('Y-m-d H:i:s');
// Using a timestamp ( with php getTimestamp() function as method)
$order_timestamp_created = $order_data['date_created']->getTimestamp();
$order_timestamp_modified = $order_data['date_modified']->getTimestamp();
$order_discount_total = $order_data['discount_total'];
$order_discount_tax = $order_data['discount_tax'];
$order_shipping_total = $order_data['shipping_total'];
$order_shipping_tax = $order_data['shipping_tax'];
$order_total = $order_data['total'];
$order_total_tax = $order_data['total_tax'];
$order_customer_id = $order_data['customer_id']; // ... and so on
## BILLING INFORMATION:
$order_billing_first_name = $order_data['billing']['first_name'];
$order_billing_last_name = $order_data['billing']['last_name'];
$order_billing_company = $order_data['billing']['company'];
$order_billing_address_1 = $order_data['billing']['address_1'];
$order_billing_address_2 = $order_data['billing']['address_2'];
$order_billing_city = $order_data['billing']['city'];
$order_billing_state = $order_data['billing']['state'];
$order_billing_postcode = $order_data['billing']['postcode'];
$order_billing_country = $order_data['billing']['country'];
$order_billing_email = $order_data['billing']['email'];
$order_billing_phone = $order_data['billing']['phone'];
## SHIPPING INFORMATION:
$order_shipping_first_name = $order_data['shipping']['first_name'];
$order_shipping_last_name = $order_data['shipping']['last_name'];
$order_shipping_company = $order_data['shipping']['company'];
$order_shipping_address_1 = $order_data['shipping']['address_1'];
$order_shipping_address_2 = $order_data['shipping']['address_2'];
$order_shipping_city = $order_data['shipping']['city'];
$order_shipping_state = $order_data['shipping']['state'];
$order_shipping_postcode = $order_data['shipping']['postcode'];
$order_shipping_country = $order_data['shipping']['country'];
Get the order items and access the data with WC_Order_Item_Product
and WC_Order_Item
methods:
// Get an instance of the WC_Order object
$order = wc_get_order($order_id);
// Iterating through each WC_Order_Item_Product objects
foreach ($order->get_items() as $item_key => $item ):
## Using WC_Order_Item methods ##
// Item ID is directly accessible from the $item_key in the foreach loop or
$item_id = $item->get_id();
## Using WC_Order_Item_Product methods ##
$product = $item->get_product(); // Get the WC_Product object
$product_id = $item->get_product_id(); // the Product id
$variation_id = $item->get_variation_id(); // the Variation id
$item_type = $item->get_type(); // Type of the order item ("line_item")
$item_name = $item->get_name(); // Name of the product
$quantity = $item->get_quantity();
$tax_class = $item->get_tax_class();
$line_subtotal = $item->get_subtotal(); // Line subtotal (non discounted)
$line_subtotal_tax = $item->get_subtotal_tax(); // Line subtotal tax (non discounted)
$line_total = $item->get_total(); // Line total (discounted)
$line_total_tax = $item->get_total_tax(); // Line total tax (discounted)
## Access Order Items data properties (in an array of values) ##
$item_data = $item->get_data();
$product_name = $item_data['name'];
$product_id = $item_data['product_id'];
$variation_id = $item_data['variation_id'];
$quantity = $item_data['quantity'];
$tax_class = $item_data['tax_class'];
$line_subtotal = $item_data['subtotal'];
$line_subtotal_tax = $item_data['subtotal_tax'];
$line_total = $item_data['total'];
$line_total_tax = $item_data['total_tax'];
// Get data from The WC_product object using methods (examples)
$product = $item->get_product(); // Get the WC_Product object
$product_type = $product->get_type();
$product_sku = $product->get_sku();
$product_price = $product->get_price();
$stock_quantity = $product->get_stock_quantity();
endforeach;
So using
get_data()
method allow us to access to the protected data (associative array mode) …
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.
How to grab the order status of the last order in WooCommerce via a shortcode
$order_items = $last_order->get_status()
will return a string and is therefore not an array. So using end( $order_items )
is a superfluous step.
Use instead:
function woostatus() {
// Not available
$na = __( 'N/A', 'woocommerce' );
// For logged in users only
if ( ! is_user_logged_in() ) return $na;
// The current user ID
$user_id = get_current_user_id();
// Get the WC_Customer instance Object for the current user
$customer = new WC_Customer( $user_id );
// Get the last WC_Order Object instance from current customer
$last_order = $customer->get_last_order();
// When empty
if ( empty ( $last_order ) ) return $na;
// Get order status
$order_status = $last_order->get_status();
// Return
return $order_status;
}
// Register shortcode
add_shortcode( 'display_woostatus', 'woostatus' );
SHORTCODE USAGE
In an existing page:
[display_woostatus]
Or in PHP:
echo do_shortcode('[display_woostatus]');
WooCommerce - When order is created?
If you want to update the order late or at any time just pass order_id(eg.115) and perform the operation accordingly
add_action('init',function(){
$order_id = 115;
if($order_id){
$order = new WC_Order($order_id);
$order->update_status('wc-processing');
}
});
Woocommerce which hook to use for order status changes
"I need to catch every time an order status changes from
wc_on_hold
towc_completed
"
You would need to change your hook to woocommerce_order_status_changed
.
"I couldn't get on Chrome's Console that echo giving me the order price"
You can't use javascript
and console.log
in this hook. You would need to either use the die
function or the error_log
function to log it to your debug.log
file.
Using die
function
add_action('woocommerce_order_status_changed', 'so_status_completed', 10, 3);
function so_status_completed($order_id, $old_status, $new_status)
{
$order = wc_get_order($order_id);
//$order_total = $order->get_formatted_order_total();
$order_total = $order->get_total();
die($order_total);
}
Using error_log
function
dd_action('woocommerce_order_status_changed', 'so_status_completed', 10, 3);
function so_status_completed($order_id, $old_status, $new_status)
{
$order = wc_get_order($order_id);
//$order_total = $order->get_formatted_order_total();
$order_total = $order->get_total();
error_log(print_r('order total: ' . $order_total, true));
}
Second question
"since I am just here, I want to ask you if
$order-get_total()
is the right one to retrieve order amount without fee applied?"
You might want to take a look at the $order->get_subtotal()
for the totals before shipping, coupons and taxes:
Please see these related answers:
- https://stackoverflow.com/a/47782647/15040627
- https://stackoverflow.com/a/61102779/15040627
- https://stackoverflow.com/a/32634480/15040627
- https://stackoverflow.com/a/44708344/15040627
Related Topics
Setlocale(Lc_All, 'En_Gb.Utf8') Not Working on Windows
How to Convert Special Characters to Normal Characters
Laravel 5.3 - HTMLspecialchars() Expects Parameter 1 to Be String
Regular Expression to Remove CSS Comments
How to Force Utf-8 Encoding in Browser
No Mail Received in Inbox with Xampp 1.8.0, Mercurymail and Mail()
Laravel 5 Isdirty() Always Returns False
How to Check If the Request Came from Mobile or Computer in PHP
JavaScript or Jquery Doesn't Work in Dynamically Generated Content
How to Store a Class Instance in a $_Session Space
How to Backup/Export the Connected Database Database.SQL File in Laravel
Restrict Content Access to Logged in Users with PHP
.Htaccess for Friendly Url with Multiple Variables
Using Ajax/Jquery to Refresh an Image