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!
Hello Genius, How can we redirect to an external link after checking if someone purchased the virtual product?
Hi Bilal,
You could modify the closing line of code to look like this, which just redirects after the order status has been completed:
// Update Status
if ( $only_virtual ) $order->update_status( ‘completed’ );
// Redirect to another URL
$url = ‘https://www.yoururl.com’; // Replace this url with the URL you want to redirect to
if ( wp_redirect( $url ) ) exit;
I haven’t tested this though and I wouldn’t recommend it, without digging into the WooCommerce code it is possible that this might prevent other code from being executed
Thanks, Chris
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 »
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.
Hi Mike,
I’ve the code to suit, the check on variable products was outdated – i’ve ran it through my test site and looks to be working on my end.
Thanks, Chris
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.
Hi Mike,
After posting my comment above I did make updates yes, make sure your code matches the one I have currently online
I’ve tested and it works, if it’s not working i’d possibly have to jump into your store
Thanks, Chris
Ok thank you, I’ll let you know after I receive an order, or put a test order in, whichever comes first.
It’s not working with downloadable only
Hi Bilal, I’ve updated the code to include virtual and downloadable
Thanks, Chris
You are a gem man.
🙂
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..
Hi Mike, yes two different requests came in at about the same time haha so the code changed a few times
It should work under both circumstances anyway
What it’s doing is checking if a product is NOT virtual or downloadable, and if that condition is met, then it assumes this order contains a physical product, and will therefore not change the status
The current code should autocomplete any orders that do not contain physical products, regardless of whether it’s downloadable / virtual or any combination of the two
Thanks, Chris
Ok, many thanks for the reply!
Hi, just wondering if you incorporated the suggestions from Lindsay and Jakob commenters as I need to implement what they said as well.
Hey Mike, yes they’ve been included. Just checks for a variation ID, and if set fetches that product otherwise will fetch the main product if there is no variation found. Thanks, Chris
Actually if you’re products are virtual only and don’t contain downloads, you’ll need to change:
To:
I’ve updated the code now
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?
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!
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
Thanks Chris, worked perfectly!
how can i make it work for free items only?
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!
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 🙂
Hi,
Thanks for great codes!
I have 2 questions.
Thanks! Chris
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