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        businessbloomer.com/woocommerce-customization
 * @sourcecode    https://businessbloomer.com/?p=309
 * @author        Rodolfo Melogli, Business Bloomer
 * @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        businessbloomer.com/woocommerce-customization
 * @sourcecode    https://businessbloomer.com/?p=309
 * @author        Rodolfo Melogli, Business Bloomer
 * @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

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 *