0

For one day, during the free shipping event, I would like to enable free shipping for every order (using hook / filter) without changing the actual shipping settings inside admin (minimum requirement). I tried using the following snippet, but unfortunately does not work when minimum total for free shipping is not met. Free shipping does not appear inside $rates.

function force_free_shipping( $rates ) {
    $free = array();
    foreach ( $rates as $rate_id => $rate ) {
        if ( 'free_shipping' === $rate->method_id ) {
            $free[ $rate_id ] = $rate;
            break;
        }
    }
    return ! empty( $free ) ? $free : $rates;
}
add_filter( 'woocommerce_package_rates', 'force_free_shipping', 200 );
mr.work
  • 173
  • 10

1 Answers1

1

My code is taken from this topic (Set custom shipping rates programmatically in Woocommerce 3 , and credit goes to @LoicTheAztec and his answer https://stackoverflow.com/a/48787963/17787127) and adjusted. Mine is kinda ugly I guess, but at least it works.

If you only have one shipping method, use this:

add_filter( 'woocommerce_package_rates', 'custom_shipping_costs', 20, 2 );
function custom_shipping_costs( $rates, $package ) {
    // New shipping cost (can be calculated)
    $new_cost = 0;
    $tax_rate = 0;

    foreach( $rates as $rate_key => $rate ){
        // Excluding free shipping methods
        if( $rate->method_id != 'shipping_method_0_flat_rate1'){

            // Set rate cost
            $rates[$rate_key]->cost = $new_cost;

            // 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] = $new_cost * $tax_rate;
            }
            $rates[$rate_key]->taxes = $taxes;

        }
    }
    return $rates;
}

If you have multiple shipping methods use this:

add_filter( 'woocommerce_package_rates', 'custom_shipping_costs', 20, 2 );
function custom_shipping_costs( $rates, $package ) {
    // New shipping cost (can be calculated)
    $new_cost = 0;
    $tax_rate = 0;

    foreach( $rates as $rate_key => $rate ){
        // Excluding free shipping methods
        if( $rate->method_id != 'shipping_method_0_flat_rate1'){

            // Set rate cost
            $rates[$rate_key]->cost = $new_cost;

            // 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] = $new_cost * $tax_rate;
            }
            $rates[$rate_key]->taxes = $taxes;

        } elseif ( $rate->method_id != 'shipping_method_0_flat_rate5'){

            // Set rate cost
            $rates[$rate_key]->cost = $new_cost;

            // 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] = $new_cost * $tax_rate;
            }
            $rates[$rate_key]->taxes = $taxes;

        }
    }
    return $rates;
}

For both cases you need to replace shipping_method_0_flat_rate1 and/or shipping_method_0_flat_rate5 with your shipping method IDs (you can find it with Chrome inspect tool):

shipping_method_id

In order for the code to work the first time, you may have to remove product from cart, add it again and check it.
Code goes in functions.php, tested and works.

ilkork
  • 23
  • 5