Home > Enterprise >  Set all shipping methods cost to zero based on cart contents total amount in WooCommerce
Set all shipping methods cost to zero based on cart contents total amount in WooCommerce

Time:04-01

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 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?

CodePudding user response:

Try with:

 $cart_total = WC()->cart->get_total();

CodePudding user response:

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

  • Related