Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'm currently setting up a woocommerce driven shop.

I use the fedex shipping calc. extension to get the shipping costs calculated.

I wanna ship all items that are under 200$ for free. never mind if the cart total is above the 200$. Means you can add 4 or 6 or never mind how much items to the cart if each of the items is below the 200$ the shipping is free.

So what I did is I have set all that (below 200$)items up as "virtual" items. That way they skip the fedex shipping calc.

The problem is that I also wanna offer LOCAL PICKUP as a shipping option. But customers are not able to select that option if they have virtual items only in their cart.

Is there a way to enable the local pickup option anyway?

Or is there a smarter solution to get that idea done?


i have also tried to the following:

  1. I have created a special shipping class named it "free shipping".

  2. I have disabled the "virtual" option for one of the items wich has a price below the 200$. And i added that "special class "free shipping" to that item.

  3. I have then activated the FLAT RATE shipping method and set the shipping cost on that to 0.00

  4. I told that FLAT RATE shipping option to be active for my previously generated class (free shipping) only.

  5. I renamed the option from FLAT RATE to FREE SHIPPING so that it is listed as FREE SHIPPING on the checkout page

  6. So far so good, now if i add that item to the basket i see both options the FREE SHIPPING (the original flat rate i have renamed) and the "LOCAL PICKUP" option.

so far so good. that works fine ...

the problem is as soon as i add an another item to the cart with an price over 200$ fedex take affect and will calculate the shipping cost and a few fedex options are displayed.

i also see the local pickup BUT AND THAT IS THE PROBLEM I ALSO SEE THE FREE SHIPPING OPTION CUZ THE the item i have given the special class is still in the basket.

means people are able to select free shipping and that is not what i am looking for. As soon as a item with a price of over 200$ is in the basket the free shipping should be gone.


Here's a snippet colleted from some Gists out of a GitHub issue discussion linked by @Ewout in another answer. I added a var_dump(), so you can uncomment and check what exactly you want to remove.

$available_methods is an array of:

$available_methods as $method_id => $method
Compare against $method_id if you need more specific checks.

// Hide standard shipping option when free shipping is available
add_filter( 'woocommerce_available_shipping_methods',         'wpse90835_hide_standard_shipping_when_free_is_available' );
 *  Hide Standard Shipping option when free shipping is available
 * @param array $available_methods
function  wpse90835_hide_standard_shipping_when_free_is_available($available_methods )
// Developers!: Dump this to see what you can unset
# var_dump( $available_methods );

// remove standard shipping option
if ( 
    isset( $available_methods['free_shipping'] ) 
    AND isset( $available_methods['flat_rate'] )
    unset( $available_methods['flat_rate'] );

return $available_methods;

can somebody tell me how to use the "Compare against $method_id if you need more specific checks."

share|improve this question
I'm not an expert on shipping, but couldn't you create a special shipping class? Once you set the items as virtual, you're telling WooCommerce that they don't need to be shipped. –  helgatheviking Nov 13 '13 at 11:58
The thing is as soon as you are set a item to "virtual" the option to assign it to a shipping class is not available anymore. i have also tried to the following: –  Shorty05 Nov 13 '13 at 15:45
Right, so don't set the item as virtual. I just looked into it though and I can't (quickly) find a way to exclude items from the the API shipping calculation. I'm sure it is possible, but I can't think of anything off-hand. –  helgatheviking Nov 13 '13 at 16:14

2 Answers 2

Well I dug a little deeper and found that in the abstract WC_Product class, there is the needs_shipping() method:

 * Checks if a product needs shipping.
 * @access public
 * @return bool
public function needs_shipping() {
    return apply_filters( 'woocommerce_product_needs_shipping', $this->is_virtual() ? false : true, $this );

and it is filterable, which means we can override the need for shipping costs on any product we like. Assuming you have a shipping class with the slug: shipping-class you can set any item with that class to not need shipping:

function wpa_123136_no_shipping( $needs_shipping, $product ){
  if( $product->get_shipping_class() == 'free-shipping' ){
    $needs_shipping = false;
  return $needs_shipping;
add_filter('woocommerce_product_needs_shipping','wpa_123136_no_shipping', 10, 2 );

or if you have a price-point and don't want to bother with the free shipping class:

function wpa_123136_no_shipping( $needs_shipping, $product ){
  if( $product->get_price() < 200 ){
    $needs_shipping = false;
  return $needs_shipping;
add_filter('woocommerce_product_needs_shipping','wpa_123136_no_shipping', 10, 2 );
share|improve this answer
thanks for looking into that ;) i will test it now and let you know if that works. –  Shorty05 Nov 13 '13 at 18:04
it doesn't work. as soon as i unstick the "virtual" option i see the shipping tab and if i don't fill in any dimensions or weights i get an error at the cart: Product # is missing dimensions. Aborting. (it comes from the fedex plugin) which means the code gets ignored cuz fedex still tries to calculate shipping. –  Shorty05 Nov 14 '13 at 13:46
Sorry. The solution must be in the shipping methods files (maybe in calculate_shipping()?) but I'm not familiar enough with the shipping classes and don't have the Fedex plugin to even look at. –  helgatheviking Nov 14 '13 at 15:27
no problem helga, thanks for looking into it anyway! i am very thankful for all your infos. –  Shorty05 Nov 14 '13 at 17:13

I have the same issue. I am thinking of purchasing the Local Pickup extension, it sounds like it helps you achieve this... though seems stupid to have to buy an extension to fix something that isn't working natively.

The extension (among other things) promises these features: • Selected pickup location is displayed in customer’s Account View Order page, order emails, and in the Order Admin • Configure some product categories as “pickup only” • Optionally disallow local pickup for other categories of product


share|improve this answer
I'm not sure Local Pickup Plus is actually what you guys are looking for though. Shorty05 seemed to want to offer free shipping on certain items. Wouldn't offering local pickup be confusing? –  helgatheviking Nov 14 '13 at 22:53
The thing is I wanna give customers the option to pickup what ever they like (never mind if virtual (free shipped) or standard (fedex) product. It works fine if customers have both in the card. But as soon as a we have virtual only products in the cart. Pickup is unavailable since woo skips the entire shipping part. –  Shorty05 Nov 15 '13 at 7:32

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.