WooCommerce custom shipping costs for min required subtotal with tax calculations

I have set some Shipping methods with taxable option enabled in WooCommerce. I use this code to set up different shipping cost if spend over X amount:

// Extra discount on shipping for orders of values of above 150 or 100.
function custom_adjust_shipping_rate( $rates ) {
    $cart_subtotal = WC()->cart->subtotal;

    // Check if the subtotal is greater than value specified
    if ( $cart_subtotal >= 29.99 ) {

        // Loop through each shipping rate
        foreach ( $rates as $rate ) {

            // Store the previous cost in $cost
            $cost = $rate->cost;

            // Adjust the cost as needed
            // original shipping greater than 6 discount by 5 
            if ( $cost == 7.38 ) {
                // discount rate by 5
                $rate->cost = $cost - 2.54;
            }
            // Optional discount for other shipping rates 
            if ( $cost == 4.10 ) {
                $rate->cost = $cost - 5;
            }
        }
    }
    return $rates;
}
add_filter( 'woocommerce_package_rates', 'custom_adjust_shipping_rate', 10 );

But the problem is the tax calculations. My code doesn’t handle taxes.

How can I adjust taxes from custom shipping cost?

How to enable taxes in cost calculations?

Any advice is appreciated.

Answer

To enable shipping taxes calculations in your code, use the following revisited code instead:

add_filter( 'woocommerce_package_rates', 'adjust_shipping_rates_cost', 10, 2 );
function adjust_shipping_rates_cost( $rates, $package ) {
    $min_subtotal  = 30; // Set min subtotal
    $cart_subtotal = 0; // Initializing
        
    // Loop through cart items to get items total for the current shipping package 
    foreach( $package['contents'] as $item ) {
        $cart_subtotal += $item['line_subtotal'] + $item['line_subtotal_tax'];
        // $cart_subtotal += $item['line_subtotal']; // Or without taxes
    }

    // Check if the subtotal is greater than specified value
    if ( $cart_subtotal < $min_subtotal ) {
        return $rates; // Exit
    }

    // Loop through shipping rates
    foreach ( $rates as $rate_key => $rate ) {
        $has_taxes = false; // Initializing
        $taxes     = array(); // Initializing
        $new_cost = $initial_cost = $rate->cost; // grab initial cost

        if ( $initial_cost == 7.38 ) {
            $new_cost -= 2.54;
        } elseif ( $initial_cost == 4.10 ) {
            $new_cost -= 5;
        }
        $rates[$rate_key]->cost = $new_cost; // Set new rate cost

        // Loop through taxes array (change taxes rate cost if enabled)
        foreach ($rate->taxes as $key => $tax){
            if( $tax > 0 ){
                // Get the tax rate conversion
                $tax_rate    = $tax / $initial_cost;

                // Set the new tax cost in the array
                $taxes[$key] = $new_cost * $tax_rate;
                $has_taxes   = true; // Enabling tax changes
            }
        }
        // set array of shipping tax cost
        if( $has_taxes ) {
            $rates[$rate_key]->taxes = $taxes;
        }
    }
    return $rates;
}

Code goes in functions.php file of the active child theme (or active theme). It should work.

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

Leave a Reply

Your email address will not be published. Required fields are marked *