Instead of using the init
hook, you should try to use one of the following functions, that will auto-complete processing orders that have a total amount less than $50 (for example):
1) Using woocommerce_order_status_processing
action hook (the best choice):
add_action( 'woocommerce_order_status_processing', 'auto_complete_processing_orders_based_on_total', 20, 4 );
function auto_complete_processing_orders_based_on_total( $order_id, $order ){
// HERE define the max total order amount
$max_total_limit = 50;
if ( $order->get_total() < $max_total_limit ) {
$order->update_status( 'completed' );
}
}
Code goes in function.php file of your active child theme (active theme). Tested and works.
2) Using woocommerce_thankyou
action hook (good alternative if your orders are always in processing status):
add_action( 'woocommerce_thankyou', 'thankyou_auto_complete_processing_orders_based_on_total', 90, 1 );
function thankyou_auto_complete_processing_orders_based_on_total( $order_id ){
if( ! $order = wc_get_order( $order_id ) ){
return;
}
// HERE define the max total order amount
$max_total_limit = 50;
if( $order->has_status('processing') && $order->get_total() < $max_total_limit ){
$order->update_status( 'completed' );
}
}
Code goes in function.php file of your active child theme (active theme). Tested and works.
3) Bulk update processing orders based on total amount (2 possibilities):
A) The lightest and efficient way with a direct SQL query using init
hook (the best way):
add_action( 'init', 'sql_auto_complete_processing_orders_based_on_total' );
function sql_auto_complete_processing_orders_based_on_total(){
// HERE define the max total order amount
$max_total_limit = 50;
global $wpdb;
// Very light bulk update direct SQL query
$orders_ids = $wpdb->query("
UPDATE {$wpdb->prefix}posts as a
JOIN {$wpdb->prefix}postmeta AS b ON a.ID = b.post_id
SET a.post_status = 'wc-completed'
WHERE a.post_status = 'wc-processing'
AND b.meta_key = '_order_total' AND b.meta_value < '$max_total_limit'
");
}
Code goes in function.php file of your active child theme (active theme). Tested and works.
B) Based on your code using init
hook (Very heavy, but more compatible with future database structure changes in woocommerce, if it happen one day):
add_action( 'init', 'init_thankyou_auto_complete_processing_orders_based_on_total' );
function init_thankyou_auto_complete_processing_orders_based_on_total(){
// HERE define the max total order amount
$max_total_limit = 50;
// Get all processing orders
$orders = wc_get_orders( array( 'limit' => -1, 'status' => 'processing') );
if( sizeof($orders) > 0 ) {
// loop through processing orders
foreach( $orders as $order ) {
if( $order->get_total() < $max_total_limit ) {
$order->update_status( 'completed' );
}
}
}
}
Code goes in function.php file of your active child theme (active theme). Tested and works.
Related: WooCommerce: Auto complete paid Orders (depending on Payment methods)