Search code examples
phpwordpresswoocommercecheckoutshipping-method

Prevent WooCommerce Shipping Rate ID from Changing for Each Zone


My shipping rate IDs seem to be different for each zone. For example it will be free_shipping:32 in zone 1, free_shipping:46 in zone 2, etc. I don't believe this is normally how WooCommerce functions. Would anyone happen to know what might be causing this and how to solve it?

This seems to be affecting every shipping method, not just free shipping.

I'd like to remove table rates from the cart if free shipping is available. Is there a way to get around the unique shipping instance ID in this function?

if ( isset( $rates['free_shipping:7'] ) ) {
    foreach ( $rates as $key => $value ) {
        if ( false !== strpos( $key, "table_rate" ) ) {
            unset( $rates[$key] );
        }
    }
}     
return $rates;

Solution

  • You can't prevent WooCommerce Shipping Rate ID from Changing for Each Zone, as each shipping method that you set has a unique instance ID, which is part of the Shipping Rate ID.

    But you can target a shipping method type, like for example Free Shipping as follows:

    add_filter('woocommerce_package_rates', 'filter_wc_package_rates', 10, 2);
    function filter_wc_package_rates($rates, $package) {
        $free_shipping_found = false; // Initializing
    
        // Loop through available shipping rates
        foreach ( $rates as $key => $rate ) {
            // Check for Free shipping methods
            if( 'free_shipping' === $rate->method_id ) {
                $free_shipping_found = true; // Free shipping found
                break; // Stop the loop
            }
        }
    
        // If there is an available free shipping method
        if( $free_shipping_found ) {
            // Loop through available shipping rates
            foreach ( $rates as $key => $rate ) {
                // Target shipping methods rate Ids containing 'table_rate' sub string
                if ( false !== strpos($key, 'table_rate') ) {
                    unset($rates[$key]); // Remove shipping method 
                }
            }
        }
        return $rates;
    }   
    

    Code goes in functions.php file of your child theme (or in a plugin). It should work.

    Important: You will have to empty your cart to refresh shipping methods cache.