free shipping woocommerce

Free Shipping For Specific Products in WooCommerce

Shipping is a big department for large WooCommerce stores, and even though free shipping may sound easy, it gets a tad bit challenging when you want partial free shipping i.e. allow certain products to ship for free, while charge a shipping rate for some especially when you’re running a huge store with hundreds or even thousands of products (not uncommon for stores with Printful WooCommerce integration, or other fulfillment companies).

Scenario

Let’s assume our customer, John Doe, adds two products to his cart. We would like to charge him a real-time shipping rate for Product A, and charge no shipping fee for Product B i.e. offer free shipping for one product in the cart, and charge shipping for the other product (or the rest of the products) in the cart.

There are a few traditional ways to do this, but the most efficient way to carry this out is to eliminate Product B from being considered for shipping altogether!

Why charge $0.00 for shipping (and gift-wrap that as “Free Shipping”) when you can completely remove the line-item that shows shipping costs?

How to Set-up Free Shipping for Individual Products

The process is pretty simple, and only involves three steps:

  1. Create a shipping class, and name it accordingly. For e.g. “Free”. Copy down the slug for this class. In most cases, you’d want the slug to be free.
  2. Assign that shipping class to the product(s) that you’d like to offer shipping for free.
  3. Add the following code to your theme’s functions.php file.
<?php

/* WooCommerce - Exclude Products From Shipping */

function cs_exlude_free_shipping( $packages ) {
  foreach( $packages as $i => $package ){
    foreach ( $package['contents'] as $key => $item ) {
      if ( $item['data']->get_shipping_class() == 'free' ) {
        unset( $packages[$i]['contents'][$key] );
        add_filter( 'woocommerce_cart_needs_shipping', '__return_true' );
      }
    }
  }
  return $packages;
}
add_filter( 'woocommerce_cart_shipping_packages', 'cs_exlude_free_shipping' );

The free in the get_shipping_class conditional statement is the slug of the class you created for free shipping. Replace it with your slug if it’s different than free.

That’s it.

You can do this for multiple products, of course. Simply assign the shipping class to each product for which you want to enable free shipping.