Automatically Mark WooCommerce Orders as Completed After Payment for Virtual Products

By default, WooCommerce automatically marks virtual downloadable products as “completed” after the customer pays successfully. But if our virtual product is not downloadable, such as a coupon or an online recharge code, the order will not be marked as completed automatically after payment. That is clearly not a great user experience. The following adjustment makes WooCommerce support automatic completion for non-downloadable virtual products as well.

Just copy the code below into the theme’s functions.php file.

add_filter( 'woocommerce_payment_complete_order_status', 'virtual_order_payment_complete_order_status', 10, 2 );
function virtual_order_payment_complete_order_status( $order_status, $order_id ) {
  $order = new WC_Order( $order_id );
  if ( 'processing' == $order_status &&
       ( 'on-hold' == $order->status || 'pending' == $order->status || 'failed' == $order->status ) ) {
    $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() ) {
            // If it is not a virtual product, stop checking and break out.
            $virtual_order = false;
            break;
          } else {
            $virtual_order = true;
          }
        }
      }
    }
    // If it is a virtual product, return completed.
    if ( $virtual_order ) {
      return 'completed';
    }
  }
  // For non-virtual products, return the existing order status.
  return $order_status;
}

This is actually a very common requirement. It is hard to understand why WooCommerce does not provide a built-in option for it and instead leaves us to implement it ourselves.

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *