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        Watch tutorial @ https://businessbloomer.com/?p=19055
 * @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        Watch tutorial @ https://businessbloomer.com/?p=19055
 * @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 this code?

You can place PHP snippets at the bottom of your child theme functions.php file (before "?>" if you have it). CSS, on the other hand, goes in your child theme style.css file. Make sure you know what you are doing when editing such delicate files - if you need more guidance, please take a look at my free WooCommerce Customization video tutorial.

Does this snippet still work?

Please let me know in the comments if everything worked as expected. I would be happy to revise the snippet if you report otherwise (please provide screenshots). I have tested this code with Storefront theme, the WooCommerce version listed above and a WordPress-friendly hosting on PHP 7.

If you think this code saved you time & money, please join other Business Bloomer supporters and avail of 365 days of WooCommerce benefits. Thank you in advance :)

Need Help with WooCommerce?

Check out these free videos, tutorials and tips!

  • how-to-edit-woocommerce-with-php-snippets
  • woocommerce-hooks-add_action-list-visual
  • woocommerce-customize-single-product-page-PHP
  • woocommerce-customize-shop-page-PHP
  • woocommerce-advanced-customization
  • how-to-edit-woocommerce-cart
  • woocommerce-customize-checkout-page-PHP
  • woocommerce-email-customization
  • woocommerce-conditional-logic

Rodolfo Melogli

Author, WooCommerce expert and WordCamp speaker, Rodolfo has worked as a 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.

34 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 πŸ™‚

  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

    1. Hey Amir, thanks for your comment! You could set the default State: https://businessbloomer.com/woocommerce-set-default-state-checkout-page/

  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!

    2. 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

    3. 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;
      }
      
      
    2. Is there any way to adjust error message? I’m getting “Invalid shipping method.” which is kind of confusing when excluded state was selected

    3. 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?

    4. 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?

    2. 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? Support? Leave your Comment Now!
_____

If you are writing code, please wrap it between: [php]code_here[/php]. Failure to complying with this (as well as going off topic) will result in comment deletion. You should expect a reply in about a week - this is a popular blog but I need to get paid work done first. Please consider joining #BloomerArmada to ask me 1-to-1 WooCommerce questions. Thank you :)

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.