Woocommerce conditional shipping cost reduction based on cart amount and item count

I’m looking for a way to make a custom reduction on shipping cost, based on cart total percentage, flat rate and quantity per type of product…


For 6 product : flat shipping rate 20€

  • Total cart is 120€ | Shipping cost = flat rate cost – 10% total cart | 20 – 12 = 8€
  • Total cart is 180€ | Shipping cost = flat rate cost – 10% total cart | 20 – 18 = 2€
  • Total cart is 220€ | Shipping cost = flat rate cost – 10% total cart | 20 – 22 = 0€

For 12 product : flat shipping rate 30€

  • Total cart is 120€ | Shipping cost = flat rate cost – 10% total cart | 30 – 12 = 18€
  • Total cart is 180€ | Shipping cost = flat rate cost – 10% total cart | 30 – 18 = 12€
  • Total cart is 220€ | Shipping cost = flat rate cost – 10% total cart | 30 – 22 = 8€

How can this be done?

Answer

This can be done without a plugin…

1) You will need first in WooCommerce shipping settings for each shipping zone to set an amount of 1 for “Flat rate” method:

enter image description here

This amount will be changed in our function to 20€ from 1 to 11 items and 30€for 12 and more items. This amount will be decreased by the 10% cart total amount.


2) Then using a custom function hooked in woocommerce_package_rates filter hook, you will be able to make a discount on shipping cost based on cart item count and on cart total.

Here is that code:

add_filter( 'woocommerce_package_rates', 'custom_package_rates', 10, 2 );
function custom_package_rates( $rates, $packages ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;

    // Get some cart data and set variable values
    $cart_count = WC()->cart->get_cart_contents_count();
    $cart_total =  WC()->cart->cart_contents_total;
    $cart_10_percent = $cart_total * 0.1;
    $flat_rate_value = 20; // Default "Flat rate" value

    foreach($rates as $rate_key => $rate_values ) {
        $method_id = $rate_values->method_id;
        $rate_id = $rate_values->id;

        if( $method_id == 'flat_rate' ){
            if( $cart_count < 6 )
                $cart_10_percent = 0; // No percent discount
            elseif( $cart_count >= 12 )
                $flat_rate_value = 30; // "Flat rate" value for 12 or more items

            $rate_cost = $flat_rate_value > $cart_10_percent ? $flat_rate_value - $cart_10_percent : 0;

            // Set the new calculated rate cost
            $rates[$rate_id]->cost = number_format( $rates[$rate_id]->cost * $rate_cost, 2 );

            // Taxes rate cost (if enabled)
            $taxes = array();
            foreach ($rates[$rate_id]->taxes as $key => $tax){
                if( $tax > 0 ){ // set the new tax cost
                    // set the discounted tax cost
                    $taxes[$key] = number_format( $tax * $rate_cost, 2 );
                }
            }
            $rates[$rate_id]->taxes = $taxes;
        }
    }
    return $rates;
} 

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

Tested on WooCommerce 3 and works.


Refresh the shipping caches (needed sometimes):
1) First empty your cart.
2) This code is already saved on your function.php file.
3) Go in a shipping zone settings and disable one “flat rate” (for example) and “save”. Then re-enable that “flat rate” and “save”. You are done and you can test it.