blogjunkie
blogjunkie

Reputation: 237

Update cart fee on shipping method change in WooCommerce

I need a way to offer shipping discount up to a maximum of $25. I'm using the Fee API to do this since there are no coupon codes for shipping. Here's my code:

add_action( 'woocommerce_cart_calculate_fees', 'conditional_shipping_discount' );
  
function conditional_shipping_discount() {
    
    $max_shipping_discount = 25;
    $cart_subtotal = WC()->cart->subtotal;
    $current_shipping_method = WC()->session->get( 'chosen_shipping_methods' );
    $current_shipping_method_cost = WC()->session->get('cart_totals')['shipping_total'];
    
    // If our cart is > $99 AND shipping is not already free
    if ( ($cart_subtotal >= 99) && ($current_shipping_method_cost > 0) ) {
        
        // Calculate 25% of cart subtotal
        $calculated_shipping_discount = $cart_subtotal * 0.25; 
        
        // $shipping_discount = lowest value
        $shipping_discount = min( $current_shipping_method_cost, $calculated_shipping_discount, $max_shipping_discount );
                
        WC()->cart->add_fee( 'Shipping Discount', -1 * abs($shipping_discount) );
    }
}

This works great for the most part, except when the customer selects a different shipping method. The fee only shows the previously selected shipping discount. This GIF shows what I mean:

lagging fee update

The fee is corrected when the page is reloaded, or when the update_checkout event is triggered by changing item quantities or updating the checkout fields.

How can I have the cart fee (shipping discount) to update immediately when the shipping method is selected? Thank you in advance.

Upvotes: 0

Views: 1813

Answers (1)

Rajeev Singh
Rajeev Singh

Reputation: 1809

As I am checking your function, we always got previous shipping costs if I switch/change shipping methods. there is only one issue with $current_shipping_method_cost.

So if you change 1 line

$current_shipping_method_cost = WC()->session->get('cart_totals')['shipping_total'];

to

$current_shipping_method_cost = WC()->cart->get_shipping_total();

You always getting current/active shipping costs.

full code is :

add_action( 'woocommerce_cart_calculate_fees', 'conditional_shipping_discount' );  
function conditional_shipping_discount() {

    $max_shipping_discount = 25;
    $cart_subtotal = WC()->cart->subtotal;

    //$current_shipping_method = WC()->session->get( 'chosen_shipping_methods' );
    $current_shipping_method_cost = WC()->cart->get_shipping_total();

    // If our cart is > $99 AND shipping is not already free
    if ( ($cart_subtotal >= 99) && ($current_shipping_method_cost > 0) ) 
    {
       // Calculate 25% of cart subtotal
       $calculated_shipping_discount = $cart_subtotal * 0.25; 
    
       // $shipping_discount = lowest value
       $shipping_discount = min( $current_shipping_method_cost, $calculated_shipping_discount, $max_shipping_discount );
            
       WC()->cart->add_fee( 'Shipping Discount', -1 * abs($shipping_discount) );
    }
  }

Upvotes: 1

Related Questions