Search code examples
phpwordpresswoocommercecoupon

Set all shipping methods cost to zero for a Free shipping coupon in Woocommerce


I have 3 shipping methods in my cart that should become zero prices as soon as your customer enters Free Shipping coupon.

I know how to add a filter in functions.php to detect the coupon but is someone know a snippet to set shipping methods visibles in cart (radio button) to ZERO for this order?

My deliveries methods are companies like UPS, FedEx...

I activated the free shipping option in order it can be managed with coupon.

The list of choice of deliveries methods for the customers is calculated according to my products shipping class and order total weight.

Shipping class are not calculated but set by product and i use TABLE RATE PLUGIN to calculate the weight.


Solution

  • First free shipping method has to be enabled with option "A valid free shipping coupon"…

    Then you need to set the desired coupon codes with option "Allow free shipping" enabled.

    The following code will set all shipping methods costs to zero when a valid coupon code (with option "Allow free shipping" enabled) will be applied.

    Update: Hide "Free shipping" method and append shipping label titles with "(free)"

    add_filter( 'woocommerce_package_rates', 'coupon_free_shipping_customization', 20, 2 );
    function coupon_free_shipping_customization( $rates, $package ) {
        $has_free_shipping = false;
    
        $applied_coupons = WC()->cart->get_applied_coupons();
        foreach( $applied_coupons as $coupon_code ){
            $coupon = new WC_Coupon($coupon_code);
            if($coupon->get_free_shipping()){
                $has_free_shipping = true;
                break;
            }
        }
    
        foreach( $rates as $rate_key => $rate ){
            if( $has_free_shipping ){
                // 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;
    }
    

    Code goes in function.php file of your active child theme (or active theme).

    Tested and works. It should works also for you.

    Sometimes, you should may be need to refresh shipping methods:
    1) Empty cart first.
    2) Go to shipping Zones settings, then disable/save and re-enable/save the related shipping methods.