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.
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 ) { 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 ) { // Get product object if ( isset($item['variation_id']) && ! empty($item['variation_id']) ) { $product = wc_get_product( $item['variation_id'] ); } else { $product = wc_get_product( $item['product_id'] ); } // Safety check if ( ! is_object($product) ) { return false; } // Is virtual $is_virtual = $product->is_virtual(); // Is_downloadable $is_downloadable = $product->is_downloadable(); if ( ! $is_virtual && ! $is_downloadable ) { $only_virtual = false; } } // true if ( $only_virtual ) { $order->update_status( 'completed' ); } }
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.
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!
Supercharge your WooCommerce store with WP Davies
Copyright © 2023 Design by WP Davies
ABN 23 988 145 173 | WP DAVIES
This doesn’t seem to be working in the latest version of Woocommerce (6.8.2).
Hi Charlie, Thanks for the comment. I’ve tested on my end and it should be working, you may have a conflict with another plugin potentially? What error(s) are coming up or what’s the issue? Thanks, Chris
Hi,
Thanks for great codes!
I have 2 questions.
Thanks! Chris
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 »
Good stuff man 🙂
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?
As it stands this code only applies to products that are both virtual & downloadable.
To make it apply to products that are only virtual and not necessarily downloadable, you would need to remove && ! $is_downloadable from line 34.
This would mean that it is only checking if products are virtual, rather than virtual & downloadable.
Great. Thank you!
how can i make it work for free items only?
Thanks Chris, worked perfectly!
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.
Hi there, thanks for reading this article!
I can’t imagine why you wouldn’t be putting the order into complete if you’re doing it manually, anything that runs when it flicks over to processing would still happen
Please clarify further if you’ve got a specific scenario
Thanks, Chris
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']);
}
Yep 100%, this is rock solid. I’ve added this in and a few safety checks. Thanks for the update friend, this is important!