Woocommerce New Order Action - Get Order Information

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 and WC_Abstract_Order getter and setter methods are now required on the WC_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 using get_data(), get_meta_data() and get_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 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.

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 to wc_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



Leave a reply



Submit