Search code examples
phpwordpresswoocommerceorders

Change Woocommerce Order Status based on Shipping Method


The idea here is that when an order comes in with an "express delivery" as Shipping Method, the order status is updated to On-Hold.

As there I have some different "express delivery" Shipping Method rates I thought that by using stristr() to see if the word 'express' appears anywhere in the formatted shipping method title. But I seem to be missing something as I don't get anything.

How can I check if the Order shipping method is an "express delivery" to be able to update the order status?

Here is the code that I have:

add_action( 'woocommerce_thankyou', 'express_orders_4865', 10, 1 );
function express_orders_4865( $order_id ) {
    global $woocommerce;

    $order = new WC_Order( $order_id );

    $shipping_method = $order->get_shipping_method();

    if (stristr($shipping_method, 'express') === TRUE) {
        $order->update_status('on-hold');
    } else {
        return;
    }
}

EDIT-----------------------------------------------------------

For anyone using Woocommerce Table Rate Shipping the get_method_id returns the table rate id so i used get_method_title instead as below, if there is a better way please comment...

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

    $search = 'Express'; // The needle to search in the shipping method ID

    // Get an instance of the WC_Order object
    $order = wc_get_order( $order_id );

    // Get the WC_Order_Item_Shipping object data
    foreach($order->get_shipping_methods() as $shipping_item ){
        // When "express delivery" method is used, we change the order to "on-hold" status


        if( strpos( $shipping_item->get_method_title(), $search ) !== false ){
            $order->update_status('on-hold');
            break;
        }
    }
}

Solution

  • I prefer to use the faster and less memory intensive function strpos() instead as the shipping method ID is alway in lowercase (like a kind of slug).

    So is better the get the WC_Order_Item_Shipping object data for this case, using the available methods.

    So the code should be:

    add_action( 'woocommerce_thankyou', 'express_shipping_update_order_status', 10, 1 );
    function express_shipping_update_order_status( $order_id ) {
        if ( ! $order_id ) return;
        
        $search = 'express'; // The needle to search in the shipping method ID
    
        // Get an instance of the WC_Order object
        $order = wc_get_order( $order_id );
    
        // Get the WC_Order_Item_Shipping object data
        foreach($order->get_shipping_methods() as $shipping_item ){
            // When "express delivery" method is used, we change the order to "on-hold" status
            if( strpos( $shipping_item->get_method_title(), $search ) !== false && ! $order->has_status('on-hold')){
                $order->update_status('on-hold');
                break;
            }
        }
    }
    

    Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

    Tested and works…