Categories
WordPress

How to Set Up Woocommerce Free Shipping On a Specific Product

The WooCommerce USPS Shipping Method and the UPS Shipping Method extensions makes it easy for you to charge your customers for shipping cost at checkout. The only problem, is that they are both a calculator for all products in the cart, and does not exclude products based on shipping classes. So an order can only use one shipping method.

Recently on a site I was working on for a designer the site needed to offer free shipping within the US on a specific product category and charge the customer for shipping on all other products. The scenario required the ability to have two different shipping methods (Free and Paid) dependent upon the products in the order and shipping location. To accomplish this task we needed the one order divided into two carts.

Create Shipping Class

So all the products that could qualify for free shipping are assigned a shipping class.

Add Shipping Class To Product1

 

In this example I am calling the shipping class freepromo.

Configure Free Shipping

Then free shipping is enabled in the WooCommerce Shipping Settings. Configure Additional ShippingThen the USPS and UPS shipping methods are enabled and configured. At this point every time a customer is in the US they will get free shipping. If they are not in the US they will be given a choice of UPS and USPS shipping rates.

So we still need to set up:

  • Free shipping only for products being shipped in the US with the freepromo shipping class
  • USPS and UPS shipping options for customers not in the US buying the freepromo products
  • USPS and UPS shipping options for customers purchasing all other products.
  • Free shipping and USPS and UPS shipping options for customers that purchase freepromo and non-freepromo products in one order.

There is a free plugin called Multiple Packages for WooCommerce. The plugin does work but it does not allow for additional shipping options for products with the freepromo shipping class that don’t qualify for free shipping. It also makes free shipping available to the product that does not have the freepromo shipping class.

To allow all four use cases we need to add a little code to functions.php or a site specific plugin.

/** Seperate freepromo products from other Items - forcing multiple carts **/
add_filter( 'woocommerce_cart_shipping_packages', 'ps_two_shipping_methods_in_cart' );

function ps_two_shipping_methods_in_cart( $packages ) {
   $packages = array();
   $freepromo_items = array();
   $regular_items = array();
   $freeshipclass= 'freepromo';
   $shipto = array(
                'country' => WC()->customer->get_shipping_country(),
                'state' => WC()->customer->get_shipping_state(),
                'postcode' => WC()->customer->get_shipping_postcode(),
                'city' => WC()->customer->get_shipping_city(),
                'address' => WC()->customer->get_shipping_address(),
                'address_2' => WC()->customer->get_shipping_address_2()
    );

    // Sort freepromo from regular
    foreach ( WC()->cart->get_cart() as $item ) {
        if ( $item['data']->needs_shipping() ) {
            if ( $item['data']->get_shipping_class() == $freeshipclass ) {
                $freepromo_items[] = $item;
            } else {
                $regular_items[] = $item;
            }
        }
    }

//If product qualifies for free shipping
    if ( $freepromo_items && WC()->customer->get_shipping_country() =='US' ) {
        $packages[] = array(
            'ship_via' => array( 'free_shipping'  ),
            'contents' => $freepromo_items,
            'contents_cost' => array_sum( wp_list_pluck( $freepromo_items, 'line_total' ) ),
            'applied_coupons' => WC()->cart->applied_coupons,
            'destination' => $shipto
        );
    }elseif ( $freepromo_items ) { //if product does qualify for free shipping but customer is not in US
        $packages[] = array(
            'ship_via' => array( 'usps','ups'  ), //available shipping methods for international
            'contents' => $freepromo_items,
            'contents_cost' => array_sum( wp_list_pluck( $freepromo_items, 'line_total' ) ),
            'applied_coupons' => WC()->cart->applied_coupons,
            'destination' => $shipto
        );
    }


//If product does not qualify for free shipping
    if ( $regular_items ) {
        $packages[] = array(
        	'ship_via' => array( 'usps','ups'  ),
            'contents' => $regular_items,
            'contents_cost' => array_sum( wp_list_pluck( $regular_items, 'line_total' ) ),
            'applied_coupons' => WC()->cart->applied_coupons,
            'destination' => $shipto
        );
    }   
   
    return $packages;
}

In the code shown above you will need to change the shipping class name and the available shipping methods in the ship_via array.

Here are some examples of what the cart looks like in different scenarios:

This image shows the cart for a product that does not belong to the freepromo class.
This image shows the cart for a product that does not belong to the freepromo class.

 

shippingclassint
Based on the freepromo restrictions the customer does not qualify for free shipping of the freepromo product because they are not in the US.

 

US customer is ordering a  product that has the freepromo shipping class and one product that pays shipping.
US customer is ordering a product that has the freepromo shipping class and one product that pays shipping.

 

Note: The code shown above is code from the Multiple Packages for WooCommerce plugin that I modified to meet the requirements of the project.

Subscribe To Updates and Tips Via Email

Get tips on web development, WordPress, web design & more

2 replies on “How to Set Up Woocommerce Free Shipping On a Specific Product”

Comments are closed.