Change order status just after payment in WooCommerce

30,462

Solution 1

Update 2 - 2019: Use WooCommerce: Auto complete paid orders (updated thread)

So the right hook to use is woocommerce_payment_complete_order_status filter returning complete


Update 1: Compatibility with WooCommerce version 3+

I have changed the answer

Based on: WooCommerce - Auto Complete paid virtual Orders (depending on Payment methods), you will be able to handle also all payment methods in conditionals:

// => not a filter (an action hook)
add_action( 'woocommerce_thankyou', 'custom_woocommerce_auto_complete_paid_order', 10, 1 );
function custom_woocommerce_auto_complete_paid_order( $order_id ) {
    if ( ! $order_id )
        return;

    $order = new WC_Order( $order_id );

    // No updated status for orders delivered with Bank wire, Cash on delivery and Cheque payment methods.
    if ( get_post_meta($order_id, '_payment_method', true) == 'bacs' || get_post_meta($order_id, '_payment_method', true) == 'cod' || get_post_meta($order_id, '_payment_method', true) == 'cheque' ) {
        return;
     }
    // "completed" updated status for paid "processing" Orders (with all others payment methods)
    elseif ( $order->has_status( 'processing' ) ) {
        $order->update_status( 'completed' );
    }
    else {
        return;
    }
}

Solution 2

The function woocommerce_thankyou is an action. You're required to use add_action function to hook into it. I would recommend changing the priority to 20 so that other plugins/code changes may be applied before update_order_status.

add_action( 'woocommerce_thankyou', 'update_order_status', 20);
Share:
30,462
Borys Zielonka
Author by

Borys Zielonka

Updated on April 06, 2020

Comments

  • Borys Zielonka
    Borys Zielonka about 4 years

    I need to change automatically an order status for completed after receiving payment, but only if the order status is "processing". I found that snippet, what makes orders status completed in every case, but my payments plugins after successful payment changes returns data and changes the order status for "processing". I would like to change it into "completed" after success and don't change it if the status isn't "processing". The main problem I met is I don't know how to get the received status order.

    Here is my code:

    add_filter( 'woocommerce_thankyou', 'update_order_status', 10, 2 );
    
    function update_order_status( $order_id ) {
       $order = new WC_Order( $order_id );
       $order_status = $order->get_status();    
       if ('processing' == $order_status) {    
           $order->update_status( 'completed' );    
        }    
     //return $order_status;
    }
    

    Edit:

    I figured it out already. Here's the code that works for me:

    add_filter( 'woocommerce_thankyou', 'update_order_status', 10, 1 );
    
    function update_order_status( $order_id ) {
      if ( !$order_id ){
        return;
      }
      $order = new WC_Order( $order_id );
      if ( 'processing' == $order->status) {
        $order->update_status( 'completed' );
      }
      return;
    }