Search code examples
phpwordpresswoocommercecartshipping-method

Free shipping Based on minimal cart items count in WooCommerce


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?


Solution

  • 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:

    1. This code is already saved on your function.php file.
    2. In a shipping zone settings, disable / save any shipping method, then enable back / save.
      You are done and you can test it.