Woocommerce: Auto Complete Paid Orders

WooCommerce: Auto complete paid orders

The most accurate, effective and lightweight solution (For WooCommerce 3 and above) - 2019

This filter hook is located in:

  • WC_Order Class inside payment_complete() method which is used by all payment methods when a payment is required in checkout.
  • WC_Order_Data_Store_CPT Class inside update() method.

As you can see, by default the allowed paid order statuses are "processing" and "completed".

###Explanations:

  1. Lightweight and effective:

As it is a filter hook, woocommerce_payment_complete_order_status is only triggered when an online payment is required (not for "cheque", "bacs" or "cod" payment methods). Here we just change the allowed paid order statuses.

So no need to add conditions for the payment gateways or anything else.


  1. Accurate (avoid multiple notifications):

This is the only way to avoid sending 2 different customer notifications at the same time:

• One for "processing" orders status

• And one for "completed" orders status.

So customer is only notified once on "completed" order status.

Using the code below, will just change the paid order status (that is set by the payment gateway for paid orders) to "completed":

add_action( 'woocommerce_payment_complete_order_status', 'wc_auto_complete_paid_order', 10, 3 );
function wc_auto_complete_paid_order( $status, $order_id, $order ) {
return 'completed';
}

Code goes in function.php file of the active child theme (or active theme).

Related: WooCommerce: autocomplete paid orders based on shipping method


2018 - Improved version (For WooCommerce 3 and above)

Based on Woocommerce official hook, I found a solution to this problem *(Works with WC 3+).

In Woocommerce for all other payment gateways others than bacs (Bank Wire), cheque and cod (Cash on delivery), the paid order statuses are "processing" and "completed".

So I target "processing" order status for all payment gateways like Paypal or credit card payment, updating the order status to complete.

The code:

add_action( 'woocommerce_thankyou', 'wc_auto_complete_paid_order', 20, 1 );
function wc_auto_complete_paid_order( $order_id ) {
if ( ! $order_id )
return;

// Get an instance of the WC_Product object
$order = wc_get_order( $order_id );

// No updated status for orders delivered with Bank wire, Cash on delivery and Cheque payment methods.
if ( in_array( $order->get_payment_method(), array( 'bacs', 'cod', 'cheque', '' ) ) ) {
return;
}
// For paid Orders with all others payment methods (paid order status "processing")
elseif( $order->has_status('processing') ) {
$order->update_status( 'completed' );
}
}

Code goes in function.php file of the active child theme (or active theme).


Original answer (For all woocommerce versions):

The code:

/**
* AUTO COMPLETE PAID ORDERS IN WOOCOMMERCE
*/
add_action( 'woocommerce_thankyou', 'custom_woocommerce_auto_complete_paid_order', 10, 1 );
function custom_woocommerce_auto_complete_paid_order( $order_id ) {
if ( ! $order_id )
return;

$order = wc_get_order( $order_id );

// No updated status for orders delivered with Bank wire, Cash on delivery and Cheque payment methods.
if ( ( 'bacs' == get_post_meta($order_id, '_payment_method', true) ) || ( 'cod' == get_post_meta($order_id, '_payment_method', true) ) || ( 'cheque' == get_post_meta($order_id, '_payment_method', true) ) ) {
return;
}
// For paid Orders with all others payment methods (with paid status "processing")
elseif( $order->get_status() === 'processing' ) {
$order->update_status( 'completed' );
}
}

Code goes in function.php file of the active child theme (or active theme).

With the help of this post: How to check payment method on a WooCommerce order by id?

with this : get_post_meta( $order_id, '_payment_method', true ); from helgatheviking

"Bank wire" (bacs), "Cash on delivery" (cod) and "Cheque" (cheque) payment methods are ignored and keep their original order status.

Updated the code for compatibility with WC 3.0+ (2017-06-10)

Auto complete order woocommerce

The reference you picked is ok

https://woocommerce.com/document/automatically-complete-orders/

Just needed a small adjustment:

/**
* Auto Complete Processing WooCommerce orders on Thankyou Page
*/
add_action( 'woocommerce_thankyou', 'custom_woocommerce_auto_complete_order' );
function custom_woocommerce_auto_complete_order( $order_id ) {
if ( ! $order_id ) {
return;
}

$order = wc_get_order( $order_id );
if ( $order->has_status('processing') ) {
$order->update_status( 'completed' );
}

}

