Enabling Free Shipping for ALL Fedex Shipping Rates in Magento

Published by John on January 13, 2016 Under Magento

Magento LogoRecently, while working on a client’s Magento website, I ran into an issue enabling free shipping for certain products via Fedex.

Using a Shopping Cart Rule, I setup the correct conditions/actions for the rule to provide free shipping for certain product categories when one of their main products was ordered. After a bit of playing, I was able to get the rule to work for the Free Method specified under: System->Configuration->Shipping Methods->Fedex->Free Method

However, this only worked for a single shipping rate/method. So, for example, if Free Method was set to Priority (1 day), but both Priority (1 day) and Ground (2-5 days) were available, the free shipping rule would only apply to the Priority shipping method.

While technically everything is working correctly, as Magento only allows a single shipping method to be free, I wanted to be able to provide free shipping by all available Fedex Methods. I was able to fix this rather easily by overriding a couple files, as shown below.

The Problem

When using a Magento Shopping Cart Rule, only a single shipping method for any given carrier can be used to provide free shipping. By default, you can not provide free shipping for all available methods for a given carrier.

Prerequisites

  1. A Backup of your Magento Database and Files.
  2. A working Shopping Cart Rule that provides free shipping on a product or a product that correctly shows free shipping via Fedex

Before you continue, make sure you make a backup of your website files and database. Failing to do so could result in problems with your store.

Add a New Fedex Shipping Method

First, you will need to add a new shipping method, which we will specify in the Magento Fedex Configurations as the Free Method. This is not a real shipping method, so make sure you do not use it anywhere except in the following setting: System->Configuration->Shipping Methods->Fedex->Free Method

Create a new folder in your ~/public_html/app/code/local directory and copy the core fedex file over, so we can modify it:

mkdir -p ~/public_html/shop/app/code/local/Mage/Usa/Model/Shipping/Carrier

cp ~/public_html/shop/app/code/core/Mage/Usa/Model/Shipping/Carrier/Fedex.php ~/public_html/shop/app/code/local/Mage/Usa/Model/Shipping/Carrier/

Next, we will modify the getCode function to add a new method in the newly created file: ~/public_html/shop/app/code/local/Mage/Usa/Model/Shipping/Carrier/Fedex.php

In the getCode function, add the following to the $codes array: ‘FEDEX_FREE_SHIPPING’ => ‘FEDEX FREE SHIPPING’,

