Shipping: Limit States, not just Countries?

Is there a way to limit which states can order, not just which countries can order? My client wants to allow online ordering to certain shipping states, but require phone orders for the rest, so it would be very helpful to just block those states from ordering and getting confused in the first place.

  • Patrick
    • Support Monkey

    Hi there Joshua

    I hope you had a great weekend!

    I believe the following function should still work in the current version of MarketPress, from this post:

    Add the abbreviations of any states you want to block from online orders to the array, and change the error message to whatever suits best.

    add_action( 'mp_shipping_process', 'force_states');
    function force_states() {
     global $mp;
     if (!in_array($_POST['state'], array('CA', 'NV', 'OR'))) {
      $mp->cart_checkout_error('Sorry, we only accept phone orders from that state.');

    You can add it to your theme's functions.php file or with a code snippets plugin like this one:

  • Patrick
    • Support Monkey

    Hi again Joshua

    Yeah, I've tried to get that little function to work too, but no joy. I'm currently picking the brains of some of our better coders to see if we can get this updated for current MarketPress.

    There is another simple, but hacky, solution: remove the states from the array in the plugin file so they won't even be available for selection at checkout. However, as that is an edit of a plugin file, it would need to be done every time you update the plugin.

    If you want to try that way, the file is marketpress-ecommerce-3.2.2/marketpress/includes/common/data.php at line 502.

  • Patrick
    • Support Monkey


    Update - We got progress. :slight_smile:

    This snippet works to trigger the custom error message if any of the "forbidden" states are selected, but only after the buyer has entered all info and clicked the submit-order button. We're trying to get it to trigger at the previous step when they submit the shipping info.

    I'll keep you posted on that, but you can test the code on your site in the meantime... it works on my test site here:

    add_action( 'mp_can_checkout', function( $val, $MP_Checkout, $cart, $billing_info, $shipping_info ){
      if( is_array( $shipping_info ) && isset( $shipping_info['state'] ) ){
    	$phone_order_states = array( 'CA', 'NV', 'OR' );
    	if( in_array( $shipping_info['state'], $phone_order_states ) ){
    	  mp_checkout()->add_error( 'Sorry, we only accept phone orders from that state.', 'order-review-payment' );
    	  return false;
      return $val;
    }, 10, 5 );
  • Joshua
    • Flash Drive

    I was having trouble getting this to work on my site like on yours, but then I discovered that the problem is when it's a credit card payment (Stripe in my case). It will still go through. I used manual payment and it worked as expected. Any way to get this to work with the Stripe gateway (I'm guessing if you're able to get the logic to happen pre-checkout like you wanted, it will solve both issues at once). Thanks for your help!

  • Patrick
    • Support Monkey

    Hi again Joshua

    We got results!

    The following snippet works like a charm on my test site, and stops the checkout process before getting to the payment step if a forbidden state is entered in the checkout form:

    And you have indicated that the important info here is the ship-to state. So if the buyer enters a shipping address that is different than the billing address, the code will check the shipping address. If the state in that address is on the "forbidden" list, the form will display the error message and will not continue until/unless the buyer goes back one step and changes the ship-to state to an accepted one.

    Add the standard abbreviations for whichever states should be disallowed to the forbidden_states array in the code below. And you can customize the error message that displays by editing the contents of error_title and error_msg.

    Have fun! :slight_smile:

    add_action( 'wp_footer', function(){
      if( ! mp_is_shop_page( 'checkout' ) ) return;
    	<script type="text/javascript">
    	  $( document ).ready( function(){
    		var wpmudev_mp_on_next_step = function( e ){
    		  $( '.forbidden_states_msg' ).remove();
    		  var OK_TO_GO = true;
    		  if( $( '[name="billing[state]"]' ).length ){
    			var forbidden_states = new Array( 'CA', 'NV', 'OR' );
    			var state = $( '[name="billing[state]"]' );
    			var diff_shipping = $( '[name="enable_shipping_address"]' ).attr('checked');
    			if( diff_shipping && $( '[name="shipping[state]"]' ).length ){
    			  state = $( '[name="shipping[state]"]' );
    			var length = forbidden_states.length;
    			for(var i = 0; i < length; i++) {
    			  if(forbidden_states[i] == state.val()){
    				OK_TO_GO = false;
    				$error_title = '<h4 class="mp_sub_title">Oops, sorry!</h4>';
    				$error_msg = '<ul>We only accept phone orders from that state.</ul>';
    				$( this ).before( '<div class="mp_checkout_section_errors show forbidden_states_msg"> ' + $error_title + $error_msg + '</div>' );
    		  if( OK_TO_GO ){
    			$( this ).unbind( 'click', wpmudev_mp_on_next_step );
    		$( '.mp_button-checkout-next-step' ).bind( 'click', wpmudev_mp_on_next_step );
    		$( '.mp_checkout_section_heading-link' ).on( 'click', function(){
    		  $( '.mp_button-checkout-next-step' ).bind( 'click', wpmudev_mp_on_next_step );
    }, 10 );

Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.