WooCommerce: Hide Shipping If Local Pickup Is Selected

Let’s talk about checkout UX: if a user is willing to pick up the item in store, why should there be a shipping form on the checkout?

Well, let’s see how we can hide this dynamically with a bit of PHP and JS!

WooCommerce: disable shipping if local pickup is chosen @ Cart or Checkout

PHP Snippet: Hide Shipping Fields When Local Pickup is Selected – WooCommerce Checkout

/**
 * @snippet       Hide Shipping Fields for Local Pickup
 * @how-to        Get CustomizeWoo.com FREE
 * @sourcecode    https://businessbloomer.com/?p=72660
 * @author        Rodolfo Melogli
 * @testedwith    WooCommerce 3.5.7
 * @donate $9     https://businessbloomer.com/bloomer-armada/
 */
  
add_action( 'woocommerce_after_checkout_form', 'bbloomer_disable_shipping_local_pickup' );
 
function bbloomer_disable_shipping_local_pickup( $available_gateways ) {
	
	// Part 1: Hide shipping based on the static choice @ Cart
	// Note: "#customer_details .col-2" strictly depends on your theme

	$chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
	$chosen_shipping = $chosen_methods[0];
	if ( 0 === strpos( $chosen_shipping, 'local_pickup' ) ) {
	?>
		<script type="text/javascript">
			jQuery('#customer_details .col-2').fadeOut();
		</script>
	<?php  
	} 

	// Part 2: Hide shipping based on the dynamic choice @ Checkout
	// Note: "#customer_details .col-2" strictly depends on your theme

	?>
		<script type="text/javascript">
			jQuery('form.checkout').on('change','input[name^="shipping_method"]',function() {
				var val = jQuery( this ).val();
				if (val.match("^local_pickup")) {
							jQuery('#customer_details .col-2').fadeOut();
					} else {
					jQuery('#customer_details .col-2').fadeIn();
				}
			});
		</script>
	<?php
 
}

Where to add this snippet?

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 files - if you need more guidance, please take a look at my free video tutorial "Where to Place WooCommerce Customization?"

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 Customization?

Check out these free video tutorials. You can start learning how to customize WooCommerce without unnecessary plugins. Watch me code and learn by example!

  • how-to-edit-woocommerce-with-php-snippets
  • woocommerce-hooks-add_action-list-visual
  • woocommerce-customize-single-product-page-PHP

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.

