Francesca
Francesca

Reputation: 23

WooCommerce - hide / show shipping methods based on cart subtotal

In my WooCommerce store (using version 4.2.2), I would like to hide / show some shipping methods based on cart subtotal as follow:

Note shipping methods A, B, C and D are all "flat rate".

I have googled this and managed to get this trying the following code (I was just testing with one rate and one threshold):

add_filter( 'woocommerce_package_rates', 'hide_shipping', 10, 2 );
function hide_shipping( $rates, $package ) {
    // Retrieve cart subtotal
    global $woocommerce;
    $cart_subtotal = $woocommerce->cart->get_subtotal();
 
    if( $cart_subtotal > 25 ){
        unset( $rates['flat_rate:7'] );
    }
 
    return $rates;
}

But the code has no effect. Where am I going wrong?

Upvotes: 2

Views: 1899

Answers (1)

LoicTheAztec
LoicTheAztec

Reputation: 254373

Try the following (setting your 5 shipping methods rate Ids inside the code at the beginning). Also for your "free shipping" rate, set the "Minimum order amount" to 0 (zero).

add_filter( 'woocommerce_package_rates', 'hide_specific_shipping_method', 10, 2 );
function hide_specific_shipping_method( $rates, $package ) {
    // Settings: define you shipping rate IDs below
    $rate_id_1     = 'flat_rate:7';
    $rate_id_2     = 'flat_rate:11';
    $rate_id_3     = 'flat_rate:12';
    $rate_id_4     = 'flat_rate:15';
    $rate_free     = 'free_shipping:5';
    
    $cart_subtotal = WC()->cart->get_subtotal();
    
    if ( $cart_subtotal < 25 ) {
        // Enable only methods 1 et 2
        if ( isset($rates[$rate_id_3]) )
             unset( $rates[$rate_id_3] );
        if ( isset($rates[$rate_id_4]) )
             unset( $rates[$rate_id_4] );
        if ( isset($rates[$rate_free]) )
             unset( $rates[$rate_free] );
    } 
    elseif ( $cart_subtotal >= 25 && $cart_subtotal < 50 ) {
        // Enable only methods 3 et 4
        if ( isset($rates[$rate_id_1]) )
             unset( $rates[$rate_id_1] );
        if ( isset($rates[$rate_id_2]) )
             unset( $rates[$rate_id_2] );
        if ( isset($rates[$rate_free]) )
             unset( $rates[$rate_free] );
    } 
    else {
        // Enable only Free shipping
        if ( isset($rates[$rate_id_1]) )
             unset( $rates[$rate_id_1] );
        if ( isset($rates[$rate_id_2]) )
             unset( $rates[$rate_id_2] );
        if ( isset($rates[$rate_id_3]) )
             unset( $rates[$rate_id_3] );
        if ( isset($rates[$rate_id_4]) )
             unset( $rates[$rate_id_4] );
    }
    return $rates;
}

Code goes in functions.php file of your active child theme (or active theme). Tested and works.

IMPORTANT: Refresh the shipping caches:
1). This code is already saved on your function.php file.
2). In a shipping zone settings, disable / save any shipping method, then enable back / save.
You are done and you can test it.

Upvotes: 3

Related Questions