In Woocommerce, I want to offer free shipping based on the number of unique cart items. First, I began looking at the available plugins and I can't find any simple solution for this.
What I would like is: if the visitor add 4 different items to the cart the shipping will be free, but not if for example user adds the same product 4 times. So basically it will work only for 4 different items (with 4 different SKU numbers).
Have any suggestions?
Using WooCommerce - Hide other shipping methods when FREE SHIPPING is available existing answer code, you just need to count the different order items with:
$items_count = count(WC()->cart->get_cart());
Now, you need to set your free shipping method settings to
N/A
(first option);
Then you will be able to allow free shipping easily altering the code as follow:
add_filter( 'woocommerce_package_rates', 'free_shipping_on_items_count_threshold', 100, 2 );
function free_shipping_on_items_count_threshold( $rates, $package ) {
$items_count = count(WC()->cart->get_cart()); // Different item count
$items_threshold = 4; // Minimal number of items to get free shipping
$free = array(); // Initializing
// Loop through shipping rates
foreach ( $rates as $rate_id => $rate ) {
// Find the free shipping method
if ( 'free_shipping' === $rate->method_id ) {
if( $items_count >= $items_threshold ) {
$free[ $rate_id ] = $rate; // Keep only "free shipping"
} elseif ( $items_count < $items_threshold ) {
unset($rates[$rate_id]); // Remove "Free shipping"
}
break;// stop the loop
}
}
return ! empty( $free ) ? $free : $rates;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
If you want to allow coupons to set free shipping too, you will have to change your free shipping settings to "A minimum order amount OR a coupon" with a 0
Minimum order amount, using the following instead:
add_filter( 'woocommerce_package_rates', 'free_shipping_on_items_count_threshold', 100, 2 );
function free_shipping_on_items_count_threshold( $rates, $package ) {
$items_count = count(WC()->cart->get_cart()); // Different item count
$items_threshold = 4; // Minimal number of items to get free shipping
$coupon_free_ship = false; // Initializing
$free = array(); // Initializing
// Loop through applied coupons
foreach( WC()->cart->get_applied_coupons() as $coupon_code ) {
$coupon = new WC_Coupon( $coupon_code ); // Get the WC_Coupon Object
if ( $coupon->get_free_shipping() ) {
$coupon_free_ship = true;
break;
}
}
// Loop through shipping rates
foreach ( $rates as $rate_id => $rate ) {
// Find the free shipping method
if ( 'free_shipping' === $rate->method_id ) {
if( $items_count >= $items_threshold || $coupon_free_ship ) {
$free[ $rate_id ] = $rate; // Keep only "free shipping"
} elseif ( $items_count < $items_threshold ) {
unset($rates[$rate_id]); // Remove "Free shipping"
}
break;// stop the loop
}
}
return ! empty( $free ) ? $free : $rates;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
Refresh the shipping caches: