Search code examples
phpwordpresswoocommercecart

Hide specific shipping method for specific products in Woocommerce


I have a few products in my WooCommerce store that are to heavy (more than 20kg) to be shipped by a certain shipping method. I would like to hide 'shipping_method_0_flat_rate2' for all cart items which contain a product that is heavier than 20kg.

I tried to adjust the snippet below, but it is not complete and working:

add_filter( 'woocommerce_package_rates', 'hide_shipping_based_on_tag' ,    10, 1 );
function check_cart_for_share() {

    // specify the product id's you want to hide
    $product_ID = array(
    '113', // Product name
    );
    global $woocommerce;
    $cart = $woocommerce->cart->cart_contents;

    $found = false;

    // loop through the array looking for the products. Switch to true if the product is found.
    foreach ($woocommerce->cart->cart_contents as $key => $values ) {
        $terms = get_the_terms( $values['product_id'], 'product_cat' );
        foreach ($terms as $term) {
            if( in_array( $term->term_id, $product_ID ) ) {

        $found = true;
        break;
    }
  }
}

return $found;

}

function hide_shipping_based_on_tag( $available_methods ) {

    // use the function above to check the cart for the products.
    if ( check_cart_for_share() ) {

    // remove the method you want
    unset( $available_methods['shipping_method_0_flat_rate2'] ); // Replace with the shipping option that you want to remove.
}

    // return the available methods without the one you unset.
    return $available_methods;

}

Any help is appreciated.


Solution

  • You are making things more complicated in your code and your shipping method ID is not the good one… Try this instead:

    add_filter( 'woocommerce_package_rates', 'specific_products_shipping_methods', 10, 2 );
    function specific_products_shipping_methods( $rates, $package ) {
    
        $product_ids = array( 113 ); // HERE set the product IDs in the array
        $method_id = 'flat_rate:2'; // HERE set the shipping method ID
        $found = false;
    
        // Loop through cart items Checking for defined product IDs
        foreach( $package['contents'] as $cart_item ) {
            if ( in_array( $cart_item['product_id'], $product_ids ) ){
                $found = true;
                break;
            }
        }
        if ( $found )
            unset( $rates[$method_id] );
    
        return $rates;
    }
    

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

    You should need to refresh the shipping caches:
    1) First this code is already saved on your function.php file.
    2) In Shipping settings, enter in a Shipping Zone and disable a Shipping Method and "save". Then re-enable that Shipping Method and "save". You are done.