WooCommerce: Limit Shipping to One State Only

WooCommerce allows you to limit shipping by countries (or “allowed” countries). However, say your business is based in Pennsylvania, USA (PA) or in one of the Australian states. You may want to limit shipping to a state only.

All you need is pasting the following code in your functions.php

WooCommerce: limit shipping to only 1 state

WooCommerce 3.0+ Snippet

Since WooCommerce 3.0, “get_shipping_state()” replaces “shipping_state” function:


/**
 * @snippet       Only ship to PA 
 * @how-to        Get CustomizeWoo.com FREE
 * @sourcecode    https://businessbloomer.com/?p=309
 * @author        Rodolfo Melogli
 * @testedwith    WooCommerce 3.2.1
 */

function bbloomer_only_ship_to_pa( $rates, $package ) {
global $woocommerce;
$excluded_states = array( 'AL','AK','AS','AZ','AR','CA','CO','CT','DE','DC','FL','FM','GA','GU','HI','ID','IL','IN','IA','KS','KY','LA','ME','MH','MD','MA','MI','MN','MS','MO','MT','NE','NV','NH','NJ','NM','NY','NC','ND','MP','OH','OK','OR','PW','PR','RI','SC','SD','TN','TX','UM','UT','VT','VA','VI','WA','WV','WI','WY' );
if( in_array( WC()->customer->get_shipping_state(), $excluded_states ) ) {
	$rates = array();
}
return $rates;
}

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

WooCommerce 2.1+ Snippet

woocommerce_available_shipping_methods has been replaced with woocommerce_package_rates.

If you’re targeting a different country, you will need to take a look at the woocommerce\i18n\states.php folder inside the plugin, and then find your desired country. If states are not there, please check https://docs.woocommerce.com/document/states-not-in-core/.


/**
 * @snippet       Only ship to PA WooCommerce 2.1+
 * @how-to        Get CustomizeWoo.com FREE
 * @sourcecode    https://businessbloomer.com/?p=309
 * @author        Rodolfo Melogli
 * @testedwith    WooCommerce 2.6
 */

function bbloomer_only_ship_to_pa( $rates, $package ) {
global $woocommerce;
$excluded_states = array( 'AL','AK','AS','AZ','AR','CA','CO','CT','DE','DC','FL','FM','GA','GU','HI','ID','IL','IN','IA','KS','KY','LA','ME','MH','MD','MA','MI','MN','MS','MO','MT','NE','NV','NH','NJ','NM','NY','NC','ND','MP','OH','OK','OR','PW','PR','RI','SC','SD','TN','TX','UM','UT','VT','VA','VI','WA','WV','WI','WY' );
if( in_array( WC()->customer->shipping_state, $excluded_states ) ) {
	$rates = array();
}
return $rates;
}

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

Up to WooCommerce 2.0


// Only ship to PA Woo 2.0

function only_ship_to_pa( $available_methods ) {
	global $woocommerce;
	$excluded_states = array( 'AL','AK','AS','AZ','AR','CA','CO','CT','DE','DC','FL','FM','GA','GU','HI','ID','IL','IN','IA','KS','KY','LA','ME','MH','MD','MA','MI','MN','MS','MO','MT','NE','NV','NH','NJ','NM','NY','NC','ND','MP','OH','OK','OR','PW','PR','RI','SC','SD','TN','TX','UM','UT','VT','VA','VI','WA','WV','WI','WY' );
 	if( in_array( $woocommerce->customer->get_shipping_state(), $excluded_states ) ) {
		// Empty the $available_methods array
		$available_methods = array();
	}
 	return $available_methods;
}
add_filter( 'woocommerce_available_shipping_methods', 'only_ship_to_pa', 10 );

Where to add custom code?

You should place custom PHP in functions.php and custom CSS in style.css of your child theme: where to place WooCommerce customization?

This code still works, unless you report otherwise. To exclude conflicts, temporarily switch to the Storefront theme, disable all plugins except WooCommerce, and test the snippet again: WooCommerce troubleshooting 101