82 thoughts on “WooCommerce: Hide Shipping If Local Pickup Is Selected

  1. Nice snippet. But from a UX perspective I see one issue: The annotations a customer can make are attached to the delivery address, because WooCommerce treats them as probably as additional information for the delivery. So when using the snippet the customer can’t enter notes anymore which might be relevant for pickup or the order itself. My customers often enter general information or feedback.

  2. What do I do if I want to apply this to a delivery option that is not local pickup? How do I identify the delivery method name to put in the code, in place of local_pickup ?

    1. Hello James, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  3. Thanks for the code. It’s working with Porto theme. Just had to change #customer_details .col-2 to .woocommerce-shipping-fields and it hides shipping section completely. Thanks again.

    1. Awesome!

  4. How about if I have more than one local pickup option?

    1. Hello Steve, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  5. Thanks working fine on latest updates on 14 July 2019.

    1. Great!

  6. Hi,
    many thanks for the snippet. However, I’m not displaying shipping options until the billing & shipping addresses are entered. Some customers enter shipping address (different from billing) and then still choose the local pickup option (which is free). So I’m more interested in reverse logic, i.e. hiding the local pickup option if ‘ship to a different address’ option is chosen by the customer. How could that be achieved?
    Thanks,
    Andrius

    1. Hi Andrius, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  7. This kind of works for me, I select local and other shipping methods disappear but they fade back in pretty much instantly as soon as Woo has reloaded the change.

    1. Hello Bert, sounds like a JavaScript conflict to me – maybe your theme (or another plugin) is messing/conflicting with my snippet?

      To troubleshoot, disable all plugins but WooCommerce and also switch temporarily to “Twentyseventeen” theme (load the snippet there in functions.php) – does it work? If yes, you have a problem with your current theme or one of the plugins.

      Hope this helps!

      R

  8. Hi,

    Thank you very much for your explanation. Your guides are awesome.

    I tried to apply the code and now all the shipping methods disappeared and I have only the local pick up options that set by default. There is no way to change it or to reverse it. Even when I deactivated the PHP snippet (and removed it too) + remove cache, the shipping method is not showing up again.

    I know it seems like it is not related to the code in your guide, but I 200% sure it is because few seconds before I added the code the other methods was there.

    How can i fix the issue pleaes?

    1. Try to empty your Cart first and then clear WooCommerce “sessions” from Status > Tools

  9. it worked!
    but u need to refresh the page in oreder to see the result
    HELP!!!!!!

  10. Thanks for all the help, this blog has helped me a lot. I have placed the code but it does not work. The CSS ID is correct, any ideas?

    1. Could be a jQuery error on your site, not sure. Still works for me, WC 3.5.7 & Storefront theme

  11. didnt work for me

  12. Thanks so much for this, super helpful!

    I found I had to change the input to a select field, took me ages to realise that was the issue!

    Sharing here in case it’s helpful to someone else:

    jQuery('form.checkout').on('change','select[name^="shipping_method"]',function() {
        var val = jQuery( this ).val();
        if (val.match("^local_pickup")) {
                    jQuery('.woocommerce-shipping-fields').fadeOut();
            } else {
                    jQuery('.woocommerce-shipping-fields').fadeIn();
        }
    });
    
    1. Thanks a mill Matt!

  13. Hello, thanks for the helpful snippet!
    It works well, however even though the shipping fields are hidden it still gives me an error that the shipping fields haven’t been filled.
    Is there a way also to dynamically disable the required attribute for the fields, aside for hiding them?

    1. Hi there, thanks for your comment! I just checked and I get no error, so maybe you have something wrong in the WooCommerce shipping settings such as “Default to customer shipping address”

  14. Works great (WP 5.0.3, WooCommerce 3.5.3). The problem is that in saved order this adress still is (in emails, too). I would like to see “Pinkup point” text. How can I do it?

    1. Hello Michal, thanks so much for your comment! Yes, this is possible – unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R

  15. Hi Rodolfo,

    I came on your website months ago and immediately bookmarked, so much good stuff here!

    I wasn’t sure what is best way to ask this so I’m commenting here as it is related to shipping.

    I always had biggest trouble finding best way to offer good shipping calculations on products, used few “real time” rates plugins and table rates plugins but could never find anything that works really good.
    Some products I could ship Free but some are heavier and need different methods, built in flat rate doesn’t seem to work good either and usually Free/Flat rate still show up as an option even when there are “heavier” products in the cart.

    Do you have a post describing possible solutions for shipping?
    Or what do you suggest?

    Much appreciated.

  16. Hi Rodolfo,

    I need some help on Woocommerce Shipping. I have 4 shipping options (Same day delivery, Delivery, Local Pickup at X, Local Pickup at Y). But when I go to the Cart page, it forces the user to first enter a Pin code and only then shows the 4 shipping options.

    What I want is, when the user adds the product to the Cart and goes to the Cart page, it should first ask the user as to whether he wants Delivery or Pickup and based on the user’s choice, should show the 2 Delivery options or the 2 Pickup options.

    Is this possible in Woocommerce?

    Thanks,

    Narayan

    1. Hello Narayan, thanks so much 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

  17. Hi Sir,
    I have a little question about a side-effect of your PHP Snippet: Hide Shipping Fields When Local Pickup is Selected โ€“ WooCommerce Checkout.
    It works well in the opened checkout page, however:
    When the user makes the choice for shipping, the shipping fields are there correctly. But when he (in his doubt) turns back to the choice of Local Pickup, the shipping fields remain visible. Only with a page refresh (browser reload) they are then hiding again.
    Woocommerce Shipping destination is set to Default to customer billing address

    Do you possibly know of any way to overcome this?

    Thank you in advance.
    With regards,
    DV

    1. Hello DV, thanks for your comment! The

      jQuery('#customer_details .col-2').fadeOut();

      should do exactly that, so custom troubleshooting might be needed. Sorry ๐Ÿ™‚

  18. Hi there,

    I’ve added this code and works fine, but my woocomerce still have the address as a mandatory field even for local pickup…

    So, I don’t have address fields but it ask for address.. any ideas?

    Thanks!

    1. Hey Javier, thanks for your comment! Maybe in the WooCommerce shipping settings you have “Default to customer shipping address”?

  19. Hi Rudolf,

    i use your snippet for disable/hide second shipping address. If the customer chose local pickup.
    Works fine, great!

    But, if i need hide/unset a billing_field, when a customer chose a certain payment_method?

    Thank you, and great work!

    1. Hey Jorge, thanks so much 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

    2. Hi Rodolfo,
      tel me,
      how and how much?

      1. Hey Jorge, thanks for your comment ๐Ÿ™‚ If you’d like to get a quote, feel free to contact me here. Thanks a lot!

  20. Hey Rodolfo,

    I think this may be related to the recent WC updates, I’m not sure if the snippet works correctly as it should.

    1. When the local pickup is selected, it correctly hides the shipping address fields as it should, but the shipping address field will remain a mandatory field, so it will trigger notice error upon the submission.

    2. Together with the shipping fields, it also hides the Order Notes field. Any way the Order Notes field could remain regardless of local pickup being selected? That field is quite important.

    1. Hey Joe, thanks for your comment! I just tested this and I cannot recreate the #1 error. If shipping is “closed” then billing details should be used by the order, so no validation should occur. Maybe you had a previously saved checkout? Try with another user on a fresh cart if possible.

      For the second issue, correct, I’m targeting the whole “col 2” of the checkout which contains the order notes as well. You can definitely specify a different HTML container (i.e. the one that contains the shipping only) and edit the snippet as you wish ๐Ÿ™‚

      Hope this helps!

    2. I have just encountered the same problem. “it correctly hides the shipping address fields as it should, but the shipping address field will remain a mandatory field”.
      Update to woocommerce 3.4.3 in the last days.
      Any ideas?

    3. Perhaps the .col2 should be changed to .woocommerce-shipping-fields by default in your snippet as this correctly hides the shipping fields but not the order notes.

      With regards to the second issue people are having, it could come from where shipping is selected, then ship/”deliver to a different address” selected followed by pickup selected again. So now mandatory fields are hidden as opposed to disabled.

      I was able to cause this problem to occur by selecting Local pickup -> Flat rate -> Ship to different address -> Local Pickup. Even with “Default to customer billing address” selected in the settings.

  21. I don’t know if this is related, but I’m having an issue where I select one shipping option in Cart it defaults to Local Pickup at checkout. Any ideas?

    1. Hey Jasmine, thanks so much for your comment! Honestly I doubt ๐Ÿ™‚ The best would be to test this snippet on a fresh install of WooCommerce with a different theme and no other plugins – let me know ๐Ÿ™‚

  22. Worked instantly!
    You could set the selector variable once so it is easier to adjust:

    $shippingSelector = '.woocommerce-shipping-fields';

    and then like this …

     jQuery('<?php echo $shippingSelector ?>').fadeOut(); 

    and also for the other parts where the selector is needed

    Thank you!

    1. Very nice Andreas ๐Ÿ™‚

  23. With the recent update of Storefront, I just had to re-upload the functions.php file with the snippet…no problem, but now I have a different issue, related to this section of the checkout, but not necessarily related to the snippet above itself…

    When I first designed my website in Sept, I had to do so much customization, and for the most part, I kept a good log of what I was doing and where I got the info from. There is one small bit of customization that, even though I’ve followed the notes I kept, I can’t get it to work…maybe you can help.

    The checkbox that shows after “Ship to a Different Address?”…which I have changed to “Delivery Information”, has been set as checked by default…but previously I was able to hide that checkbox entirely, but leave it set as checked by default. I was told, and it worked, to create a new folder: wp-content/themes/storefront/woocommerce/checkout and to upload a file to that folder, form-shipping.php…contents of that file are below. Can you give me any insight why this isn’t working now and why the checkbox is still showing? This is copied EXACTLY as I uploaded it in September…

    1. Ugh…sorry, forgot to wrap it…

      <?php
      /**
       * Checkout shipping information form
       *
       * This template can be overridden by copying it to yourtheme/woocommerce/checkout/form-shipping.php.
       *
       * HOWEVER, on occasion WooCommerce will need to update template files and you
       * (the theme developer) will need to copy the new files to your theme to
       * maintain compatibility. We try to do this as little as possible, but it does
       * happen. When this occurs the version of the template file will be bumped and
       * the readme will list any important changes.
       *
       * @see     https://docs.woocommerce.com/document/template-structure/
       * @author  WooThemes
       * @package WooCommerce/Templates
       * @version 3.0.9
       */
      
      if ( ! defined( 'ABSPATH' ) ) {
      	exit; // Exit if accessed directly
      }
      
      ?>
      <div class="woocommerce-shipping-fields">
      	<?php if ( true === WC()->cart->needs_shipping_address() ) : ?>
      
      		<h3 id="ship-to-different-address">
      			<label class="woocommerce-form__label woocommerce-form__label-for-checkbox checkbox">
      				<input id="ship-to-different-address-checkbox" class="woocommerce-form__input woocommerce-form__input-checkbox input-checkbox" <?php checked( apply_filters( 'woocommerce_ship_to_different_address_checked', 'shipping' === get_option( 'woocommerce_ship_to_destination' ) ? 1 : 0 ), 1 ); ?> type="checkbox" name="ship_to_different_address" value="1" /> <span><?php _e( 'Ship to a different address?', 'woocommerce' ); ?></span>
      			</label>
      		</h3>
      
      		<div class="shipping_address">
      
      			<?php do_action( 'woocommerce_before_checkout_shipping_form', $checkout ); ?>
      
      			<div class="woocommerce-shipping-fields__field-wrapper">
      				<?php
      					$fields = $checkout->get_checkout_fields( 'shipping' );
      
      					foreach ( $fields as $key => $field ) {
      						if ( isset( $field['country_field'], $fields[ $field['country_field'] ] ) ) {
      							$field['country'] = $checkout->get_value( $field['country_field'] );
      						}
      						woocommerce_form_field( $key, $field, $checkout->get_value( $key ) );
      					}
      				?>
      			</div>
      
      			<?php do_action( 'woocommerce_after_checkout_shipping_form', $checkout ); ?>
      
      		</div>
      
      	<?php endif; ?>
      </div>
      <div class="woocommerce-additional-fields">
      	<?php do_action( 'woocommerce_before_order_notes', $checkout ); ?>
      
      	<?php if ( apply_filters( 'woocommerce_enable_order_notes_field', 'yes' === get_option( 'woocommerce_enable_order_comments', 'yes' ) ) ) : ?>
      
      		<?php if ( ! WC()->cart->needs_shipping() || wc_ship_to_billing_address_only() ) : ?>
      
      			<h3><?php _e( 'Additional information', 'woocommerce' ); ?></h3>
      
      		<?php endif; ?>
      
      		<div class="woocommerce-additional-fields__field-wrapper">
      			<?php foreach ( $checkout->get_checkout_fields( 'order' ) as $key => $field ) : ?>
      				<?php woocommerce_form_field( $key, $field, $checkout->get_value( $key ) ); ?>
      			<?php endforeach; ?>
      		</div>
      
      	<?php endif; ?>
      
      	<?php do_action( 'woocommerce_after_order_notes', $checkout ); ?>
      </div>
      
      1. Steve, thanks so much for your comment! Unfortunately this looks like custom troubleshooting work and I cannot help here via the blog comments. Thanks a lot for your understanding! ~R

  24. Hello,
    I’ve added this to my child theme functions file but nothing happens.
    // Note: “#customer_details .col-2” strictly depends on your theme. – am I meant to change this to something that my theme uses? if so, how do I find it out?

    1. Hey Danny, thanks for your comment! If you give me your checkout URL I will tell you your custom CSS ID you need to use ๐Ÿ™‚

  25. Love your tutorials, Rodolfo!
    I’m working on a flower shop site as well, but I have 3 shipping zones, the town name, which has the option of free pickup or delivery for $10, local, which is a choice of zipcodes for $16, and outside local which is $20. The problem is, if someone isn’t signed in, the cart defaults to showing the $20 shipping. I just want to hide the shipping from the cart page, and only show it after the delivery location is typed in, or is there some better way to do this? Can you point me to another tutorial or plugin?

    Thanks!!

    1. Thanks for your comment Fran! You can hide the shipping calculations on the Cart page from the WooCommerce settings, if that’s what you meant ๐Ÿ™‚

  26. Thank you SO MUCH for this code snippet! I have a website for my flower shop and I’ve not been able to enable the pick up option because it still asked for shipping information during checkout. Now I can offer both delivery and pick up to my customers. Thanks again!

  27. Hello Rodolfo,

    Great snippet! Thanks you.
    I also added “add_filter( ‘woocommerce_shipping_chosen_method’, ‘__return_false’, 99);” to remove default shipping.
    But… is there way to validate “if shipping is selected” and show “No shipping was selected…” error in cart to prevent go to checkout? I think all this, could make a sense according to your snippet.
    Thanks you
    Tom

    1. Hey Tom, thanks so much 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

  28. Hi there, great work.

    I’m forcing some categories to have only local_pickup via “WooCommerce Conditional Shipping and Payments” plugin, so if some product is from that category, no other shipping method is shown and local_pickup is applied.

    Anyway in the checkout page, the form for introducing alternative shipping address is still showing up. I’ve tried using your code, but it looks it does nothing. Any idea?

    I’ve tried several alternatives, but with no result.
    Thanks

    1. Hola Ivan, thanks so much 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

  29. What if the .fadeOut() fields are required for the order form? How can I also exclude them from the form validation?

    1. Hey Petros, thanks so much for your comment! Shipping fields shouldn’t be required as long as billing has been filled out. What fields are you talking about in your example?

  30. Don’t think it hides shipping on WordPress Version 4.8.3 + WooCommerce Version 3.2.1

    1. Sorry got it working in storefront….. need to work out what to do for flatsome theme

    2. Flatsome = #customer_details .woocommerce-shipping-fields

      Cheers my friend

      1. Thank you Clint ๐Ÿ™‚

    3. Thank you! Worked here with Flatsome theme too.

  31. as you code doesnt work with latest version

    1. Satish, thanks for your comment! Other people are reporting otherwise. Can you try it with a default/different theme please?

  32. Works 100% .. thank you Rodolfo, you’re a Legend!

  33. I am using Shopkeeper-child theme. Tried the snippet but does nothing. DO I need to change something in the snippet for this theme?
    Thanks,
    Allen

    1. Allen, thanks for your comment! The snippet targets the shipping

      with CSS class “#customer_details .col-2”. So, yes, you’d have to see what custom class you have and change it for your own theme ๐Ÿ™‚
  34. I agree with this snippet, except I can see time when I would like to leave the note available
    in which case you will need to modify your code to .woocommerce-shipping-fields.

    1. Cheers for the feedback John ๐Ÿ™‚

  35. I had to change
    if (val.match(“^local_pickup”)) {
    to
    if (val.match(/local_pickup/)) {

  36. Hello Rodolfo,

    Great snippet!

    We are using another ‘Local pick up’ plugin.
    Can we establish the same for this plugin?

    See attachment: https://rocket.bjctools.nl/shipping.png

    1. Hey Luuk, yes, I’m sure this can be done ๐Ÿ™‚

  37. Hey, you posted this at the right time!

    But what I’d like to know is how to remove the flat rate shipping option when a user qualifies for free shipping.

    Right now to qualify for free shipping the order total must be > $49, but when a user goes above this amount the cart/checkout shows two options, ‘Free’ and ‘Flat rate $2.99’ which is silly and redundant since the user will always be happy with Free.

    But anyway, how do I remove the flat rate option when Free shipping criteria is met? It seems like a big oversight on Woocommerce’s part.

    Screenshot for reference: http://imgur.com/a/rFW6e

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 *