Search the site:

Home Blog How to automatically Complete WooCommerce orders when they go to the Processing status

How to automatically Complete WooCommerce orders when they go to the Processing status

Every e-commerce site requires tracking and managing orders which can be quite a daunting task for the administrator, considering the amount of orders that an average high-traffic e-commerce website receives per day. When it comes to WooCommerce, an order gets created as soon as the Checkout process is completed. According to where the order is in the payment-to-delivery chain, it gets assigned a status. These statuses are set and/or changed by WooCommerce, the Payment Gateway and the store-owner/administrator depending on where the order lies. Let’s look at this diagram of the flow of an order in WooCommerce:

automatically Complete WooCommerce orders when they go to the Processing status - Order Status diagram
Source: https://docs.woocommerce.com/document/managing-orders/

As illustrated, after payment for an order is successfully completed, its status is set to “Processing” until the store owner manually changes it to “Completed”. This is an overhead task for the store owner or the administrator, especially in cases where the sales volume is high. One way to make this process efficient is to automatically complete WooCommerce orders when they go to the Processing status. Let’s see how we can do that using code snippets.

Automatically set the WooCommerce order status as Completed based on payment method

In most cases, you would need to do this only after the payment has been successfully made, and this is only possible when the user has not selected the Cash-on-Delivery option. The code below, when inserted in the functions.php file of your child theme, will automatically set the status of the order as Completed whenever a payment has been successfully made. Hence, in all cases except when the user selects the Cash-on-Delivery option, the order status will automatically change to Completed.

add_action('woocommerce_order_status_changed', 'ts_auto_complete_by_payment_method');

function ts_auto_complete_by_payment_method($order_id)
{
  
  if ( ! $order_id ) {
        return;
  }

  global $product;
  $order = wc_get_order( $order_id );
  
  if ($order->data['status'] == 'processing') {
        $payment_method=$order->get_payment_method();
        if ($payment_method!="cod")
        {
            $order->update_status( 'completed' );
        }
      
  }
  
}

 

Here, you will use the woocommerce_order_status_changed hook to call a function when the status of an order is changed. After checking whether the order has the Processing status, only if the payment method is not Cash-on-Delivery, the order status will be changed to Completed. WooCommerce has four default payment methods viz. Direct Bank Transfer (bacs), Check payments (cheque), Cash on Delivery (cod) and PayPal (paypal). Depending on which payment method you are specifying the condition for, you would need to use the appropriate ID e.g. “bacs”, “cheque”, “cod”, “paypal”.

Automatically set the WooCommerce order status as Completed for virtual products

Another case where you would want the order status to complete automatically is when the product or products in the order are virtual products. Virtual products are products which are either not tangible, or are downloadable. An example of this would be a store membership subscription or coupon that offers discounts to those who have bought the subscription.

automatically Complete WooCommerce orders when they go to the Processing status - Virtual Product Example - Store Membership
Example of a Virtual Product

A store membership subscription may not have a tangible form but instead an expiry date. Downloadable products such as software or even electronic movie tickets are virtual products too, as they do not have an offline presence or form. With most virtual products, there is never an option of “Cash-on-Delivery”. Payments are made on the spot, and hence it would be safe to not include the condition of checking for payment methods used, but instead only add a condition to check if all the products in the order are virtual products.

add_action('woocommerce_order_status_changed', 'ts_auto_complete_virtual');

function ts_auto_complete_virtual($order_id)
{
  
  if ( ! $order_id ) {
        return;
  }
  
  global $product;
  $order = wc_get_order( $order_id );
  
  if ($order->data['status'] == 'processing') {
    
    $virtual_order = null;

    if ( count( $order->get_items() ) > 0 ) {

      foreach( $order->get_items() as $item ) {

        if ( 'line_item' == $item['type'] ) {

          $_product = $order->get_product_from_item( $item );

          if ( ! $_product->is_virtual() ) {
            // once we find one non-virtual product, break out of the loop
            $virtual_order = false;
            break;
          } 
          else {
            $virtual_order = true;
          }
       }
     }
   }

    // if all are virtual products, mark as completed
    if ( $virtual_order ) {
      $order->update_status( 'completed' );
    }
  }	
}

Here, we use the same hook to call our function ts_auto_complete_virtual. After checking if the order is in a Processing status, you need to go through each item in the order to see if it’s a virtual product. An order has a lot of items associated with it such as products, shipping, fee etc. Here, line_item refers to the product. Only the products need to be fetched one by one to check if they are virtual. If even one item is not a virtual product, the status of the order will not be marked as Completed. Depending on your requirements however, and using the first code snippet in this post, you may add more conditions to mark the order status as Completed. For example, if you wish to mark Order Status as Completed even for non-virtual products (if the payment for these products are done), then you can do so by adding a check on the payment method after it checks for whether it’s a virtual product. Through this code snippet however, the status of the order will be set as Completed only if all products in the order are virtual products.

Browse more in: Code Snippets, WooCommerce How Tos, WooCommerce Tutorials

1
Leave a Reply

avatar
1 Comment threads
0 Thread replies
1 Followers
 
Most reacted comment
Hottest comment thread
1 Comment authors
Maged Mohamed Recent comment authors

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  Subscribe  
newest oldest
Notify of
Maged Mohamed
Guest

Hi there,

Can this work with the free orders ? Which in this case the order total is 0 and all the payment gateways are hidden so in this case can it work to update the order from processing to completed ?

from purchased

Subscribe for more offers