Automatically Complete Virtual and Downloadable Orders In WooCommerce

5/5

The World's No.1 WooCommerce Plugin

Mark Orders As Complete As Soon As They're Submitted In WooCommerce

If you are selling software or other downloadable / virtual products, there’s not really any need to have the order “processing”.

As soon as the customer checks out, the product is usually delivered.

Therefore, it makes sense for us to just automatically mark it as complete.

The below snippet will show you exactly how to do this.

If all the products within the order are virtual, it will mark the order as complete.

Copy and paste the following code into your functions.php file.

				
					/**
 *
 * @author Christopher Davies, WP Davies
 * @link https://wpdavies.dev/
 * @link https://wpdavies.dev/automatically-complete-virtual-orders-woocommerce/
 * @snippet Automatically complete orders in WooCommerce
 *
 **/
add_action('woocommerce_thankyou', 'wpd_autocomplete_virtual_orders', 10, 1 );
function wpd_autocomplete_virtual_orders( $order_id ) {

    // Check if order ID is correct
    if ( ! is_numeric( $order_id ) ) return false; 

	// Get order
	$order = wc_get_order( $order_id );

	// Don't continue if this isn't an order
	if ( ! is_a( $order, 'WC_Order' ) ) return false;

	// get order items = each product in the order
	$items = $order->get_items();

	// Default to virtual
	$only_virtual = true;

	// Loop through order items
	foreach ( $items as $item ) {

		// Only check product line items
		if ( ! is_a( $item, 'WC_Order_Item_Product') ) continue;

		// Check if this is a variation product
		$variation_id = $item->get_variation_id();

		// Get appropriate product object
        $product = ( is_numeric($variation_id) && $variation_id > 0 ) ? wc_get_product( $variation_id ) : wc_get_roduct( $item->get_product_id() );

		// SMake sure we've got a product object
		if ( ! is_a( $product, 'WC_Product' ) ) continue;

		// Is virtual
		$is_virtual = $product->is_virtual();

		// Is Downloadable
		$is_downloadable = $product->is_downloadable();

		// Check if this product is not virtual or downloadable
		if ( ! ( $is_virtual || $is_downloadable )  ) $only_virtual = false;

	}

	// Update Status
	if ( $only_virtual ) $order->update_status( 'completed' );

}
				
			

Automatically Complete WooCommerce Orders

That’s basically it, the critical thing is toward the end of the snippet where it says $order->update_status( ‘completed’ );

This is the section which actually performs the action, everything before it is basically looping through the order to check that all the products are downloadable or virtual.

You can modify this to set the status to whatever you want, you can find a list of the standard WooCommerce statuses here.

And That's How We AutoComplete WooCommerce Orders

Happy WooCommercing friends!

If you have any questions or it’s not working for you feel free to leave a comment below and I will be able to assist you.

Thanks, Chris!

Subscribe
Notify of
guest
35 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
bilal
bilal
1 month ago

Hello Genius, How can we redirect to an external link after checking if someone purchased the virtual product?

Mike
Mike
1 month ago

Christopher, last night I received an order for a single product that is Simple and Virtual. I have your snippet in place and activated, priority 1, and the order came through with the Processing status, not Completed as I expected. In looking at the order notes, I can see that the first order attempt via Stripe failed, then he used Paypal and the next note says: “Order status changed from Failed to Processing.” so I don’t know if the first failed order attempt had anything to do with it not going to the completed status. Here’s a screenshot attached, what… Read more »

simple-virtual-order
Mike
Mike
Reply to  Mike
1 month ago

Just received another order with a single variable product, whose variation is virtual (but not downloadable) and it stayed in the Processing status until I changed it to Completed, so I think an adjustment needs to be made to your snippet.

Mike C
Mike C
Reply to  Christopher Davies
1 month ago

Did you make any changes to the code after my last comment a week ago? I can try to replace it again, but my orders stay in processing status, they don’t go to completed even though each product is a variable virtual (but not downloadable) product in the order.

Mike C
Mike C
Reply to  Christopher Davies
1 month ago

Ok thank you, I’ll let you know after I receive an order, or put a test order in, whichever comes first.

bilal
bilal
1 month ago

It’s not working with downloadable only

bilal
bilal
Reply to  Christopher Davies
1 month ago

You are a gem man.

Mike
Mike
Reply to  Christopher Davies
1 month ago

I was just coming on here to report it wasn’t working for virtual orders and then saw this comment. I will update the snippet and report back..

Mike
Mike
Reply to  Christopher Davies
1 month ago

Ok, many thanks for the reply!

Mike
Mike
1 month ago

Hi, just wondering if you incorporated the suggestions from Lindsay and Jakob commenters as I need to implement what they said as well.

Mike
Mike
Reply to  Christopher Davies
1 month ago

Wait, now I’m confused? I have some products that are virtual only (they should be auto completed) and I also have products that are virtual and downloadable (they should also be auto completed) Does your current snippet achieve that?

Lindsay
Lindsay
1 year ago

Please note this does not check variable products. If you want to check if BOTH simple products and variations are virtual, you need to update the code as follows:

Remove this line:

$product = wc_get_product( $item['product_id'] );

And replace it with this:

$product_variation_id = $item['variation_id'];
if ($product_variation_id) {
$product = wc_get_product($item['variation_id']);
} else {
$product = wc_get_product($item['product_id']);
}

Last edited 1 year ago by Lindsay
TKNR
TKNR
1 year ago

Hi,
Christopher.

Thank you for great code.
Could I ask one question?

When I manually change an order from Pending to Processing, it does not automatically complete.

How can I solve this?

I really need this feature for several reasons.

Matt
Matt
1 year ago

Thanks Chris, worked perfectly!

khaled
khaled
1 year ago

how can i make it work for free items only?

Jakob
Jakob
1 year ago

If I sell products that is only set to virtual (happens when I sell event tickets from events plugin integrated with woocommerce), can I also set these orders to completed – or will they already work like that?

Jakob
Jakob
Reply to  Christopher Davies
1 year ago

Great. Thank you!

Sean
Sean
1 year ago

Small addition to the code in case you happen to use the woocommerce subscriptions addon for your virtual service/product: /**  *  * @author    Christopher Davies, WP Davies  * @link      https://wpdavies.dev/  * @link      https://wpdavies.dev/automatically-complete-virtual-orders-woocommerce/  * @snippet   Automatically complete virtual, downloadable, and subscription orders in WooCommerce. This stops them from being in "Processing" waiting for a manual completion  *  */ add_action('woocommerce_thankyou', 'wpd_autocomplete_virtual_orders', 10, 1 ); function wpd_autocomplete_virtual_orders( $order_id ) {    if( ! $order_id ) return;    // Get order    $order = wc_get_order( $order_id );    // get order items = each product in the order    $items = $order->get_items();    // Set variable    $only_virtual = true;    foreach ( $items as $item ) {        //… Read more »

Taka
Taka
1 year ago

Hi,
Thanks for great codes!

I have 2 questions.

  1. What happens if customer dont pay money choosing bank transfer? Still Code automatically sent to customer?
  2. My product is virtual product but not downloadable. How can I fix this code?
Charlie
Charlie
1 year ago

This doesn’t seem to be working in the latest version of Woocommerce (6.8.2).