skip to Main Content

So I’m using this PHP snippet in order to give a free shipping to my customers when they have more than $60 in their cart.

function wc_ninja_change_flat_rates_cost( $rates, $package ) {
    // Make sure flat rate is available
    if ( isset( $rates['flat_rate:1'] ) ) {
        // Current value of the shopping cart
        $cart_subtotal = WC()->cart->subtotal;

        // Check if the subtotal is greater than 60
        if ( $cart_subtotal >= 59.99 ) {
            // Set the cost to $0
            $rates['flat_rate:1']->cost = 0;
            $rates['flat_rate:2']->cost = 0;
            $rates['flat_rate:3']->cost = 0;
        }
    }
    

    return $rates;
}

add_filter( 'woocommerce_package_rates', 'wc_ninja_change_flat_rates_cost', 10, 2 );

Currently if they have a product which cost $70 in the cart and apply a $20 coupon, they still receive a free shipping (because the subtotal is above $60).

I want to grant them a free shipping (set all shipping methods cost to zero) only if the amount is greater than $60 AFTER any discounts/coupons.

I already tried with:

$cart_subtotal = WC()->cart->total;

But there is no difference, any idea how to achieve this?

2

Answers


  1. Try with:

     $cart_total = WC()->cart->get_total();
    
    Login or Signup to reply.
  2. Using WC()->cart->get_total() will not give the desired result, because the output also contains HTML markup while you just need an integer, use WC()->cart->cart_contents_total instead.

    It is also not necessary to define all shipping methods via code ($rates['flat_rate:1'], $rates['flat_rate:'], etc.. ), you can just loop through all available shipping methods and adjust them.

    So you get:

    function filter_woocommerce_package_rates( $rates, $package ) {
        // Cart total amount (integer)
        $cart_total = WC()->cart->cart_contents_total;
    
        // Greater than or equal to
        if ( $cart_total >= 59.99 ) {
            foreach ( $rates as $rate_key => $rate ) {
                // For "free shipping" method (enabled), remove it
                if ( $rate->method_id == 'free_shipping' ) {
                    unset( $rates[$rate_key] );
                // For other shipping methods
                } else {
                    // Append rate label titles (free)
                    $rates[$rate_key]->label .= ' ' . __( '(free)', 'woocommerce' );
    
                    // Set rate cost
                    $rates[$rate_key]->cost = 0;
    
                    // Set taxes rate cost (if enabled)
                    $taxes = array();
    
                    foreach ( $rates[$rate_key]->taxes as $key => $tax ) {
                        if ( $rates[$rate_key]->taxes[$key] > 0 ) {
                            $taxes[$key] = 0;
                        }
                    }
    
                    $rates[$rate_key]->taxes = $taxes;
                }
            }
        }
    
        return $rates;
    }
    add_filter( 'woocommerce_package_rates','filter_woocommerce_package_rates', 10, 2 );
    

    Don’t forget to empty your cart to refresh shipping cached data!


    My answer is largely based on Set all shipping methods cost to zero for a Free shipping coupon in Woocommerce answer code

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search