After you are done, the method array should look as follows:


        $codes = array(
            'method' => array(
                'EUROPE_FIRST_INTERNATIONAL_PRIORITY' => Mage::helper('usa')->__('Europe First Priority'),
                'FEDEX_1_DAY_FREIGHT'                 => Mage::helper('usa')->__('1 Day Freight'),
                'FEDEX_2_DAY_FREIGHT'                 => Mage::helper('usa')->__('2 Day Freight'),
                'FEDEX_2_DAY'                         => Mage::helper('usa')->__('2 Day'),
                'FEDEX_2_DAY_AM'                      => Mage::helper('usa')->__('2 Day AM'),
                'FEDEX_3_DAY_FREIGHT'                 => Mage::helper('usa')->__('3 Day Freight'),
                'FEDEX_EXPRESS_SAVER'                 => Mage::helper('usa')->__('Express Saver'),
                'FEDEX_GROUND'                        => Mage::helper('usa')->__('Ground'),
                'FIRST_OVERNIGHT'                     => Mage::helper('usa')->__('First Overnight'),
                'GROUND_HOME_DELIVERY'                => Mage::helper('usa')->__('Home Delivery'),
                'INTERNATIONAL_ECONOMY'               => Mage::helper('usa')->__('International Economy'),
                'INTERNATIONAL_ECONOMY_FREIGHT'       => Mage::helper('usa')->__('Intl Economy Freight'),
                'INTERNATIONAL_FIRST'                 => Mage::helper('usa')->__('International First'),
                'INTERNATIONAL_GROUND'                => Mage::helper('usa')->__('International Ground'),
                'INTERNATIONAL_PRIORITY'              => Mage::helper('usa')->__('International Priority'),
                'INTERNATIONAL_PRIORITY_FREIGHT'      => Mage::helper('usa')->__('Intl Priority Freight'),
                'PRIORITY_OVERNIGHT'                  => Mage::helper('usa')->__('Priority Overnight'),
                'SMART_POST'                          => Mage::helper('usa')->__('Smart Post'),
                'STANDARD_OVERNIGHT'                  => Mage::helper('usa')->__('Standard Overnight'),
                'FEDEX_FREIGHT'                       => Mage::helper('usa')->__('Freight'),
                'FEDEX_NATIONAL_FREIGHT'              => Mage::helper('usa')->__('National Freight'),
                'FEDEX_FREE_SHIPPING'                 => 'FEDEX FREE SHIPPING',
            ),

Note, that we added a new method with a key of FEDEX_FREE_SHIPPING that is titled ‘FEDEX FREE SHIPPING.’

Select New Shipping Method as the “Free Method”

After this change, you should now see the new shipping method available in the System->Configuration->Shipping Methods->Fedex section. It should appear under both the Free Method section and also the Allowed Methods section.

Set the Free Method to be FEDEX FREE SHIPPING as below. If you do not see it, you may need to clear your Magento Cache.

Magento Fedex Free Shipping

Modify the Mage_Shipping_Model_Carrier_Abstract Class

Finally, we will need to modify the _updateFreeMethodQuote method of the Mage_Shipping_Model_Carrier_Abstract class to use this setting.

First, create a new folder in your ~/public_html/app/code/local directory and copy the core abstract shipping file over, so we can modify it:

mkdir -p ~/public_html/shop/app/code/local/Mage/Shipping/Model/Carrier

cp ~/public_html/shop/app/code/core/Mage/Shipping/Model/Carrier/Abstract.php ~/public_html/shop/app/code/local/Mage/Shipping/Model/Carrier/

Next, find the _updateFreeMethodQuote function and modify it as so:


    protected function _updateFreeMethodQuote($request)
    {
        if ($request->getFreeMethodWeight() == $request->getPackageWeight() || !$request->hasFreeMethodWeight()) {
            return;
        }

        $freeMethod = $this->getConfigData($this->_freeMethod);
        if (!$freeMethod) {
            return;
        }
        $freeRateId = false;

        if (is_object($this->_result)) {
            foreach ($this->_result->getAllRates() as $i=>$item) {
                if ($item->getMethod() == $freeMethod) {
                    $freeRateId = $i;
                    break;
                }
            }
        }
        
        /* 
         * Fedex Shipping Mod - John         
         * 
         * Allow for free shipping on ALL fedex shipping methods
         * 
         * Magento only allows a single free shipping method under System->Configuration->Shipping Methods->Fedex->Free Method
         * 
         * The below checks to see if $freeMethod  is set to a custom shipping method added 
         * to Mage/Usa/Model/Shipping/Carrier/Fedex.php called 'FEDEX_FREE_SHIPPING'
         * 
         * If it is, allow free shipping on all rates.
         * 
         */ 
         
        if($freeMethod == 'FEDEX_FREE_SHIPPING'){
			$price = 0;
			
			if (is_object($this->_result)) {
				foreach ($this->_result->getAllRates() as $i=>$item) {
					$this->_result->getRateById($i)->setPrice($price);
				}
				
			}
			
			return;
		} 
        
		/*
		 * Fedex Shipping Mod - John 
		*/

Specifically the part we added is between the Fedex Shipping Mod comments. This checks to see if the $freeMethod is set to ‘FEDEX_FREE_SHIPPING’ and if it is, will zero out the price for ALL Fedex Shipping Methods.

After this, you should be able to use your existing free shipping rule on all Fedex Shipping Methods.

Using with Other Shipping Methods

The above should work with other shipping methods, like USPS, UPS, DHL, etc.


4 Comments |

Comments:

  1. Sam on Apr 26, 2018

    Hello!

    I have used your free shipping for all fedex methods for a while now on Magento CE 1.9 and it has worked great, couldn’t thank you enough!

    Though now we are moving to Magento CE 2.2 and the same issue arises. I tried to wiggle a way of working your 1.9 method into the 2.2 but it falls apart when going to the abstract method and the actual workings of implementing the free method for all.

    Wondering if you have worked on this at all and have found a solution??

  2. John on Apr 27, 2018

    Glad to hear that this has been working for you. It is always nice to know that some people have been using my work(and that it has been working well!)

    The client I developed this for is still on 1.9, so until they upgrade to Magento 2.X(or I need it for another client,) I likely won’t be spending any time on this…I’ve got a lot of other website projects I’m working on right now.

    I am available for development though, so if you want to, I can update this for you for a reasonable fee.

  3. Sam on Apr 27, 2018

    Good news, little more digging and I was able to get it working!

    Real simple actually, adding the new fedex shipping method to the dropdown works the same in essentially the same spot.

    I just had to look in a different spot to find _updateFreeMethodQuote to edit and add the same code (which is now found at /vendor/magento/module-shipping/Model/Carrier/AbstractCarrier.php) which still works!

    Thanks again for the great work, Take care!

  4. John on Apr 27, 2018

    Awesome! Glad you were able to get it working!

Add a Comment