2

I have integrated a payment gateway to accept online payments for my store running on woocommerce. Everything works fine but I noticed that woocommerce is changing the order status to wc-processing for all the online paid orders by default.

As per my store's functionality I want all the online paid orders to be in wc-on-hold status initially.

Is there any way to stop woocommerce changing the order status to wc-processing programatically?

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
krishna89
  • 850
  • 1
  • 19
  • 42

2 Answers2

4

Here it is a code snippet based on this thread. We use here woocommerce_thankyou (that is fired just after payment has been done) to hook our function, converting 'processing' orders status to 'on-hold':

add_action( 'woocommerce_thankyou', 'custom_woocommerce_paid_order_status', 10, 1 );
function custom_woocommerce_paid_order_status( $order_id ) {
    if ( ! $order_id ) {
        return;
    }

    global $woocommerce;
    $order = new WC_Order( $order_id );

    // 'processing' orders status are converted to 'on-hold'.
    if ( is_object($order) && $order->has_status( 'processing' ) {
        $order->update_status( 'on-hold' ); 
    }

    return;
}

You can also target in your conditions the payment gateways for example here we bypass 3 payment gateways and target a specific payment gateway using "your_payment_gateway" slug:

add_action( 'woocommerce_thankyou', 'custom_woocommerce_paid_order_status', 10, 1 );
function custom_woocommerce_paid_order_status( $order_id ) {
    if ( ! $order_id ) {
        return;
    }

    global $woocommerce;
    $order = new WC_Order( $order_id );

    // Bypass orders 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;
    }

    // Target your "your_payment_gateway_slug" with this conditional
    if ( is_object($order) && get_post_meta($order->id, '_payment_method', true) == 'your_payment_gateway_slug'  && $order->has_status( 'processing' ) ) {
        $order->update_status( 'on-hold' ); 
    }

    return;
}

This code snippets goes on function.php file of your active child theme or theme.

You can easily do anything you want, and the correct hook for paid orders is woocommerce_thankyou

References:

Community
  • 1
  • 1
LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • Thank you so much, but in your solution the order would turn `on-hold` where it was already been marked as `processing` from gateway. My problem is I have an email alert flow connected with order status in which `on-hold` should be first status right from the gateway processing. – krishna89 Aug 05 '16 at 09:35
3

yes there is a way, but you need to modify the payment plugin or add your own code, you can read this to understand how payments work.

Now, woocommerce use $order->payment_complete() method to handle the completed order, so you need to hook your own function to modify the status, here is the description of that method

Use this filter: woocommerce_payment_complete_order_status

Samvel Aleqsanyan
  • 2,812
  • 4
  • 20
  • 28
Mauro
  • 1,472
  • 12
  • 22
  • You are right `$order->payment_complete()` is changing the order status to `processing` in my payment plugin. I will try placing my own function instead and let you know. – krishna89 Aug 05 '16 at 10:04
  • Instead of `$order->payment_complete()` I added the following code and it worked as I expected. `$order->update_status('on-hold'); add_post_meta($order->id, '_paid_date', current_time('mysql'), true); update_post_meta($order->id, '_transaction_id', $txnid); $order->reduce_order_stock();` – krishna89 Aug 05 '16 at 13:04