Related content

  • WooCommerce: “You Only Need $$$ to Get Free Shipping!” @ Cart
    This is a very cool snippet that many of you should use to increase your average order value. Ecommerce customers who are near the “free shipping” threshold will try to add more products to the cart in order to qualify for free shipping. It’s pure psychology. Here’s how we show a simple message on the […]
  • WooCommerce: Cart and Checkout on the Same Page
    This is your ultimate guide – complete with shortcodes, snippets and workarounds – to completely skip the Cart page and have both cart table and checkout form on the same (Checkout) page. But first… why’d you want to do this? Well, if you sell high ticket products (i.e. on average, you sell no more than […]
  • WooCommerce: Disable Payment Method If Product Category @ Cart
    Today we take a look at the WooCommerce Checkout and specifically at how to disable a payment gateway (e.g. PayPal) if a specific product category is in the Cart. There are two tasks to code in this case: (1) based on all the products in the Cart, calculate the list of product categories in the […]
  • WooCommerce: Add Privacy Policy Checkbox @ Checkout
    Here’s a snippet regarding the checkout page. If you’ve been affected by GDPR, you will know you now need users to give you Privacy Policy consent. Or, you might need customer to acknowledge special shipping requirements for example. So, how do we display an additional tick box on the Checkout page (together with the existing […]
  • WooCommerce: Redirect to Custom Thank you Page
    How can you redirect customers to a beautifully looking, custom, thank you page? Thankfully you can add some PHP code to your functions.php or install a simple plugin and define a redirect to a custom WordPress page (as opposed to the default order-received endpoint). This is a great way for you to add specific up-sells, […]

Rodolfo Melogli

Business Bloomer Founder

Author, WooCommerce expert and WordCamp speaker, Rodolfo has worked as an independent WooCommerce freelancer since 2011. His goal is to help entrepreneurs and developers overcome their WooCommerce nightmares. Rodolfo loves travelling, chasing tennis & soccer balls and, of course, wood fired oven pizza. Follow @rmelogli

36 thoughts on “WooCommerce: Limit Shipping to One State Only

  1. Hey,

    I just try using this with woocommerce 3.2.1 and there is an error

    <b>Notice</b>: shipping_state was called <strong>incorrectly</strong>. Customer properties should not be accessed directly...
    1. You’re right Raul! Snippet updated πŸ™‚

      1. Hi,

        I’m trying to set your snippets to exclude canadian provinces except one for shipping (but not for invoicing) and it’s not working. Does your snippet work with WC4+ ?

        Thanks

        1. It should, yes. Try with no other plugins but Woo and 2020 theme. If it doesn’t work, make sure you know the correct state codes. If it doesn’t work then, get back to me please

  2. Hi,

    Thanks for the tutorial. How do I restrict shipping to selected cites within a state. I tried WooCommerce Advanced Shipping but didn’t get it. Kindly help.

    Moyie

    1. Hey Moyie, thanks for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R

  3. Is there anyway to replace ‘Select an option’ with a state name from woocommerce checkou page (billing_state field). Also needed to show other text when click the select box

  4. Hello! Thank you for the snippet! What codes should I use for other countries than USA? Where I can find them?

    1. Bogdan, thanks for the great question! You will need to take a look at the woocommerce\i18n\states.php folder inside the plugin, and then find your desired country. If states are not there, please check https://docs.woocommerce.com/document/states-not-in-core/. Hope this helps!

  5. Think my question’s the same as Kevin’s – trying to show all states in the billing state selector upon checkout, and only select ones under shipping. Currently it seems custom_woocommerce_states and woocommerce_countries_shipping_country_states effects both select boxes. Any way to do this?

    1. Thanks for your feedback Rick! Much appreciated πŸ™‚ I also wrote this a while ago: https://businessbloomer.com/woocommerce-limit-state-dropdowns-one-state/ – I wonder if that might help?

  6. Hello, can I remove some states from shipping state dropdown? this for only shipping dropdown so not will affect on billing state drop down

    1. Hi Kamrul, thanks for your message. Please check this other post I wrote, it should help you πŸ™‚

  7. I can get only certain States to show. But I want all US States to show for billing and then only certain states to show for shipping.

    1. Hey Kevin, thanks for your inquiry! I took a look at your code and it’s not the same as mine – please use my code and then let me know if it works πŸ™‚ Thank you!

      1. Hi, I am trying to restrict not only the cities in a country, but also different areas, as I am working with local shop delivering only to certain areas in the city. Is this possible in Woocommerce and how? Thank you in advance

        1. Donka, thanks so much for your feedback! Yes, this is possible – but unfortunately this is custom work and I cannot provide this solution on the blog right now. If you would like to get a quote, feel free to go here. Thank you! R

  8. Hi there. Thanks for the woo snippet! I’ve been setting up an online shop for a Pizzeria and it was critical for the shop to restrict the shipping zone within a single state in my country, which by the way is Brazil. The snippet worked out of the box, so far I’m on WC 2.3.8.

    1. Thank you for the feedback Adriano!

  9. Hey there, we need to restrict specific states for certain products. Do you know how that modification should work? Thanks

    1. Thanks for your comment Adam!

      Yes, this will require a more complicated PHP coding. It would be interesting to understand whether your website allows more than 1 product in the cart or not… If there are 2 products with different restrictions, how is that going to work?

      So, I think you’ll first need to force 1 product in the cart max. After that, you’ll need to check what product is in the cart and according to its restrictions, apply a similar code from this post.

      Does this make sense to you? πŸ™‚

  10. So I have ended up with that code:

    function only_ship_to_continental( $rates, $package ) {

    global $woocommerce;

    $excluded_states = array( ‘AK’,’HI’,’GU’,’PR’,’AA’,’AE’,’AP’,’AS’,’MP’,’UM’,’VI’ );

    if( in_array( WC()->customer->shipping_state, $excluded_states ) ) {
    $rates = array();
    }

    return $rates;
    }

    add_filter( ‘woocommerce_package_rates’, ‘only_ship_to_continental’, 10, 2 );

    but somehow Armed Forces (AA) are not excluded :\

    1. Ok cool. Strange about AA πŸ™‚

  11. Not sure if I understand this – excluded states always are going to be on a drop down, but rejected during the checkout process?

    1. Yes, basically the dropdowns will still have the states but if you select the wrong one it will give you “There doesnβ€˜t seem to be any available shipping methods. Please double check your address, or contact us if you need any help.”

      Try this code instead; it will delete all states in the dropdown but PA – you can edit it and modify as you wish:

      
      // Only one state e.g. PA in US
      
      add_filter( 'woocommerce_states', 'custom_woocommerce_states' );
      
      function custom_woocommerce_states( $states ) {
      $states['US'] = array(
      'PA' => 'Pennsylvania',
      );
      return $states;
      }
      
      
      1. Is there any way to adjust error message? I’m getting “Invalid shipping method.” which is kind of confusing when excluded state was selected

        1. If you see my previous comment, I gave you some code to completely remove states from the dropdown πŸ™‚

          Anyway, that error is weird, you should get “There doesn’t seem to be any available shipping methods. Please double check your address, or contact us if you need any help.” instead. Have you properly set up Woocommerce and said you ship to US?

          1. OK – I have that message under “S&H” section (sidebar).

  12. @Rodolfo

    Yes – that code version. It looks like WooCommerce has changed hooks or something to them in 2.2.x so is no longer compatible. I will try to find solution.

    1. Well, the big change was in Woo 2.1 and I don’t think they changed the filter again πŸ™‚ Can you copy/paste your code here so that I can take a look?

      1. function only_ship_to_continental( $rates, $package ) {
        global $woocommerce;
        $excluded_states = array( ‘AK’,’HI’,’GU’,’PR’ );
        if( in_array( WC()->customer->shipping_state, $excluded_states ) ) {
        $rates = array();
        }
        return $rates;
        }

        add_filter( ‘woocommerce_package_rates’, ‘only_ship_to_continental’, 10, 2 );

  13. Not working with 2.2.11

    1. Thanks for your feedback! Did you use the code “Woocommerce 2.1+”?

  14. I tried it but did not work. Any other suggestions.

    1. Thanks for your feedback πŸ™‚ What version of Woocommerce are you using?

Questions? Feedback? Customization? Leave your comment now!
_____

If you are writing code, please wrap it like so: [php]code_here[/php]. Failure to complying with this, as well as going off topic or not using the English language will result in comment disapproval. You should expect a reply in about 2 weeks - this is a popular blog but I need to get paid work done first. Please consider joining the Business Bloomer Club to get quick WooCommerce support. Thank you!

Your email address will not be published. Required fields are marked *