Hide Shipping Methods for Specific Shipping Class in Woocommerce

Hide shipping methods for specific shipping class in WooCommerce

Update 2019: You should try instead this shorter, compact and effective way:

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;
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

Tested and works.

Sometimes, you should may be need to refresh shipping methods going to shipping areas, then disable / save and re-enable / save your "flat rates" shipping methods.

Related: Hide shipping methods for specific shipping classes in WooCommerce

To find the shipping methods IDs and the shipping classes IDs see below…


Update for many different shipping methods (related to your comments):

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 methods you want to hide
$method_key_ids = array('flat_rate:7', 'local_pickup:3');

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

Tested and works…


Finding the shipping class ID.

  1. In the database under wp_terms table:

Search for a term name or a term slug and you will get the term ID (the shipping class ID).


  1. On Woocommerce shipping settings editing a "Flat rate", with your browser html inspector tool, inspect a shipping Class rate field like:

Sample Image

In the imput name attribute you have woocommerce_flat_rate_class_cost_64. So 64 is the ID for the shipping class.


Get the shipping method rate ID:

To get the related shipping methods rate IDs, something like flat_rate:12, inspect with your browser code inspector each related radio button attribute value like:

Sample Image

Hide shipping methods for some shipping classes in WooCommerce

Try the following code, where everything is merged in a unique hooked function:

add_filter( 'woocommerce_package_rates', 'hide_shipping_method_based_on_shipping_class', 10, 2 );
function hide_shipping_method_based_on_shipping_class( $rates, $package )
{
// HERE define your shipping class to find
$classes_group1 = array(47, 48, 49);
$classes_group2 = array(40, 41, 43, 44, 45, 46);

// HERE define the shipping methods you want to hide
$method_key_ids1 = array('flat_rate:3', 'flat_rate:6', 'flat_rate:7');
$method_key_ids2 = array('flat_rate:8');

$found_group1 = $found_group2 = false; // Initializing

// Checking in cart items
foreach( $package['contents'] as $item ) {
$shipping_class = $item['data']->get_shipping_class_id();

// Shipping Classes group 1
if( in_array( $shipping_class, $classes_group1 ) ){
foreach( $method_key_ids1 as $method_key_id ){
// Remove the targeted methods 1
unset($rates[$method_key_id]);
$found_group1 = true; // Flag
}
}
// Shipping Classes group 2
if( in_array( $shipping_class, $classes_group2 ) ){
foreach( $method_key_ids2 as $method_key_id ){
$found_group2 = true; // Flag
}
}

// If Shipping Classes group 2 alone in cart
if( ! $found_group1 && $found_group2 ){
foreach( $method_key_ids2 as $method_key_id ){
// Remove the targeted methods 2
unset($rates[$method_key_id]);
}
}
}
return $rates;
}

Code goes in functions.php file of the active child theme (or active theme). It should works.

Refresh shipping methods:

  • Empty the cart.
  • If needed, go to shipping areas settings, then disable / save and re-enable / save any shipping methods from a shipping zone.

Hide shipping methods for specific shipping classes in WooCommerce

To use multiple shipping classes, you should first defined them in an array and in the IF statement you will use in_array() conditional function this way:

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 classes to find
$classes = [3031, 3032];

// HERE define the shipping methods you want to hide
$method_key_ids = array('flat_rate:189');

// Checking in cart items
foreach( $package['contents'] as $item ) {
// If we find one of the shipping classes
if( in_array( $item['data']->get_shipping_class_id(), $classes ) ){
foreach( $method_key_ids as $method_key_id ){
unset($rates[$method_key_id]); // Remove the targeted methods
}
break; // Stop the loop
}
}
return $rates;
}

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

Sometimes, you should may be need to refresh shipping methods going to shipping areas, then disable / save and re-enable / save your "flat rates" shipping methods.

Related thread: Hide shipping methods for specific shipping class in WooCommerce

Hide free shipping for specific shipping classes exclusively in Woocommerce

There are some mistakes and your code can be simplified. To disable free shipping for specific shipping classes exclusively, try the following revisited code:

