Change WooCommerce specific shipping method cost based on cart subtotal

97 Views Asked by At

I'm managing a site that is WP with Woocommerce. During checkout, there is a 3-Day-Air shipping method option, which, right now is only shown for customers residing in 2 specific US states. The shipping method is a live rate from UPS and pulled in via the UPS API. (The API is handled via Hive UPS Shipping & Label plugin).

Currently, I have one filter working that unsets all other shipping methods if the user's $shipping_state is in the 2-state array in the filter. Another filter shows all shipping options, except the 3-Day_Air option, IF the state address is not in the array of the 2 states.

Then this filter in the snippet below is to change the incoming live-rate price for 3-Day-Air to $69.95 for shipping cost.

My question: is there a way to subtract $50 from the rate set in the snippet if the cart subtotal is over $200? (or reset the rate $19.95 if the >200 condition is met?)

This post answer is close

This is another workaround but it would have to only work for the condition of shipping_address is one of the 2 states.

Any help would be greatly appreciated. I'm picking up bits and pieces of PHP, but it gets murky pretty quickly. Thanks in advance.

add_filter( 'woocommerce_package_rates', function( $shipping_costs) {
    
    $shipping_method_min_cost = array(
        'wf_shipping_ups:12'    =>  69.95,      // Shipping id  => min_cost
        
    );

    foreach( $shipping_costs as $shipping_cost ) {
        $shipping_method_id = $shipping_cost->get_id();
        if( isset($shipping_method_min_cost[$shipping_method_id]) ) {
            $cost = (float) $shipping_cost->get_cost();
            if( $cost < $shipping_method_min_cost[$shipping_method_id] ) {
                $shipping_cost->set_cost($shipping_method_min_cost[$shipping_method_id]);
            }
        }
    }
    return $shipping_costs;
});

1

There are 1 best solutions below

1
On BEST ANSWER

To change "the incoming live-rate price for 3-Day-Air to $69.95 for shipping cost", you simply need to use one of the following ways inside your function:

  1. Cart subtotal excluding taxes
    $shipping_method_min_cost = array(
        'wf_shipping_ups:12' => WC()->cart->subtotal >= 200 ? 69.95 : 19.95,
    );
  1. Cart subtotal including taxes:
    $shipping_method_min_cost = array(
        'wf_shipping_ups:12' => WC()->cart->get_subtotal() >= 200 ? 69.95 : 19.95,
    );

Both ways should work.


You could also use the shipping package displayed cart subtotal (handle tax calculations).

Below is a complete-revised code version, that handle shipping taxes (if enabled), using the shipping package displayed cart subtotal:

add_filter( 'woocommerce_package_rates', 'filter_woocommerce_package_rates', 10, 2 );
function  filter_woocommerce_package_rates( $rates, $package ) {  
    $targeted_method = 'wf_shipping_ups:12'; // Targeted shipping method rate ID
    $cart_subtotal   = $package['cart_subtotal']; // get displayed cart subtotal
    $new_cost        = $cart_subtotal >= 200 ? 69.95 : 19.95; // Cost calculation

    // Loop through shipping rates for the current shipping package
    foreach( $rates as $rate_key => $rate ) {
        $base_cost = $rate->cost;
        if( $rate_key === $targeted_method && $base_cost < $new_cost ) {
            $rates[$rate_key]->cost = $new_cost; // set the new cost

            $has_taxes = false; // Initializing
            $taxes     = array(); // Initializing

            // 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 / $base_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;
            }
            break;
        }
    }
    return $rates;
}

It should work too.


To refresh shipping cached data, simply empty the cart.