skip to Main Content

I need to change the order status from the default ‘processing’ status to ‘priority’ if a customer chooses any 1 of 4 express shipping options.

I’m using the classic checkout.

Here’s what I’ve tried so far but nothing happens when a user places an order.

add_action( 'woocommerce_thankyou', 'shipping_method_update_order_status', 10, 1 );
function shipping_method_update_order_status( $order_id ) {
    if ( ! $order_id ) return;
    
    // Here define your shipping methods Ids
    $shipping_method_0_flat_rate25 = array('flat_rate');
    $shipping_method_0_flat_rate26 = array('flat_rate');
    $shipping_method_0_flat_rate27 = array('flat_rate');
    $shipping_method_0_flat_rate28 = array('flat_rate');

    // 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 ){
        // For testing to check the shipping method slug (uncomment the line below):
        // echo '<pre>'. print_r( $shipping_item->get_method_id(), true ) . '</pre>';

        if( in_array( $shipping_item->get_method_id(), $shipping_method_0_flat_rate25 ) && ! $order->has_status('priority_dispatch') ){
            $order->update_status('priority_dispatch'); // Already use internally save() method
            break; // stop the loop
        }
        elseif( in_array( $shipping_item->get_method_id(), $shipping_method_0_flat_rate26 ) && ! $order->has_status('priority_dispatch') ){
            $order->update_status('priority_dispatch'); // Already use internally save() method
            break; // stop the loop
        }
        elseif( in_array( $shipping_item->get_method_id(), $shipping_method_0_flat_rate27 ) && ! $order->has_status('priority_dispatch') ){
            $order->update_status('priority_dispatch'); // Already use internally save() method
            break; // stop the loop
        }
        elseif( in_array( $shipping_item->get_method_id(), $shipping_method_0_flat_rate28 ) && ! $order->has_status('priority_dispatch') ){
            $order->update_status('priority_dispatch'); // Already use internally save() method
            break; // stop the loop
        }
    }
}

2

Answers


  1. Key Changes:

    1.Simplified Shipping Method IDs: Combined all express shipping methods into a single array.

    2.Correct Method ID Format: Ensure the method IDs match the format returned by get_method_id(), which typically includes the method type and instance ID (e.g., flat_rate:25).

    3.Status Update: Changed the status to ‘priority’ to match your requirement.

    add_action( 'woocommerce_thankyou', 'shipping_method_update_order_status', 10, 1 );
    function shipping_method_update_order_status( $order_id ) {
        if ( ! $order_id ) return;
    
        // Define your express shipping methods IDs
        $express_shipping_methods = array('flat_rate:25', 'flat_rate:26', 'flat_rate:27', 'flat_rate:28');
    
        // 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 ) {
            // Get the full method ID including instance ID
            $method_id = $shipping_item->get_method_id() . ':' . $shipping_item->get_instance_id();
    
            // Check if the shipping method is one of the express options
            if ( in_array( $method_id, $express_shipping_methods ) && ! $order->has_status('priority') ) {
                $order->update_status('priority'); // Update the order status to 'priority'
                break; // Stop the loop
            }
        }
    }
    
    
    Login or Signup to reply.
  2. It is better to avoid using woocommerce_thankyou hook to change the order status from processing orders for many reasons. The hook woocommerce_order_status_processing is more convenient and reliable, as it’s triggered when an order gets the "processing" status.

    Also, you can use instead the unique shipping method instance ID (which is the number after the : character, from your slugs).

    Caution: Be sure that the slug for your custom order status is "priority_dispatch".

    Try the following revised code:

    add_action( 'woocommerce_order_status_processing', 'shipping_method_update_order_status', 10, 2 );
    function shipping_method_update_order_status( $order_id, $order ) {
        // Here, define the shipping methods instance IDs in the array
        $defined_instance_ids = array('25', '26', '27', '28');
    
        // Loop through order "shipping" items
        foreach ( $order->get_items('shipping') as $item ) {
            // Check for any matching shipping method instance ID
            if ( in_array( $item->get_instance_id(), $defined_instance_ids ) ) {
                // Update the order status
                $order->update_status('priority_dispatch'); 
                break; // Stop the loop
            }
        }
    }
    

    It should work.

    Related: Get orders shipping items details in WooCommerce 3


    How to get the correct shipping rate ID(s) and instance ID(s)

    The following function will display, near the footer (on frontend, when there are items in cart), the available shipping rates IDs and instance IDs:

    add_action('wp_footer', 'display_shipping_methods_rates_data');
    function display_shipping_methods_rates_data() {
        echo '<pre><h4>Available Shipping Methods Rates</h4>
        <table><thead><tr><th>Shipping method</th><th>Rate ID</th><th>Instance ID</th></tr></thead><tbody>';
    
        foreach ( WC()->cart->get_shipping_packages() as $package_key => $package ){
            $data = WC()->session->get( "shipping_for_package_{$package_key}" );
            foreach ( $data['rates'] as $rate ) {
                echo '<tr><td>'.$rate->label.'</td><td>'.$rate->id.'</td><td>'.$rate->instance_id.'</td></tr>';
            }
        }
        echo '</tbody></table></pre>';
    }
    

    Once you get the correct shipping rate IDs (or instances IDs) to be used in your code, you can remove this code snippet.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search