Black Friday & Cyber Monday SUPER SALE ALL WEEK:
Grab 40% OFF on plugins
Days
Hours
Minutes
Seconds

How to Hide a Shipping Method Based on Product and State in WooCommerce?

WooCommerce provides an option of shipping classes, which can be used to set shipping rules for individual products. But sometimes this may not be enough. Imagine a case where you want to hide a shipping method for a particular product if the customer is from a specific state. This is not possible out of the box in WooCommerce.

This post helps you to hide a shipping method based on product and state in WooCommerce.

Where to Add Custom Code in WooCommerce?

It is advisable to add the code snippets to the functions.php file of your child theme. Access the file directly from Appearance->Theme File Editor->Locating the child theme’s functions.php from the right sidebar. You can also access it from your theme’s directory file. Insert the following code snippet in functions.php. The alternative & easy option is to install & activate the Code Snippets plugin. You can then add the code as a new snippet via the plugin.

Preliminary Steps

1. Create a shipping class (e.g. Electronic products) from WooCommerce->Settings->Shipping->Shipping classes->Add shipping class

How to Hide a Shipping Method Based on Product and State in WooCommerce? - Tyche Softwares

2. Assign the products to the shipping class you have created from Products->Select a product->Under product data->Select shipping-> Choose the Shipping class.

How to Hide a Shipping Method Based on Product and State in WooCommerce? - Tyche Softwares

3. Find the shipping class ID from WooCommerce->Settings->Shipping->Shipping classes->Right-click on the shipping class name-> Select Inspect->Developer tools. (e.g. Shipping Class ID of Electronic product is: 56)

How to Hide a Shipping Method Based on Product and State in WooCommerce? - Tyche Softwares

4. Find the shipping method ID from -> Right-click on the Shipping method->Select Inspect->Developer tools (e.g. of Free Shipping method ID is: “free_shipping:35”).

How to Hide a Shipping Method Based on Product and State in WooCommerce? - Tyche Softwares

Solution: Hide a Shipping Method based on Product and State in WooCommerce

Let’s consider an online store targeting customers in a particular region, such as ‘New York’ in the United States. The implementation of the below code hides ‘Free Shipping’ when the customer selects the shipping state as ‘New York’ and if the selected product matches the ID of the shipping class ‘Electronic products’. For the demonstration of output, I have assigned the product “Sony 32 Inch LED Television” to the class “Electronic products”.

add_filter('woocommerce_package_rates', 'ts_restrict_shipping_for_product', 10, 2);

function ts_restrict_shipping_for_product($rates, $package) {
    $shipping_class_target = 56; // Replace with your desired shipping class ID
    $in_cart = false;

    // Check if the specific shipping class product is in the cart
    foreach (WC()->cart->get_cart_contents() as $key => $values) {
        if ($values['data']->get_shipping_class_id() == $shipping_class_target) {
            $in_cart = true;
            break;
        }
    }

    // Check the shipping destination
    $shipping_state = WC()->customer->get_shipping_state();
    $shipping_country = WC()->customer->get_shipping_country();

    // Modify shipping rates based on conditions
    if ($in_cart) {
        // If the specific product is in the cart
        if ($shipping_country === 'US' && $shipping_state !== 'NY') {
            // Shipping is only allowed to New York
            // You can customize this part to handle the action you want (e.g., display an error message)
            wc_add_notice('Sorry, you can only purchase this product for shipping to New York.', 'error');
            // Remove all shipping rates to prevent checkout for other states
            $rates = array();
        }
        
        // Hide free shipping for the specific product
        if (isset($rates['free_shipping:35'])) { // Replace 'free_shipping:35' with the actual shipping method ID
            unset($rates['free_shipping:35']);
        }
    }

    return $rates;
}

Output 

Scenario 1

Let’s consider that a customer adds the “Hamilton Kettle”  product that doesn’t belong to the class “Electronic products” and selects the state “California”. So, no restrictions are applied either to hide the shipping method or regions.

How to Hide a Shipping Method Based on Product and State in WooCommerce? - Tyche Softwares

Scenario 2

When a customer adds a “Sony 32 Inch LED Television” belonging to the class “Electronic products” class to their cart and selects the state NewYork, the code removes the ‘Free Shipping’ option. As per the code, both the conditions are met and hence we got the intended result as shown below.

How to Hide a Shipping Method Based on Product and State in WooCommerce? - Tyche Softwares

Scenario 3

Though the product in the cart belongs to the class “Electronic products” & if any state other than ‘New York’ is selected, it shows an error message as shown below.

How to Hide a Shipping Method Based on Product and State in WooCommerce? - Tyche Softwares

Even if the customer proceeds from the cart page to the checkout page, the error message remains, and no shipping options are available.

How to Hide a Shipping Method Based on Product and State in WooCommerce? - Tyche Softwares

Code Explanation

  • The add filter function attaches a custom function, ‘ts_restrict_shipping_for_product,’ to the hook named woocommerce_package_rates. This function modifies shipping rates during WooCommerce checkout based on specific conditions.
  • Defining the function ts_restrict_shipping_for_product($rates, $package). 
  • $shipping_class_target = 56; This line defines the ID of the shipping class you want to apply restrictions. You should replace 56 with the actual ID of the shipping class you want to target.
  • The foreach loop iterates through the items in the shopping cart.
  • It checks if any product in the cart has a shipping class ID matching the $shipping_class_target.
  • If such a product is found, it sets $in_cart to true and breaks out of the loop.
  • These lines retrieve the shipping state and country information for the customer.
    • $shipping_state = WC()->customer->get_shipping_state();
    • $shipping_country = WC()->customer->get_shipping_country();
  • The code inside the if ($in_cart) { … } block checks if the specific product is in the cart.
  • If the product is in the cart, it further checks if the shipping destination is within the United States (‘US’) but not in New York (‘NY’).
  • If the conditions are met, it adds an error notice to inform the customer that they can only purchase the product for shipping to New York, and it removes all shipping rates to prevent checkout for other states.
  • It checks if the “Free Shipping” method with the ID ‘free_shipping:35’ exists in the $rates array.
  • If it exists, it removes it from the array using unset(). You should replace ‘free_shipping:35’ with the actual shipping method ID you want to hide.

Conclusion

The code helps you to hide specific shipping methods based on product and state. Aside location, you can also hide specific shipping methods for certain conditions based on order weight, order total, and product quantity.

Let us know your feedback on how the code was useful or any other queries in the comments section.

Browse more in: Code Snippets, WooCommerce How Tos, WooCommerce Tutorials

Share It:

Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x