Blog

How to Restrict Free Shipping in Magento

How to Restrict Free Shipping in Magento

Online stores often offer free shipping to their customers. But what if you want to restrict free shipping to certain locations or minimum cart totals? We recently had to set up free shipping on orders over $50 to the continental U.S. (sorry Alaska and Hawaii) for a client. We'll show you how we did it using Magento, our open-source eCommerce platform of choice.

With Magento's built-in settings, you can achieve free shipping in one of two ways: the free shipping method, or free shipping using a specific carrier method.

The free shipping method simply gives the store owner the option to offer generic free shipping not specific to any carrier. This is equivalent to Amazon.com's Free Super Saver Shipping. The customer can select the free shipping option, and the store owner ships the order using whichever carrier and method they would like to use. This shipping option allows the store owner to set a minimum order total to qualify for free shipping.

Free shipping method screenshot
Free shipping method settings

The second built-in setting is carrier free shipping. Using this method, you can specify in a carrier's shipping settings which method (if any) should be free. Like the generic free shipping method above, you can set a minimum order total for the customer to qualify for free shipping. For example, if I use UPS to ship all of my orders, I'll go to the UPS shipping settings in the Magento System Configuration. I can then specify a free shipping method (such as Ground), and a minimum order requirement.

Free shipping option screenshot
Free shipping using carrier method settings

These two built-in free shipping settings may work well for many online stores, but some store owners would like to only offer free shipping to certain geographic regions. In our case, we were working with a client who wanted to restrict free shipping to the continental U.S due to the high cost of shipping to Alaska and Hawaii. Unfortunately, Magento's shipping settings do not allow restricting free shipping based on geography. Luckily, however, there's an easy way to create free shipping based on geographical regions using Magento's built-in shopping cart price rules."

Shopping cart price rules
To access Magento's shopping cart price rules, go to the "Promotions" menu.

Magento calculates shipping costs for carriers like FedEx and UPS based on zip codes. In order to achieve free shipping for specific geographical regions, you need to determine the set of zip codes associated with those regions. For our example, we wanted to provide free shipping to the U.S. excluding Alaska, Hawaii, and U.S. territories. So we did some research about U.S. zip codes, and formulated a set of rules to apply free shipping to only the continental U.S. In addition, we also set a minimum order amount of $50 in order to qualify for free shipping. Click on the "Conditions" tab to define these rules.

Geographical shipping conditions
This set of rules includes orders $50 or greater, shipped to the continental U.S.

To reiterate this, the set of all zip codes for locations in the continental U.S. (excluding of course Alaska, Hawaii, and U.S. territories) can be defined as follows:

  • Zip code is greater than 00900 but less than 96200
  • Zip code is equal to or greater than 97000 but less than 99500

Finally, you just need to define what will happen when the conditions are met. In this case, we want tp provide free shipping when the conditions are met (the location is within the continental U.S. and the order total is $50 or greater). To do this, we click on the "Actions" tab. Under the "Free shipping" setting, change it to "For shipment with matching items."

Free Shipping Actions
Set the action to include free shipping on qualifying orders.

Congrats! You now have free shipping set up for any order equal or exceeding $50 shipped within the continental United States. To check it, take a look at the cart's shipping estimate calculator.

Georgia shipping screnshot Alaska shipping screnshot
Compare the shipping estimates for Anchorage, Alaska and Atlanta, Georgia.

Creating your own rules

What if you want to provide free shipping to Alaska and Hawaii, but you don't want to provide it to some other region? You can apply the same technique for mapping and excluding certain zip codes. Check out this map and list for reference:

The first digit of the ZIP code is allocated as follows:

  • 0 = Connecticut (CT), Massachusetts (MA), Maine (ME), New Hampshire (NH), New Jersey (NJ), Puerto Rico (PR), Rhode Island (RI), Vermont (VT), Virgin Islands (VI), Army Post Office Europe (AE), Fleet Post Office Europe (AE)
  • 1 = Delaware (DE), New York (NY), Pennsylvania (PA)
  • 2 = District of Columbia (DC), Maryland (MD), North Carolina (NC), South Carolina (SC), Virginia (VA), West Virginia (WV)
  • 3 = Alabama (AL), Florida (FL), Georgia (GA), Mississippi (MS), Tennessee (TN), Army Post Office Americas (AA), Fleet Post Office Americas (AA)
  • 4 = Indiana (IN), Kentucky (KY), Michigan (MI), Ohio (OH)
  • 5 = Iowa (IA), Minnesota (MN), Montana (MT), North Dakota (ND), South Dakota (SD), Wisconsin (WI)
  • 6 = Illinois (IL), Kansas (KS), Missouri (MO), Nebraska (NE)
  • 7 = Arkansas (AR), Louisiana (LA), Oklahoma (OK), Texas (TX)
  • 8 = Arizona (AZ), Colorado (CO), Idaho (ID), New Mexico (NM), Nevada (NV), Utah (UT), Wyoming (WY)
  • 9 = Alaska (AK), American Samoa (AS), California (CA), Guam (GU), Hawaii (HI), Marshall Islands (MH), Federated States of Micronesia (FM), Northern Mariana Islands (MP), Oregon (OR), Palau (PW), Washington (WA), Army Post Office Pacific (AP), Fleet Post Office Pacific (AP)