add_filter( 'woocommerce_package_rates', 'hide_free_shipping_conditionally', 10, 2 );
function hide_free_shipping_conditionally( $rates, $package ) {
// Define the targeted shipping classes slugs (not names)
$targeted_classes = array( 'extra' );

$found = $others = false; // Initializing

// Loop through cart items for current shipping package
foreach( $package['contents'] as $item ) {
if ( in_array( $item['data']->get_shipping_class(), $targeted_classes ) ) {
$found = true;
} else {
$others = true;
}
}

// When there are only items from specific shipping classes exclusively
if ( $found && ! $others ) {
// Loop through shipping methods for current shipping package
foreach( $rates as $rate_key => $rate ) {
// Targetting Free shipping methods
if ( 'free_shipping' === $rate->method_id ) {
unset($rates[$rate_key]); // Remove free shipping option(s)
}
}
}
return $rates;
}

Code goes in functions.php file of the active child theme (or active theme). It should work.

Doin't forget to empty your cart to refresh shipping cached data.

Hide specific shipping method when another specific shipping method is active in WooCommerce

Updated - added a missing ;

First you need to get the correct shipping rate Ids for "Delivery by express mail ($35)" and also for "Free shipping by express mail".

This can be do when inspecting the generated html code (with your browser inspector) on your shipping methods radio buttons. so you will see something like:

Sample Image

where the shipping method rate Id is free_shipping:10 (the radio button "value").

The code below will hide "Paid delivery by express mail (cost $35)" when "Free delivery by express mail" is available $(you will have to set both shipping rate Ids)*:

add_filter( 'woocommerce_package_rates', 'customizing_shipping_methods', 10, 2 );
function customizing_shipping_methods( $rates, $package ) {
$flat_express_delivery_rate_id = 'flat_rate:12'; // Paid delivery by express mail (cost $35)
$free_express_delivery_rate_id = 'free_shipping:10'; // Free delivery by express mail

// When Free delivery by express mail is available
if( isset($rates[$free_express_delivery_rate_id]) ) {
// Remove Paid delivery by express mail (cost $35)
unset($rates[$flat_express_delivery_rate_id]);
}
return $rates;
}

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

Refresh shipping methods

Once you have saved this code, empty cart to refresh shipping methods, or if needed, go to shipping areas settings, then disable / save and re-enable / save any shipping methods from a shipping zone.

Show or hide shipping methods based on number of cart items for specific shipping class

You should use different function names for each code snippet, but the best way is to merge everything in a unique function.

Here is the way to make it work in a unique function (for items from specific shipping method(s)):

  • hiding some shipping methods when there are 4 or less items in cart
  • hiding some other shipping methods when there are 4 or less items in cart

The code:

add_filter( 'woocommerce_package_rates', 'show_hide_shipping_methods_based_on_shipping_class', 10, 2 );
function show_hide_shipping_methods_based_on_shipping_class( $rates, $package ) {
$targeted_class_ids = array(182); // Shipping Class To Find

$allowed_max_qty = 4; // Max allowed quantity for the shipping class

$shipping_rates_ids1 = array( // Shipping Method rates Ids To Hide if more than 4 items are in cart
'wf_shipping_ups:07',
'wf_shipping_ups:08',
'wf_shipping_ups:11',
'wf_shipping_ups:54',
'wf_shipping_ups:65',
'wf_shipping_ups:70',
'wf_shipping_ups:74',
'free_shipping:2',
'request_shipping_quote',
);

$shipping_rates_ids2 = array( // Shipping Method rates Ids to Hide if 4 or less items are in cart
'flat_rate:20',
'flat_rate:20',
);

$related_total_qty = 0; // Initializing

// Checking cart items for current package
foreach( $package['contents'] as $key => $cart_item ) {
if( in_array( $cart_item['data']->get_shipping_class_id(), $targeted_class_ids ) ){
$related_total_qty += $cart_item['quantity'];
}
}

// When total allowed quantity is more than allowed (for items from defined shipping classes)
if ( $related_total_qty > $allowed_max_qty ) {
// Hide related defined shipping methods (more than 4 items)
foreach( $shipping_rates_ids1 as $shipping_rate_id ) {
if( isset($rates[$shipping_rate_id]) ) {
unset($rates[$shipping_rate_id]); // Remove Targeted Methods
}
}
} else {
// Hide related defined shipping methods (4 or less items)
foreach( $shipping_rates_ids2 as $shipping_rate_id ) {
if( isset($rates[$shipping_rate_id]) ) {
unset($rates[$shipping_rate_id]); // Remove Targeted Methods
}
}
}
return $rates;
}