What we are doing with this adjustment is checking if the order has status processing before updating it to completed. This will avoid failed orders to be turned into completed.

Hope it works

Auto-complete Paid Orders only for specific product IDs on Woocommerce

Here is a way to autocomplete paid orders for specific product IDS:

add_action( 'woocommerce_payment_complete_order_status', 'wc_auto_complete_paid_order', 10, 3 );
function wc_auto_complete_paid_order( $status, $order_id, $order ) {
// Below the targeted product Ids
$targeted_ids = array(37, 53);

// Loop through order line items
foreach( $order->get_items() as $item ) {
if ( in_array( $item->get_product_id(), $targeted_ids ) || in_array( $item->get_variation_id(), $targeted_ids ) ) {
return 'completed';
}
}

return $status;
}

Code goes in functions.php file of the active child theme (or active theme).


  • WooCommerce: Auto complete paid orders
  • Exclude specific products on auto-complete orders process in Woocommerce

Auto change order status to completed for specific products in WooCommerce

You can target specific product(s) Id(s) from order items, to make your code work only for them as follows:

add_action( 'woocommerce_thankyou', 'custom_woocommerce_auto_complete_order' );
function custom_woocommerce_auto_complete_order( $order_id ) {
if ( ! $order_id ) {
return;
}

$order = wc_get_order( $order_id );

$product_ids = array('23'); // Here set your targeted product(s) Id(s)
$product_found = false;

// Loop through order items
foreach ( $order->get_items() as $item ) {
if( array_intersect( $product_ids, array($item->get_product_id(), $item->get_variation_id()) ) ) {
$product_found = true;
break;
}
}

if( $order->has_status( 'processing' ) && $product_found ) {
$order->update_status( 'completed' );
}
}

If you want to target those products exclusively, then you will use the following instead:

add_action( 'woocommerce_thankyou', 'custom_woocommerce_auto_complete_order' );
function custom_woocommerce_auto_complete_order( $order_id ) {
if ( ! $order_id ) {
return;
}

$order = wc_get_order( $order_id );

$product_ids = array('23'); // Here set your targeted product(s) Id(s)
$product_found = true;

// Loop through order items
foreach ( $order->get_items() as $item ) {
if( ! array_intersect( $product_ids, array($item->get_product_id(), $item->get_variation_id()) ) ) {
$product_found = false;
break;
}
}

if( $order->has_status( 'processing' ) && $product_found ) {
$order->update_status( 'completed' );
}
}

Code goes in functions.php file of the active child theme (or active theme). It should works.



Addition: Avoid multiple notifications

You should better use woocommerce_payment_complete_order_status hook instead like in WooCommerce: Auto complete paid orders answer, to avoid multiple notifications.

So the code is going to be:

add_action( 'woocommerce_payment_complete_order_status', 'wc_auto_complete_paid_order', 10, 3 );
function wc_auto_complete_paid_order( $status, $order_id, $order ) {
$product_ids = array('23'); // Here set your targeted product(s) Id(s)
$product_found = false;

// Loop through order items
foreach ( $order->get_items() as $item ) {
if( array_intersect( $product_ids, array($item->get_product_id(), $item->get_variation_id()) ) ) {
$product_found = true;
break;
}
}

return $product_found ? 'completed' : $status;
}

Or targeting products exclusively:

add_action( 'woocommerce_payment_complete_order_status', 'wc_auto_complete_paid_order', 10, 3 );
function wc_auto_complete_paid_order( $status, $order_id, $order ) {
$product_ids = array('23'); // Here set your targeted product(s) Id(s)
$product_found = true;

// Loop through order items
foreach ( $order->get_items() as $item ) {
if( ! array_intersect( $product_ids, array($item->get_product_id(), $item->get_variation_id()) ) ) {
$product_found = false;
break;
}
}

return $product_found ? 'completed' : $status;
}

It should work...

Auto process paid orders instead of auto complete in WooCommerce

Try to use the following, which will set paid orders status to processing by default:

add_action( 'woocommerce_payment_complete_order_status', 'wc_auto_complete_paid_order', 10, 3 );
function wc_auto_complete_paid_order( $status, $order_id, $order ) {
return 'processing';
}

Code goes in functions.php file of the active child theme (or active theme).

Related: WooCommerce: Auto complete paid orders



Related Topics



Leave a reply



Submit