Zip code map
Map of U.S. Zip Code allocation

Posted in:
DiggThis

Comments

Anonymous's picture

Awesome post. Ironically, I just set up similar rules 3 days ago but was glitching related to a problem where I want only certain products to have free shipping. Today, when I went to search the issue, your very well laid out post made my rules mess much easier. Thanks.

Isaac's picture

Glad I could help! I struggled for a while to figure out to define the free shipping rules. It was kinda of fun to forensically figure out the zip codes though.

Anonymous's picture

This article is exactly what I'm looking for, problem is I have checked my work 3 times and it does not work. Every time this rule is active it automatically applies FREE shipping to UPS ground no matter what the order value. (I set it to be $100 or more). I know it is set up right because if I enter a coupon CODE for this it works perfectly. If I remove the coupon code so it apples automatically I just defaults to FREE Shipping no matter what.

Any thoughts?

Isaac's picture

If you don't need to restrict by geography...
Simply using the built-in carrier settings with NO promotion rules:
1. Set your free shipping method to Ground (or whatever you want).
2. Set "free shipping with minimum order amount" to enabled.
3. Set "minimum order amount for free shipping" to 100.

If you DO need to restrict by geography...
In the built-in carrier settings:
1. Set your free shipping method to Ground (or whatever you want).
2. Set "free shipping with minimum order amount" to disabled.
3. Set "minimum order amount for free shipping" to 100.

And then set the promotional rule as defined in the article. Make sure you have the "subtitle is equal to or greater than 100" rule set in place.

Let me know if it's still not working for you.

Anonymous's picture

Barry, did you ever get this resolved? I'm having the exact issue right now. Thanks :)

Anonymous's picture

Outstanding post and quite helpful. Do you have any insight into the following scenario:

My client ships perishable goods and ground ships them within a 6 state region (ground gets there in a day or 2) however they have to 2nd day air shipto all other states to prevent spoilage. They want the shipping method based on the location of the shipment, but do not want to offer the customer a choice between the two. Can you set up rules to force a particular method based on location as well? I haven't been able to get my head around this one.

Isaac's picture

Hey Nate,

Magento does have the ability to only allow a shipping method for specific countries. It does not, however, have the built-in ability to only allow a shipping method for specific states or zip codes. Theoretically, I suppose it would be possible to tweak the module to pay attention to a different geographical region (like states or zip codes) instead of countries. I haven't tried this, but I think I remember seeing a third-party module that does this without affecting the core code.

I think the best solution to your problem is Magento's built-in table rate shipping module. With the table rate module you can specify a table of fixed rates for destination vs. weight, price, or number of items ordered. The owner then chooses whichever shipping method they would like to use, rather than being tied to a specific carrier. So for example, you could charge everybody in Kansas $10 shipping per item and everybody in Florida $15 shipping per item. Or instead you could charge the shipping rate by the weight of the order or the order total crossed with the destination.

You can see an article about how to set up table rate shipping here:
http://www.magentocommerce.com/knowledge-base/entry/how-do-i-set-up-tabl...

Anonymous's picture

Great post, this is a much easier and more elegant method than using table rates as the Magento team suggest.

One question though, why is it necessary to both exclude Alaska and Hawaii AND include all other zip codes? Shouldn't the Shipping State/Province is not Alaska and Shipping State/Province is not Hawaii be sufficient?

I'm going to do some testing now on this right now, but figured you had probably exhausted the possible scenarios, so maybe you have some insight regarding this already.

Isaac's picture

Thanks.

I included the zip code rules for two reasons: because it's more precise and because shipping for the carriers (i.e. UPS and FedEx) is based on zip code, not state. By explicitly including just the zip codes of the lower 48 states, no one will get free shipping if they aren't in the contiguous U.S. This effectively excludes Alaska and Hawaii, but also excludes all U.S. territories like Guam, Puerto Rico, etc. that have U.S. zip codes.

