How to Disable Shipping Methods for Certain Products

Below, I will show you how to configure different shipping methods for different products in WooCommerce, so we can enable or disable a specific shipping method when a certain product is in the customer’s cart (or in a specific order).

We will dive into both programmatic and plugin approaches; more than that, I will show you how to do it not only for specific products, but also for products with a specific shipping class.

Disable Specific Shipping Methods for Certain Products

Simple Conditional Shipping and Payments for WooCommerce is the easiest way to use
different shipping methods for different products.

The whole process is very straightforward.

Basically, once you have installed the plugin, all you need to do is navigate to the settings page in WooCommerce > Settings > Conditions > Shipping conditions, and create a new condition like the one you see in the screenshot below:

WooCommerce disable shipping for certain products
We restricted “Local Pickup” for all shipping zones when “Wizard hat” is in the cart.

If you need to use different shipping methods for different products, then you can create as many conditional rules as you want. For example, it may look like this:

WooCommerce different shipping methods for different products
By the way, it is not necessary to have different shipping methods for “Product 1”, “Product 2”, etc. You can set the same shipping method there; in that case, the conditions will be applied in an “OR”-type relation.

More things to keep in mind:

As easy as that.

However, if you prefer a programmatic approach, you can use the code snippet below:

/**
 * @snippet WooCommerce Disable Shipping Method for Certain Products
 * @author Misha Rudrastyh
 * @url https://rudrastyh.com/woocommerce/disable-shipping-methods-for-certain-products.html#certain-products
 */
add_filter( 'woocommerce_package_rates', 'rudr_no_local_pickup_if_product_in_cart' );

function rudr_no_local_pickup_if_product_in_cart( $rates ) {
	// this is a specific product ID we are going to check
	$product_id = 20;
	// customer's cart
	foreach( WC()->cart->get_cart_contents() as $cart_item ) {
		if( $product_id === $cart_item[ 'data' ]->get_id() ) {

			foreach( $rates as $rate_id => $rate ) {
				if( str_starts_with( $rate_id, 'local_pickup' ) ) {
					unset( $rates[ $rate_id ] );
				}
			}
			break;
		}
	}

	return $rates;
}

Is everything clear in the code above? In any case, below are some of my comments:

If you want to check multiple products in the cart, you can use the following replacement:

function rudr_no_local_pickup_if_product_in_cart( $rates ) {

	$product_ids = array( 20, 21, 22 );

	foreach( WC()->cart->get_cart_contents() as $cart_item ) {
		if( in_array( $cart_item[ 'data' ]->get_id(), $product_ids ) ) {

If you’re interested in disabling payment methods for specific products as well, then feel free to check my other tutorial.

Enable a Shipping Method for Products with a Shipping Class

It is not necessary to restrict a shipping method per product individually, and using product categories and tags may not always be convenient. In that case, we can group a bunch of products we need with shipping classes.

Below is an example of how the condition will look if you decide to use the plugin I mentioned above, Simple Conditional Shipping and Payments for WooCommerce. Also, let’s not disable but enable a shipping method for a change:

Restrict or enable specific shipping methods in WooCommerce depending on a shipping class
Since multiple conditions are supported, you can select multiple shipping classes there.

If you’re not ready for the plugin approach, below are the changes you will need to make in the code snippet above:

$shipping_class = 'my-test-class'; // shipping class slug
$is_shipping_allowed = false;

// check cart contents first
foreach( WC()->cart->get_cart_contents() as $cart_item ) {
	if( $shipping_class === $cart_item[ 'data' ]->get_shipping_class() ) ) {
		$is_shipping_allowed = true;
	}
}

// make sure to restrict target shipping method if not allowed
if( ! $is_shipping_allowed ) {
	foreach( $rates as $rate_id => $rate ) {
		if( str_starts_with( $rate_id, 'local_pickup' ) ) {
			unset( $rates[ $rate_id ] );
		}
	}
}

If you’re struggling with how to use code snippets on your website, check this guide.

If you have any questions or suggestions, feel free to ask in the comments section below.

Misha Rudrastyh

Misha Rudrastyh

Hey guys and welcome to my website. For more than 15 years I've been doing my best to share with you some superb WordPress guides and tips for free.

Need some developer help? Contact me

Follow me on X