Code goes in functions.php file of your active child theme (or active theme). Untested it should works.

Refresh the shipping caches:

  1. This code is already saved on your functions.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.


Handling number of items instead of items cumulated quantity:

Replace:

$related_total_qty += $cart_item['quantity'];

by

$related_total_qty++;

Hide all Flat rate Shipping methods for specific shipping classes in WooCommerce

To use it for all "flat rate" Shipping methods and some other defined shipping methods, you will use the following instead:

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 methods you want to hide (others than "flat rate")
$method_key_ids = array('local_pickup:3');

$found = false;

// Checking in cart items
foreach( $package['contents'] as $cart_item ){
// If we find the shipping class
if( $cart_item['data']->get_shipping_class_id() == $class ){
$found = true;
break; // Stop the loop
}
}

if( ! $found )
return $rates;

// Loop through shipping methods
foreach( $rates as $rate_key => $rate ) {
// Targetting "Flat rate" and other defined shipping mehods
if( 'flat_rate' === $rate->method_id || in_array($rate->id, $method_key_ids) ) {
unset($rates[$rate_key]);
}
}

return $rates;
}

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

Refresh the shipping caches: (required)

  1. This code is already saved on your active theme's function.php file.
  2. The cart is empty
  3. In a shipping zone settings, disable / save any shipping method, then enable back / save.

Hide shipping methods based on availability of other shipping methods in WooCommerce

  • $rate->method_id will be equal to local_pickup, free_shipping, flat_rate, etc..

  • while $rate_id will be equal to local_pickup:1, free_shipping:2, etc..

So either you use it like this:

function filter_woocommerce_package_rates( $rates, $package ) { 
// Loop trough
foreach ( $rates as $rate_id => $rate ) {
// Checks if a value exists in an array, multiple can be added, separated by a comma
if ( in_array( $rate->method_id, array( 'local_pickup', 'free_shipping' ) ) ) {
unset( $rates['flat_rate:28'] );
}
}

return $rates;
}
add_filter( 'woocommerce_package_rates', 'filter_woocommerce_package_rates', 10, 2 );

OR like this:

function filter_woocommerce_package_rates( $rates, $package ) { 
// Loop trough
foreach ( $rates as $rate_id => $rate ) {
// Checks if a value exists in an array, multiple can be added, separated by a comma
if ( in_array( $rate_id, array( 'local_pickup:1', 'free_shipping:2' ) ) ) {
unset( $rates['flat_rate:28'] );
}
}

return $rates;
}
add_filter( 'woocommerce_package_rates', 'filter_woocommerce_package_rates', 10, 2 );

Code goes in functions.php file of the active child theme (or active theme). Tested and works in Wordpress 5.8.1 & WooCommerce 5.8.0

Don't forget to empty your cart to refresh shipping cached data.

Disable shipping methods having a specific word and based on a shipping class in WooCommerce

Updated

Using PHP strpos() will allow you to check if a word is contained in a string. Then you will need to make some changes in your code to make it work:

add_filter( 'woocommerce_package_rates', 'show_hide_shipping_methods', 10, 2 );
function show_hide_shipping_methods( $rates, $package ) {
$shipping_class_id = 35; // Targeted shipping class ID
$found = false;

// Loop through cart items for the current package
foreach ( $package['contents'] as $cart_item ) {
if( $cart_item['data']->get_shipping_class_id() == $shipping_class_id ) {
$found = true;
break;
}
}

// Loop through shipping rates
foreach ( $rates as $rate_key => $rate ) {
if ( $found && strpos($rate_key, '_classique') !== false ) {
unset($rates[$rate_key]);
}
elseif (! $found && strpos($rate_key, '_print') !== false ) {
unset($rates[$rate_key]);
}
}
return $rates;
}

Code goes in functions.php file of the active child theme (or active theme). It should works.

Clearing shipping caches:

  • You will need to empty your cart, to clear cached shipping data
  • Or In shipping settings, you can disable / save any shipping method, then enable back / save.

Related:

  • How can I check if a word is contained in another string using PHP?
  • Hide shipping methods for specific shipping class in WooCommerce
  • Filter Shipping method based on shipping class in Woocommerce 3


Related Topics



Leave a reply



Submit