Reputation: 1168
I need to detect when a new WooCommerce order is successfully created and set to ‘processing’—this is to add some extra functionality etc. This is fine to do on the frontend as it’s pretty easy to hook in when an order is created via either of the WooCommerce woocommerce_thankyou
or woocommerce_order_status_processing
hooks.
The problem I have is that I also want this to work when creating a new order manually via the backend of the website. I am using some custom fields when adding an order via manually which is used to manipulate the order when created. Unfortunately, although the woocommerce_order_status_processing
does work for admin orders it seems to trigger before the order meta is saved—therefore when I try to retrieve any meta data it is empty.
To get round this, I have tried the suggestions on WooCommerce hook for order creation from admin or on this GitHub thread which is to use the WordPress hooks wp_insert_post
or save_post_shop_order
(save_post_{$post->post_type}
). This works to solve my order meta problem as it seems to trigger after the order meta is saved.
However — it triggers everytime there is an update or a new post so I need to find a way of detecting whether it’s a new post or not. There is an $update
parameter on these hooks which is meant to show ‘Whether this is an existing post being updated or not’ but for some reason it always seems to be set to true even when it is a new post/order.
The only other way potentially of doing this that I can think of is as per this suggestion of checking post date vs. modified date but I just thought there must be a better way of doing this!
function my_order_created ( $post_id, $post, $update ) {
// Don’t run if $post_id doesn’t exist OR post type is not order OR update is true
if ( ! $post_id || get_post_type( $post_id ) != 'shop_order' || $update == 1 ) {
return;
}
$order = wc_get_order( $post_id );
if ( $order && $order->has_status( 'processing' ) ){
// Do something
}
}
add_action( 'wp_insert_post', 'my_order_created', 10, 3 );
Upvotes: 6
Views: 21580
Reputation: 253804
Update 2023
Since WooCommerce 3 that has implemented CRUD methods and data stores, there are some dedicated hooks, that you can specifically use for order creation. :
You can use woocommerce_new_order
action hook allowing you to trigger some custom code on order creation (located in the WC_Order_Data_Store_CPT
create()
method).
add_action('woocommerce_new_order', 'action_woocommerce_new_order', 10, 2);
function action_woocommerce_new_order( $order_id, $order ) {
// Here your custom action code
}
There is also woocommerce_new_order_data
filter hook allowing you to filter some data inside the function wp_insert_post()
before it's saved on order creation (located in the Abstract_WC_Order_Data_Store_CPT
create()
method)
add_filter('woocommerce_new_order_data', 'action_woocommerce_new_order_data', 10, 2);
function action_woocommerce_new_order( $data_arr, $wp_error ) {
// Here your custom code to filter data
// Always return the main argument
return $data_arr;
}
This is a much better option as it's just for WooCommerce order creation.
Upvotes: 5
Reputation: 4275
You can use woocommerce_new_order
hook:
add_action('woocommerce_new_order', function ($order_id) {
// your code
}, 10, 1);
Upvotes: 13