In this sense, the zip code rules are necessary and the state rules are redundant and therefore optional.

Anonymous's picture

Ah ha! I hadn't thought about US Outlying islands, thanks!

Anonymous's picture

Thanks again for the great tip, this is working perfectly for us.

In addition to offering free shipping over a certain threshold, we also offer flat rate shipping on all orders in the Continental US below that point. Any creative ideas on how we can limit that flat rate shipping option to the lower 48? Obviously that can't be done with the default flat rate module, and I can't think of a way to do it using the same method as this article.

I would like to continue using the standard UPS lookup based on package weight for air shipments, so I really don't want to go to table rates if it can be helped.

Isaac's picture

My best advice is to use table rate shipping alongside the standard UPS module. Without table rates only defined for the lower 48, the method will only show up for the lower 48. The FedEx module will show up for everybody and the customer can choose whichever shipping method is cheapest (or whichever they prefer).

Anonymous's picture

Ah, I didn't realize table rate shipping could live "alongside" other shipping methods, I thought it would show up as it's own shipping method during checkout.

Clearly I'll have to experiment with this in our development platform.

Thanks for the feedback!

Isaac's picture

No problem. The table rates do show up as their own shipping method, but it will show up in addition to any other shipping methods (like UPS). If the table rate isn't defined for a region, the shipping method shouldn't show up at all, but I haven't personally tested this. You can label this shipping method whatever you like. For example, you can call it "flat rate shipping" if you want.

Anonymous's picture

Yep, that's exactly what I was thinking, I'll configure it for flat rate shipping, and then if the destination is outside the lower 48, or the order total is over our free shipping limit it should remain hidden.

Thanks a bunch!

Jason

Anonymous's picture

Good job! THANKS! You guys do a great website, and have some great contents. Keep up the good work.
best regards,

Anonymous's picture

Thanks! great tutorial.

Anonymous's picture

Is there any way to setup a rule to disable the flat rate shipping option for items over X weight? Looks like a cart rule would be the best way to go about it, but it isn't one of the available actions that I can tell.

Isaac's picture

My only thought right now would be to use table rate shipping using weight versus location. That way you can specify a flat rate under a certain weight and a higher rate or no rate at all for over a certain weight.

Anonymous's picture

Your example is great but I noticed that it also makes the Flat Rate $0 as well. I want to do the same thing you are doing but only have FedEx Ground as the free option. Do you know any trick to do that?

Isaac's picture

Scott, yes, you can do this by setting the shipping method as a condition for the free shipping. So, the shopping cart price rule would say: "Shipping Method is not [flatrate] Fixed," or similarly, "Shipping method is [ups] Ground."

Alternatively, if you don't even want the flat-rate option to even appear for areas where the person qualifies for free shipping, you can set up the flat rate shipping using table rate shipping by geographical region. Wherever the table rate shipping isn't defined, that shipping option should not appear.

Anonymous's picture

Isaac, thank you so much. It totally solved my problem. I can't believe I didn't think of it! Go treat yourself to something nice today knowing you helped a stranger...

Isaac's picture

No problem, glad I could help!

Anonymous's picture

Im just starting up my new webshop, and are using a "give-away" auktion on FB to test the shop with real customers.

I have had 2 trades with very low bids going through. 1 and2 Euros.

Problem is, that the code I put in Magento does not calculate correct if the rebate (incl. tax) is to high according to the price before tax.

ie: normal price incl. tax 19,75 (ex 16,60) Rebate should be 17,75 to buy the product for 2 Euro as the lucky new customer just did. The system will only calculate the 16,6 as max rebate and the price is 3,15 instead of 2,00 Euro

Is there a way around this?
Can you help?
Thanks!! ;)

Isaac's picture

You might try increasing the discount to see what effect it has. The other possible problem I can think of a set minimum order. Go to System > Configuration and then click on the "Sales" tab. Under the "minimum order amount" section you can check to see if a minimum order amount is in place. If it is, turn it off. Other than that, you may need to play around with tax settings. I'm not familiar with Magneto's way of dealing with VAT/built-in tax.

Anonymous's picture

Hello Isaac
The system will only calculate the discount up to the price before tax...
... and tax setup for calculation... hmm!!

I'll just have to not sell products that cheep ;)
(What I did instead was to make a new product only with 1 pcs. on stock with no showings on any catagories - priced at the discounted price - and gave the winner the url for that product directly)

Thank you for your answer anyway!

Regards
Allan

Isaac's picture

Another way to accomplish this would be to suspend the tax rules for your product. You can set a specific tax class for each product. Then the "discount" price can simply include whatever tax you want.

