WooCommerce 2.6 – Hide shipping methods when FREE SHIPPING is available

[vc_cta h2=”The Below Code Works for the Following Plugins:”]

[/vc_cta]

WooCommerce 2.6 brings major changes in the shipping module including the introduction of Shipping Zone.
These changes break the number of existing snippets including the snippet to Hide shipping methods when FREE SHIPPING is available.

This is because of minor changes in the way $rates array is formed for the shipping method “Free Shipping”. Prior tored as $rates['free_shipping:shipping_zone_instance_id'] where shipping_zone_instance_id is the shipping zone instance id of the shipping method.
Means, if the instance id of shipping zone is 1, the rates array key will be free_shipping:1 and if instance id of shipping zone is 2, then the rates array key will be free_shipping:2 and so on.

Please refer

 

 

36 thoughts on “WooCommerce 2.6 – Hide shipping methods when FREE SHIPPING is available”

  1. Hello Vj,

    I need your help with this scenario.

    I have these shipping options:
    1. Free Shipping Above $50 Spent.
    2. Normal Shipping Below $50 Spent @ $5.
    3. Express Shipping @ $10.

    I would like Express Shipping option to be shown at all times. Free shipping to be shown only when the customer has more than $50 in the cart. It’s hidden and normal shipping is shown in its place when the cart has less than $50.

    Please help and advice :(((

    Thank you in advance!

    1. Hi @integratutions,

      You can use this code snippet to hide flat_rate 5$ when order cost is 50 or above. You’ll have to configure the flat rate ID and the free shipping ID.

      Let me know if you face any issues.

    2. Hello Lorenzo,

      Thank you for your quick reply. 🙂

      How do I check what’s my Free Shipping ID? I’m using Woocommerce 3.1.2. And the Free shipping settings pops up when clicked, not directed to a page where I can see the ID as it’s used to be done before. URL ends with &zone_id=1.

      Screenshots:
      https://cl.ly/0d0h3Z3b253b
      https://cl.ly/3E0J193x0G0q
      https://cl.ly/1e2k2B3d3m3b

      Another question is where do I set the Flat Rate ID? I can only see via the comment to set the Free Shipping ID. Here’s the edited code:

      // Hide shipping method(s) based on cart total.

      add_filter(‘woocommerce_package_rates’, ‘wf_remove_shipping_options_basedon_cart_total’, 10, 2);
      function wf_remove_shipping_options_basedon_cart_total($rates, $package){
      global $woocommerce;
      $order_total_limit = 50; //Set here limit of cart total
      $method_to_hide_when_cross_limit = array(
      ‘wf_shipping_ups:03’
      );

      $method_to_show_when_cross_limit = array(
      ‘free_shipping:1’, //config here exact free shipping key of you cart
      );

      $cart_total = WC()->cart->cart_contents_total;
      if ( $cart_total >= $order_total_limit ) {
      foreach ($method_to_hide_when_cross_limit as $shipping_method) {
      unset( $rates[$shipping_method] );
      }
      }else{
      foreach ($method_to_show_when_cross_limit as $shipping_method) {
      unset( $rates[$shipping_method] );
      }
      }
      return $rates;
      }

      Thank you so much. 🙂

    3. Hi @integratutions,

      To get the free shipping ID and Flat rate ID you need to go to the cart page and when the free shipping and flat rate shows up right click on the free shipping or flat rate and click on inspect, and the shipping method and ID will show in the details as the screenshot shown here https://snag.gy/sdZlDG.jpg

    4. Hello Lorenzo,

      Alrighty, I have gotten my flat rate ID(flat_rate:3) and free shipping ID(free_shipping:1), but something is still not correct and my flat rate 3 is still showing when the order amount is more than $50. My site is contactlens.sg, would you be able to have a look at my ID and code below to see what’s the mistake? Sorry for the trouble and really appreciate your patience and kind assistance. 🙂

      add_filter(‘woocommerce_package_rates’, ‘wf_remove_shipping_options_basedon_cart_total’, 10, 2);
      function wf_remove_shipping_options_basedon_cart_total($rates, $package){
      global $woocommerce;
      $order_total_limit = 50; //Set here limit of cart total
      $method_to_hide_when_cross_limit = array(
      ‘flat_rate:3’
      );

      $method_to_show_when_cross_limit = array(
      ‘free_shipping:1’, //config here excat freeshipping key of you cart
      );

      $cart_total = WC()->cart->cart_contents_total;
      if ( $cart_total >= $order_total_limit ) {
      foreach ($method_to_hide_when_cross_limit as $shipping_method) {
      unset( $rates[$shipping_method] );
      }
      }else{
      foreach ($method_to_show_when_cross_limit as $shipping_method) {
      unset( $rates[$shipping_method] );
      }
      }
      return $rates;
      }

    5. Hi @integratutions,

      Can you try using the flat rate ID as flat_rate without the post-fix :03, if you still face issues please raise a ticket in xadapter support and provide admin credentials to your site so that i can check.

  2. Good day! Is there a way hide specific shipping method when ALL products in cart with shipping classes? Thanks

  3. I have successfully applied this code to a site and it works. But what if im using real time UPS shipping rates and have GROUND UPS and 3 Day UPS as the shipping options and I want to show FREE SHIPPING but only remove the GROUND UPS option and still display the 3 day UPS option?

    SO if free shipping is available it would look like this:

    – FREE SHIPPING
    – 3day UPS $x.xx

    1. Hi Dave,
      You can achieve this by replacing ‘flate_rate’ with the id corresponding to 3 Day UPS.

    1. Hi Carl,
      You can achieve this by replacing ‘local_pickup’ and ‘free_shipping’ by ‘flat_rate’ in the above code and paste it in current themes functions.php

  4. Hi,

    Thank you for the code snippet! But I have a question on my logic.

    If order is less than 100 than flat rate and local pick up
    If order more than 100 free shipping and local pick up

    Can this logic work?

    1. Hi Jack,
      The code snippet will give only free shipping or local pickup if any one or both are available and will discard all other shipping options.

  5. Hi,

    Thank you for the code snippet! But I have a question.

    I use version 2.6 and when I add this code I get the following problem:

    Only local pickup is visible (not the paid shipping method) . Only orders > € 200,- will be delivered free.

    1. Hi Donny van der Kloot,
      Replace the following with
      if (‘free_shipping’ === $rate->method_id || ‘local_pickup’ === $rate->method_id) {
      this line
      if (‘free_shipping’ === $rate->method_id) {
      wil help you fix your issue. This will remove all shipping options if free shipping is available.

  6. I updated my woocommerce from 2.2 to 2.6 and copy & past the code in function.php file in theme folder. but it does not do anything. it shows both free shipping & other delivery option on the cart page. The function is not called.

    1. Make sure that you have copied the code to the current active theme’s functions.php file.

  7. Thanks!! it works”… flat rate when it should be, after a certain “amount” changes to free shipping, abd if the person insert the “adequate” postal code, the option changes to “local pickup”… but.. i think the most of us needs to show “at the same time” local pickup (if the postal code is in the region)..”and” the other option “flat rate and free shipping depending of the configuration each person wants..

    I use the code on 28/07 on 12:48 German time…

  8. Hi Elvin

    I tried it, and at first I thought it was working (it hides flat rate and keeps local pickup).

    But it seems to be hiding flat rate even when free shipping is not available? it only shows local pickup.

    1. Replace this code,
      if (‘free_shipping’ === $rate->method_id || ‘local_pickup’ === $rate->method_id) {
      $new_rates[$key] = $rates[$key];
      }
      with
      if (‘free_shipping’ === $rate->method_id) {
      $new_rates[$key] = $rates[$key];
      if( ‘local_pickup’ === $rate->method_id) {
      $new_rates[$key] = $rates[$key];
      }
      }

  9. Hi,

    I’ve looked at this snippet of code and others which aim to solve a similar problem. When I put this code and the suggested changes in my child theme’s functions.php file I’m not seeing the flat rate option disappear when the order value is greater than the limit set in the free rate.

    My aim is to hide the flat rate (paid delivery) option when the value of the order is > the value set in the free shipping option. This means that the site should always show 2 options.

    1. Local pick up
    2. Either “Free delivery” if order value >= threshold set in free delivery shipping option OR “Flat rate” if <the threshold.

    I've tried replacing the code line as indicated in one of the other replies. I've tried replacing it in both instances together and separately but the behavior of the system doesn't seem to change. It always shows all 3 optiions

    Thanks in anticipation

    1. Hi VJ,

      When you say “Updated code committed” what does this mean?

      I’ve tried using these two versions of code…

      add_filter(‘woocommerce_package_rates’, ‘xa_hide_shipping_rates_when_free_is_available’, 10, 2);
      function xa_hide_shipping_rates_when_free_is_available($rates, $package)
      {
      global $woocommerce;
      $version = “2.6”;
      if (version_compare($woocommerce->version, $version, “>=”)) {
      $new_rates = array();
      foreach($rates as $key => $rate) {
      if (‘free_shipping’ === $rate->method_id || ‘local_pickup’ === $rate->method_id) {
      $new_rates[$key] = $rates[$key];
      }
      }
      return $new_rates;
      }
      else {
      if (isset($rates[‘free_shipping’])) {
      // Below code is for unsetting single shipping method/option.
      $free_shipping = $rates[‘free_shipping’];
      if (isset($rates[‘local_pickup’])) {
      $local_pickup = $rates[‘local_pickup’];
      $rates = array(); // Unset all rates.
      $rates[‘local_pickup’] = $local_pickup; // Restore local pickup.
      $rates[‘free_shipping’] = $free_shipping; // Restore free shipping rate.
      }
      else {
      $rates = array(); // Unset all rates.
      $rates[‘free_shipping’] = $free_shipping; // Restore free shipping rate.
      }
      }
      }
      return $rates;
      }

      and this code

      add_filter(‘woocommerce_package_rates’, ‘xa_hide_shipping_rates_when_free_is_available’, 10, 2);
      function xa_hide_shipping_rates_when_free_is_available($rates, $package)
      {
      global $woocommerce;
      $version = “2.6”;
      if (version_compare($woocommerce->version, $version, “>=”)) {
      $new_rates = array();
      foreach($rates as $key => $rate) {
      if (‘free_shipping’ === $rate->method_id) {
      $new_rates[$key] = $rates[$key];
      if( ‘local_pickup’ === $rate->method_id) {
      $new_rates[$key] = $rates[$key];
      }
      }
      }
      return $new_rates;
      }
      else {
      if (isset($rates[‘free_shipping’])) {
      // Below code is for unsetting single shipping method/option.
      $free_shipping = $rates[‘free_shipping’];
      if (isset($rates[‘local_pickup’])) {
      $local_pickup = $rates[‘local_pickup’];
      $rates = array(); // Unset all rates.
      $rates[‘local_pickup’] = $local_pickup; // Restore local pickup.
      $rates[‘free_shipping’] = $free_shipping; // Restore free shipping rate.
      }
      else {
      $rates = array(); // Unset all rates.
      $rates[‘free_shipping’] = $free_shipping; // Restore free shipping rate.
      }
      }
      }
      return $rates;
      }

      In both cases I loose all shipping methods and instead get a message that shipping rates will be calculated once an address has been entered…

      For clarity and in simple terms what I think is required is something that does this.

      1. If Local pickup is set as an option then ALWAYS display local pickup AND
      2. If free shipping is available AND if the order value is >= the threshold amount set for free shipping then display free shipping ELSE
      3. Display Paid delivery

      = display 1 and either 2 or 3

      Thanks again in anticipation of a working solution (I wish I knew a bit more about how all this works :-))

      Russell

    2. Hi Russell,
      The code snippet is updated.
      It will show only free shipping and local pickup if both are available.
      If free shipping alone is available only free shipping will be shown.
      If local pickup alone is available only local pickup will be shown.
      If both free shipping and local pickup are not available then all the returned shipping options will be shown.

    3. Hi Elvin,

      Many thanks for your support with this but it’s still not doing what I expect and what I’m sure a lot of people would love to see…

      The behaviour that I’m seeing is:

      If free shipping is available show both free shipping and local pickup
      If free shipping is not available only show local pickup

      I think this is in line with your described behaviour above

      However, this is different than I have been asking for and I’m wondering if I’m guilty of hijacking a different question?

      There are three shipping options in woocommerce 2.6:1. Local pickup, 2. Flat rate and 3. Free delivery.

      Free delivery is configurable. I have 2 shipping zones WA14* and M33* WA14* is set to be free if>= 15 M33* is free if >= 20.

      If I create an order of <15 in my basket then in checkout I see only local pickup for both zones
      If I create an order of 17.5 then WA14* shows free delivery and local pickup. If I change the shipping address to M33* then I only see local pickup again.

      I am not seeing flat rate at all with this code.

      With an order value of 17.5 if I change from my billing address (which is WA14 5NH) to a different shipping address (such as M33 7PE) then I would expect the free delivery option to change to show the associated flat rate charge.

      You can see the site behaviour at arnies.co.uk

      I tried the patch that you suggested for Kramer but I got the same result

      Hope you can help please

      Regards
      Russell

    4. Hi Russell,
      The purpose of this code snippet is to hide the flat rate and other available shipping methods when free shipping is available. However it is been little modified to show local pickup too. If you want flat rate also comment the code snippet.

  10. Hi, the snippet works great, but how do we hide only the flat rate, but keep local pickup? Please help! Thanks

    1. You mean on line 25, replace $rates = array(); with unset($rates[‘flat_rate’]); ???

      Because I tried that and it doesn’t work?

    2. Hi Vj.

      All we’re trying to do is hide other shipping methods (normal flat rate) when free is available, BUT keep local pickup.

      If you could post a working snippet that can do this, that would be great!

      Thanks

    3. I have updated the code to give local pickup option along with free shipping option. Please use it.

  11. Its working correctly but i want to know one more thing that one more option is visible custom option below flat rate how to hide that actually i only want flat rate and free shipping

    1. Is there a way you can provide screenshot of shipping options shown cart page by sharing a link or so? That will help me to understand your question better.

Comments are closed.

Scroll to Top