How to Hide Shipping Methods in WooCommerce?

This is a small detail, but WooCommerce doesn’t have built-in any function for hiding shipping methods based on different situations. Imagine when your customers have a full cart, free shipping method available and they can still choose another one. Make sense? No. Maybe it’s good for a miss click -> you got extra money $$ (haha). But it’s better to hide it, agree?

Few situations when you want to hide shipping methods:

  • Hide other shipping methods when “Free Shipping” is available
  • Hide shipping methods for specific shipping class in WooCommerce
  • Hide shipping methods except for local pickup for a specific product category

Hide other shipping methods when “Free Shipping” is available

This following piece of code will hide all other shipping methods excluding Local Pickup when the Free shipping method is available. To make it work, it required to set a minimum order amount for the free shipping method in administration.

Insert code below anywhere into your active theme folder (/wp-content/themes/yourtheme/functions.php):

add_filter( 'woocommerce_package_rates', 'show_hide_shipping_methods', 100 );

function show_hide_shipping_methods( $rates ) {
    $free_rate_id    = '';
    $other_rates_ids = [];

    // Loop through available shipping rates
    foreach ( $rates as $rate_id => $rate ) {
        if ( 'free_shipping' === $rate->method_id ) {
            $free_rate_id = $rate_id; // grab "Free shipping" rate ID
        }

        // Get all other rates Ids (excluding "Free shipping" and "Local pickup" methods)
        if ( ! in_array( $rate->method_id, ['free_shipping', 'local_pickup'] ) ) {
            $other_rates_ids[] = $rate_id; 
        }
    }

    // Disable All other rates Ids when "Free shipping" is available (excl. "Local pickup")
    if ( ! empty($free_rate_id) && isset($rates[$free_rate_id]) && sizeof($other_rates_ids) > 0 ) {
        foreach ( $other_rates_ids as $rate_id ) {
            unset($rates[$rate_id]);
        }
    }
    return $rates;
}

Because this issue is very common, official WooCommerce Docs has an article on their website regarding this exact issue with hiding shipping methods when free shipping is available.

Hide shipping methods for specific shipping class in WooCommerce

At first, you need to find a shipping class. You can do it through browser HTML inspector, like that:

Cool, you have to shipping class ID. Now you can insert code below anywhere into your active theme folder (/wp-content/themes/yourtheme/functions.php):

add_filter( 'woocommerce_package_rates', 'hide_shipping_method_based_on_shipping_class', 10, 2 );
function hide_shipping_method_based_on_shipping_class( $rates, $package )
{
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    // HERE define your shipping class to find
    $class = 92;

    // HERE define the shipping method to hide
    $method_key_id = 'flat_rate:7';

    // Checking in cart items
    foreach( $package['contents'] as $item ){
        // If we find the shipping class
        if( $item['data']->get_shipping_class_id() == $class ){
            unset($rates[$method_key_id]); // Remove the targeted method
            break; // Stop the loop
        }
    }
    return $rates;
}

Hide shipping methods except for local pickup for specific product category

We used this following code for a specific store with a lot of weapons. In categories array, you must fill slugs, names, or IDs of categories. After that, if your customer wants to buy any product from these categories, he must use only local pickup.

add_filter( 'woocommerce_package_rates', 'hide_shipping_methods', 90, 2 );

function hide_shipping_methods( $rates, $package ){

    // HERE set your product categories in the array (IDs, slugs or names)
    $categories = array( 'category-slug');
    $found = false;

    // Loop through each cart item Checking for the defined product categories
    foreach( $package['contents'] as $cart_item ) {
        if ( has_term( $categories, 'product_cat', $cart_item['product_id'] ) ){
            $found = true;
            break;
        }
    }

    $rates_arr = array();
    if ( $found ) {
        foreach($rates as $rate_id => $rate) { 
            if ('local_pickup' === $rate->method_id) {
                $rates_arr[ $rate_id ] = $rate;
            }
        }
    }
    return !empty( $rates_arr ) ? $rates_arr : $rates;
}

Recent Articles

How to find WooCommerce products in the database

Hey, where in the database (or phpMyAdmin) are my WooCommerce products stored? Sometimes you may have some reason to find directly any...

Why is WordPress Asking For Your FTP Credentials to Install Plugins?

You want to install any plugin, but *blink* - WordPress need your FTP credentials. What the hell? The problem is simple -...

Fix PHP Warning: POST Content-Length of 8978294 bytes exceeds the limit of 8388608 bytes in Unknown on line 0

This error is getting probably when you trying to upload an import on WordPress on your XAMPP local dev environment, right? Well,...

How to Hide Shipping Methods in WooCommerce?

This is a small detail, but WooCommerce doesn't have built-in any function for hiding shipping methods based on different situations. Imagine when...

How to Get WordPress Post Featured Image URL

Are you a WordPress developer or an advanced WordPress user? Whoever you are, sometimes you may need the direct URL of a...

Get in touch

Be our first-class reader, build a community and follow us on social media!

Leave A Reply

Please enter your comment!
Please enter your name here