Anonymous's picture

Hello Isaac

That solved my problem!!

Thank you very much :)

BR Allan

Anonymous's picture

Isaac, great job with this! This is exactly what I was looking for.

However, I am having issues setting up free shipping for orders over 100.00 (excluding Alaska and Hawaii). I followed the shopping cart price rules word for word, I have table rate shipping in place for all orders (This is a necessity), I have tried disabling the "Free Shipping" method in the configuration, and I have also tried disabling the UPS "Free shipping over..." rule. The results are either the "Free Shipping" method is available for all states, or for none. Do you have any possible suggestions as to what I could be doing wrong?

Thanks in advance!

Isaac's picture

Hey Jen,

If you're using table rate shipping as your only shipping method, you actually don't need the cart promotion rule. My method is useful when you want to use a method other than table rate shipping. You'll want to set the table rate shipping condition to "Price vs. Destination" in the table rate shipping configuration. Then in a CSV file (you can use Excel to edit CSV files), you can specify the shipping cost for combinations of locations and order totals. For orders over $100 in locations that you specify, you can specify the table rate as $0 in order to achieve free shipping. For more information on setting up table rate shipping, check this article:

Magento Knowledge Base | How Do I Set Up Table Rate Shipping?

Anonymous's picture

Hey Isaac,

Thanks for getting back to me so quickly. I didn't realize I could set this up with table rate shipping (Can you tell I'm new to Magento?). Thanks for your help!

Isaac's picture

Hey Jen, no problem- glad to see the Magento community is expanding.

Anonymous's picture

Cool article... worth it just for the zipcode map. How do I set up magento to not offer free shipping on certain products (based on sku, or whatever), but DO offer it for all of USA?

Isaac's picture

Hey Brian, all you need to do is add a rule to your free-shipping promotion that restricts the free shipping to a range of SKUs, product titles, or categories. If you want free shipping to apply to the whole order if one of the qualifying items is present, you need to put the rules in the "conditions" tab. If you only want the free shipping to apply for certain items, you'll have to specify the qualifying products in the action tab.

Anonymous's picture

Good post, my question is if you want to setup a coupon code to do the same thing. The coupon code is invalid unless a customer will actually using the shipping estimator box to state they are in one of qualifying states. So unless I say I am in NJ first, I cannot add the coupon code.

I would much prefer for the coupon code to be accepted at first, but either provide the free shipping price or not depending on if the customer qualifies.

Any ideas?

Isaac's picture

The problem comes from the declaration: "Shipping Country is United States"

You could probably remove that clause of the rule. I just included it for redundancy.

Or, if you're not comfortable removing that rule, you can create a conditions combination that says:

If ANY of these conditions are TRUE :
Shipping Country is United States
Shipping Country is ...

Essentially, what that says is, "if the shipping country is the United States or if it is not set, then [apply free shipping]." Obviously the shipping country must be set when the customer goes to check out, so there's no way to abuse this to get free shipping.

Anonymous's picture

I don't think this solves the problem...It would basically allow the coupon code to be accepted without having a country set...but then when a customer is checking out, if they are not in the US, they will get the option for free shipping.

The difference between what I'm trying to do and what you're doing in the post is that you are creating a rule without a coupon code...and that works great. If you try to do the same without a coupon code, it will require the user to set one of the requirements in order for the coupon code to be validated.

Isaac's picture

Hey Dave,

In order to checkout, the customer must set a country. By allowing them to apply free shipping without a country set, you're allowing them see a shipping quote. The real shipping cost should update once the real shipping address has been entered during checkout.

Anonymous's picture

Ahhh ok, I see what you mean now, makes complete sense! Thanks!

Anonymous's picture

Thanks for the great info!

Is there a way to setup the free shipping as an option a customer service rep using the admin tool can access, but a normal end user on the site won't see? Specifically, some business clients with a PO. Or perhaps a way to setup free shipping per customer?

Isaac's picture

Yes. I can think of two ways to do this. First, you can use coupon codes (see the 5 comments immediately above yours). If you don't want to use a coupon code, you can set the promotional rule to only take effect for a certain group of users such as "NOT LOGGED IN, General, Wholesale, Reseller." This setting is under the "Rule Information" tab when editing the promotion.

Anonymous's picture

Hi Isaac - Just wanted to say thanks. This is a brilliant solution, especially the zip code addition.

Post new comment

The content of this field is kept private and will not be shown publicly. If you have a Gravatar account, used to display your avatar.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options

CAPTCHA
The following question helps us prevent spam submissions.
1 + 2 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.