PHP: FedEx shipping rates calculator

FedEx Ship Manager (FSM) Direct was designed to allow customers to connect directly to the FedEx back end systems using their own communications protocol. Welcome to FSM Direct!
You can compose FedEx XML Transactions to interface between your e-commerce application and the FedEx server and vice versa.
This solution is applicable only to those customers that have the development resources and knowledge to develop their own FedEx interface.

Before you begin:
FSM Direct Site Registration: To register in the FSM Direct program, go to http://www.fedex.com/us/solutions/wis/. Register and complete the brief registration form.

Steps for developing your own communications protocol and integrating it into your application are listed below.

  • Read and accept the FedEx Ship Manager Direct license agreement.
  • Review the FedEx Direct Documentation: Determine if this alternative or FedEx API is appropriate for your application.
  • Develop your application.
  • Send an email to websupport@fedex.com. Request to be set up for testing. Attach FedEx Express and/or FedEx Ground account number(s).
  • Test your application.

All documentation can be found here:

http://www.fedex.com/us/solutions/wis/pdf/fsm_directmanual.pdf

http://www.fedex.com/us/solutions/wis/pdf/xml_transguide.pdf

Here’s more about this class

How to use this Fedex rates class:


    $fedex = new Fedex;
    $fedex->setServer("https://gatewaybeta.fedex.com/GatewayDC");
    $fedex->setAccountNumber(123123123);
    $fedex->setMeterNumber(12312312);
    $fedex->setCarrierCode("FDXE");
    $fedex->setDropoffType("REGULARPICKUP");
    $fedex->setService($service, $serviceName);
    $fedex->setPackaging("YOURPACKAGING");
    $fedex->setWeightUnits("LBS");
    $fedex->setWeight(17);
    $fedex->setOriginStateOrProvinceCode("OH");
    $fedex->setOriginPostalCode(44333);
    $fedex->setOriginCountryCode("US");
    $fedex->setDestStateOrProvinceCode("CA");
    $fedex->setDestPostalCode(90210);
    $fedex->setDestCountryCode("US");
    $fedex->setPayorType("SENDER");

    $price = $fedex->getPrice();

All available variables can be found here: http://www.fedex.com/us/solutions/wis/pdf/xml_transguide.pdf (FDXRateRequest)

Possible Fedex answer:


fedex Object
(
    [server] => https://gatewaybeta.fedex.com/GatewayDC
    [accountNumber] => 123123123
    [meterNumber] => 12312312
    [carrierCode] => FDXE
    [dropoffType] => REGULARPICKUP
    [service] => STANDARDOVERNIGHT
    [serviceName] => FedEx Standard Overnight
    [packaging] => YOURPACKAGING
    [weightUnits] => LBS
    [weight] => 17
    [originStateOrProvinceCode] => OH
    [originPostalCode] => 44333
    [originCountryCode] => US
    [destStateOrProvinceCode] => CA
    [destPostalCode] => 90210
    [destCountryCode] => US
    [payorType] => SENDER
    [price] => price Object
        (
            [service] => FedEx Standard Overnight
            [rate] => 86.37
            [response] => Array
                (
                  ...//Here is full xml response
                )
        )
)

Click here to download FedEx shipping rates calculator class

Please make a donation of 1$ if you find our software useful and want to support the continued development.


Thank you.

50 Comments

  1. jrichey says:

    We have a FedEx account number, but I’m not sure what the ‘meterNumber’ is? How can I obtain that – I really need to get this working soon.

    Thanks

  2. Algirdas says:

    I either don’t know what is meterNumber. You should ask it at fedex support, but when I was developing this class – meterNumber was not necessary.

  3. fedexboy says:

    A meter number is used in conjunction with your account number. For rating purposes the meter number is optional. If you use the Direct for producing labels, and some other functionalities, the meter is required. You can obtain a meter by sending a subscribe transaction to the test server. Once you are in production, you will need to repeat that step to get your production meter.

  4. tozzini says:

    Hi Guys, i’m using the Fedex Shipping Rate Calculation, it seams to work fine, but when i try to make a Fedex Ground it returns to me error message saying that “Invalid service type” Error #16470″ did anyone have these problem??

    Thanx a lot

    Andre Tozzini

  5. Algirdas says:

    I either don’t know what the problem could it be. You should contact Fedex and ask them what is the problem with Fedex Ground service type.

  6. tozzini says:

    Thanx Algirdas….

    I will contact the Fedex Guys….

    Cya

    Andre Tozzini

  7. [...] After this I found few bugs witch I fixed and now you can download updated FedEx class from this post. [...]

  8. [...] You can download updated FedEx class from this post. [...]

  9. acorath says:

    This is in reply to a comment from just over a year ago, but for future downloads. If you’re Ground shipping, you need to change the following line from this…

    $fedex->setCarrierCode(“FDXE”);

    to this…

    $fedex->setCarrierCode(“FDXG”);

  10. dmoola says:

    all i’m getting is a 16501 error… could not communicate with mainframe. at first i thought it was maybe on their end, so i waited a day and it still says that. any suggestions?

    http://dev.koboseattle.com/Fedex/index.php

  11. Algirdas says:

    Look at comment above
    You are trying to get rates for ground service but carrier code is set to express, so you should use $fedex->setCarrierCode(“FDXG”); and everything will be ok.

  12. dmoola says:

    Genius! Sorry about that, I set it properly in the class, just not in the page calling the class.

  13. erik10206 says:

    The script looks great, but I was wondering how you go about submitting the request to get your meter number?

  14. mbecker says:

    Hello Algirdas,

    first of all many thanks that you share your skills with us!
    It´s my first time I shall intergrate the FedEx Rate Modul in a selfmade shopping cart.
    My question:
    How can I use the variables from the price object as single output?
    I only need the “rate” and the “service”, so I build these request at the end of index.php.

    
    foreach($price as $wert) {
        if(is_object($wert)){
        	foreach($wert as $eintrag) {
        		if(is_object($eintrag) || is_array($eintrag)){
        			echo '';
          		}
           		else {
           			echo $eintrag.'';
        		}
        	}
        }
    }
    
    

    At the end of fedex.php I changed “print_r($this);” into “return $this;”.

    It´s my first time I work with classes and objects, so it´s difficult for me to understand the complete script.

    Hope you can help me.

    Thank you and best regards,
    Martin

  15. ntd says:

    Martin
    Have you found an answer? I’m in the same boat.

    Also the the publisher the change for the ground issue doesn’t work while in test. Is it just the test mode problem?

    Thanks

    Nick

  16. Algirdas says:

    if you call

    $price = $fedex->getPrice();

    then you will be able to print rate

    echo $price->price->rate;

  17. Jewel says:

    Hi
    From my local PC i can access all information from fedex.com using this class but when i m trying to collect information then i can’t get.

    Whats the problem?
    Please help me.

    Thnaks

  18. Algirdas says:

    Looks like you server does not have curl lib.
    http://lt2.php.net/curl

  19. brooksh says:

    Does anyone know how to get time in transit for ground using this script? The script uses Rate Available Services and I guess that using Service Availability gives you transit time.

  20. wesley says:

    Here is a function that I built based on the code that allows you to get a single rate by calling a function. I use this on an order form that gets the FedEx rate via AJAX based on the customers shipping method:

    /**
    * Used to get real time shipping rates from FedEx.com
    * NOTE: Requires valid FedEx Account and Meter numbers
    *
    * RETURN VALUES
    * false: Invalid Service Type (remember ===)
    * 0: Missing or Empty Arguments (remember ===)
    * empty: Nothing returned from FedEx (try again)
    * string: A FedEx error code and description
    * integer: The rate to ship the package
    *
    * ARGUMENTS
    * $service: Any of the service codes specified below
    * $lbs : The weight of the package in pounds
    * $ds : Destination State (Where it's being shipping to)
    * $dz : Destination Zip
    * $os : Originating State (Where it's being shipping from)
    * $oz : Originating Zip
    *
    * AVAILABLE SERVICE TYPES----------------------------------
    * CODE DESCRIPTION
    * ---------------------------------------------------------
    * PRIORITYOVERNIGHT FedEx Priority Overnight
    * $STANDARDOVERNIGHT FedEx Standard Overnight
    * $FIRSTOVERNIGHT FedEx First Overnight
    * FEDEX2DAY FedEx 2 Day
    * FEDEXEXPRESSSAVER FedEx Express Saver
    * INTERNATIONALPRIORITY FedEx International Priority
    * INTERNATIONALECONOMY FedEx International Economy
    * INTERNATIONALFIRST FedEx International First
    * FEDEX1DAYFREIGHT FedEx Overnight Freight
    * FEDEX2DAYFREIGHT FedEx 2 day Freight
    * FEDEX3DAYFREIGHT FedEx 3 day Freight
    * FEDEXGROUND FedEx Ground
    * GROUNDHOMEDELIVERY FedEx Home Delivery
    * ---------------------------------------------------------
    */
    function getFedexRate($service,$lbs,$ds,$dz,$os="CA",$oz="91604")
    {
    $fedexAccountNum = 121212121;
    $fedexMeterNum = 3434343;
    if( empty($service) || empty($lbs) || empty($ds) || empty($dz) || empty($os) || empty($oz) ) return 0;
    switch (strtoupper($service))
    {
    case "PRIORITYOVERNIGHT": $fedexService['PRIORITYOVERNIGHT'] = 'FedEx Priority Overnight'; break;
    case "STANDARDOVERNIGHT": $fedexService['STANDARDOVERNIGHT'] = 'FedEx Standard Overnight'; break;
    case "FIRSTOVERNIGHT": $fedexService['FIRSTOVERNIGHT'] = 'FedEx First Overnight'; break;
    case "FEDEX2DAY": $fedexService['FEDEX2DAY'] = 'FedEx 2 Day'; break;
    case "FEDEXEXPRESSSAVER": $fedexService['FEDEXEXPRESSSAVER'] = 'FedEx Express Saver'; break;
    case "INTERNATIONALPRIORITY": $fedexService['INTERNATIONALPRIORITY'] = 'FedEx International Priority'; break;
    case "INTERNATIONALECONOMY": $fedexService['INTERNATIONALECONOMY'] = 'FedEx International Economy'; break;
    case "INTERNATIONALFIRST": $fedexService['INTERNATIONALFIRST'] = 'FedEx International First'; break;
    case "FEDEX1DAYFREIGHT": $fedexService['FEDEX1DAYFREIGHT'] = 'FedEx Overnight Freight'; break;
    case "FEDEX2DAYFREIGHT": $fedexService['FEDEX2DAYFREIGHT'] = 'FedEx 2 day Freight'; break;
    case "FEDEX3DAYFREIGHT": $fedexService['FEDEX3DAYFREIGHT'] = 'FedEx 3 day Freight'; break;
    case "FEDEXGROUND": $fedexService['FEDEXGROUND'] = 'FedEx Ground'; break;
    case "GROUNDHOMEDELIVERY": $fedexService['GROUNDHOMEDELIVERY'] = 'FedEx Home Delivery'; break;
    default: return false;
    }
    require("fedex.php");
    if( stristr($service,"GROUND") ) $serviceCode = "FDXG"; else $serviceCode = "FDXE";
    $fedex = new Fedex;
    $fedex->setServer("https://gateway.fedex.com/GatewayDC");
    $fedex->setAccountNumber($fedexAccountNum);
    $fedex->setMeterNumber($fedexMeterNum);
    $fedex->setCarrierCode($serviceCode);
    $fedex->setDropoffType("REGULARPICKUP");
    $fedex->setService($service, $serviceName);
    $fedex->setPackaging("YOURPACKAGING");
    $fedex->setWeightUnits("LBS");
    $fedex->setWeight($lbs);
    $fedex->setOriginStateOrProvinceCode($os);
    $fedex->setOriginPostalCode($oz);
    $fedex->setOriginCountryCode("US");
    $fedex->setDestStateOrProvinceCode($ds);
    $fedex->setDestPostalCode($dz);
    $fedex->setDestCountryCode("US");
    $fedex->setPayorType("SENDER");
    $response = $fedex->getPrice();
    if( isset($response->price) )
    $retVal = (float)$response->price->rate;
    else
    $retVal = "Error ".$response->error->number.": ".$response->error->description;
    return $retVal;
    }

    EXAMPLE:

    $rate = getFedexRate("FEDEXGROUND",1,"UT",84095);
    if( $rate === false ) echo "Invalid Service Type";
    elseif( $rate === 0 ) echo "Missing Argument(s)";
    elseif( $rate == "" ) echo "FedEx Didn't Respond";
    elseif( is_string($rate) ) echo "Error: $rate";
    else echo "Rate: $rate";

  21. Mike says:

    For some reason, my FedEx integration with “FEDEXGROUND” and CarrierCode as ‘FDXG’ but it is returning back blank values. Express services are working fine. I am in need of an urgent reply :(

    Some other info:
    $fedex->setServer(“https://gatewaybeta.fedex.com/GatewayDC”);

  22. Chris says:

    My widget encounters the same problem. I get ErrorCode 16470 (Invalid service type) both for FEDEXGROUND and GROUNDHOMEDELIVERY

    Comments would be VERY much appreciated

  23. Algirdas says:

    Actually I’m not so familiar with all the errors, so the best issue would be to as fedex support for a help.

  24. Todd says:

    It works when the carrier code is set to FDXE except the GROUNDDELIVERY and GROUNDHOMEDELIVERY. When I change carrier code to FDXG it does send any shipping data/price back. This is what I get.

    fedex Object
    (
    [server] => https://gatewaybeta.fedex.com/GatewayDC
    [accountNumber] => 510087640
    [meterNumber] => 100002119
    [carrierCode] => FDXG
    [dropoffType] => REGULARPICKUP
    [service] => FEDEXGROUND
    [serviceName] => FedEx Ground
    [packaging] => YOURPACKAGING
    [weightUnits] => LBS
    [weight] => 17
    [originStateOrProvinceCode] => OH
    [originPostalCode] => 44333
    [originCountryCode] => US
    [destStateOrProvinceCode] => CA
    [destPostalCode] => 90210
    [destCountryCode] => US
    [payorType] => SENDER
    )
    fedex Object
    (
    [server] => https://gatewaybeta.fedex.com/GatewayDC
    [accountNumber] => 510087640
    [meterNumber] => 100002119
    [carrierCode] => FDXG
    [dropoffType] => REGULARPICKUP
    [service] => GROUNDHOMEDELIVERY
    [serviceName] => FedEx Home Delivery
    [packaging] => YOURPACKAGING
    [weightUnits] => LBS
    [weight] => 17
    [originStateOrProvinceCode] => OH
    [originPostalCode] => 44333
    [originCountryCode] => US
    [destStateOrProvinceCode] => CA
    [destPostalCode] => 90210
    [destCountryCode] => US
    [payorType] => SENDER
    )

    Also it sends the wrong fuel price, I checked it with the Fed-Ex site and it it off between 400-500%

  25. great stuff :)

    I just like to ask how do we add other dimensions to it like Width, Height, Girth?

    Looking for your reply.

  26. swan micle says:

    i don’t know how to integrate FedEx shipping rate calculator in my site,help me how to integrate that?

    Every site is diferent, so there is no common integration rules.

  27. stephane says:

    Why dont you have any variable about the height and width of the product?

  28. Algirdas says:

    Because, there was no such variables in that FedEx API, I’m not shure if it is available now. The price depends on weight.

  29. Deepti says:

    Hi Algirdas,

    I just downloaded your code above for FedEx shipping rates calculator. I have adjusted the path for fedEx.php in

    (require_once(getcwd().”/xmlparser.php”);)

    now i am getting an error saying

    Fatal error: Call to undefined function curl_init() in D:\xampp\htdocs\test\Fedex\fedex.php on line 134

    what is this error. how can i calculate the shipping cost.

    Looking for your reply. Thanks

  30. Algirdas says:

    There’s no curl library installed on your server. More info can be found here http://lt.php.net/manual/en/book.curl.php

  31. Deepti says:

    Thanks it is working Superbly.

  32. Deepti says:

    Thanks a lot..

  33. marcelo says:

    Hi,

    I’ve been testing the code and works fine if I use:

    $fedex->setCarrierCode(“FDXG”);

    but when I try to use FDXE I get and error:
    [error] => fedexError Object
    (
    [number] => 16468
    [description] => Invalid Customer Account Number

    is weird because I have a thirdparty fedex module and all the options works fine using the same fedex account, any help would be apreciated.

    Thanks

  34. Mike says:

    Getting the error

    Notice: Undefined index: ERROR in fedex.php on line 160

    that is at the following line in fedex.php

    if(count($array['FDXRATEREPLY'][0]['ERROR'])) { // If it is error

    is there any solution to solve this

  35. Algirdas says:

    It’s not an error, it’s just a notice.
    You can turn off any PHP error reporting. It is recomended for a live server environment.
    Or you can use other function: array_key_exists
    I think it could be something like that:
    if (array_key_exists(‘ERROR’, $array['FDXRATEREPLY'][0]))…

  36. Aniruddha Banerjee says:

    I am getting the error on fedex.php

    require_once(ROOT_DIR.”/libraries/USPS/xmlparser.php”);

    can you please help me how do i get this file, and how to integrate this

    thanking you a lot for you contribution

    happy diwali from india

  37. Algirdas says:

    Hi,

    You just need to write correct full path there.

  38. Samir says:

    Hi,

    I integrated the code in my site. While I m running the code, I got the result from fedex site that Error Number: 16465 with Description “DataBase Is Not available on IMS system”.

    Please help me and let me know what wrong with my code.

    Samir

  39. Visitor says:

    Thanks for great easy to use code, that actually works!

    IN case anyone is still wondering about package dimensions (length width height), I am posting here what I found, and it worked for me:

    I added this line to index.php

    $fedex->setDimensions($length,$width,$height);

    Added this function in fedex.php

    function setDimensions($length,$width,$height) {
    $this->length = $length;
    $this->width = $width;
    $this->height = $height;
    }

    I added these lines to fedex.php, in function getPrice(), between and XML. Fedex gave me error if not in correct order. For Units, IN means Inches. Not sure what other units you can use. Maybe try CM?

    $str .= ‘ ‘;
    $str .= ‘ ‘. $this->length .”;
    $str .= ‘ ‘. $this->width .”;
    $str .= ‘ ‘. $this->height .”;
    $str .= ‘ IN’;
    $str .= ‘ ‘;

  40. Visitor says:

    Oops, last post didn’t show my code properly. OK for package Dimensions (length width height), you need to include a section of XML called Dimensions, with sub sections called Length, Width, Height, and Units. Units = IN means Inches. It has to be placed between Payment and Package Count or fedex server will complain.

    IN

  41. Visitor says:

    ok sorry, here i try again

    Dimensions
    Length
    Width
    Height
    Units
    / Dimensions

  42. Visitor says:

    also, after dimensions XML, you can put declared value. The section is called DeclaredValue, and you need subsections for Value and CurrencyCode. CurrencyCode=USD is for dollars, not sure what else you can use.

    DeclaredValue
    Value
    CurrencyCode USD
    / DeclaredValue

    Ok sorry for all the posts… thanks again!

  43. david says:

    help me please
    I have this error
    Notice: Undefined index: ERROR in /hermes/bosweb/web124/b1242/ipw.studiotee/public_html/shop_dev/fedex.php on line 161

  44. Tyler says:

    How do you do multiple packages? I have look all around and can’t find the right syntax.

    Any ideas?

    TJ

  45. SP says:

    I am getting an error like this “fedexerror Object”

    This is my code

    fedex Object
    (
    [server] => https://gatewaybeta.fedex.com/GatewayDC
    [accountNumber] => 510087364
    [meterNumber] => 118507629
    [carrierCode] => FDXG
    [dropoffType] => REGULARPICKUP
    [service] => STANDARDOVERNIGHT
    [serviceName] => FedEx Standard Overnight
    [packaging] => YOURPACKAGING
    [weightUnits] => LBS
    [weight] => 12
    [originStateOrProvinceCode] => CA
    [originPostalCode] => 91344
    [originCountryCode] => US
    [destStateOrProvinceCode] => CT
    [destPostalCode] => 6031
    [destCountryCode] => US
    [payorType] => SENDER
    [error] => fedexerror Object
    (
    [number] => F821

    please help

    Thanks,
    SP

  46. Eric L says:

    SP,

    You are mixing an express service with a ground carrier code.

    Your Code:
    [carrierCode] => FDXG
    [service] => STANDARDOVERNIGHT

    Change to:
    [carrierCode] => FDXE
    [service] => STANDARDOVERNIGHT

  47. Robert says:

    It still doesn’t work with Ground service
    [carrierCode] => FDXG
    [dropoffType] => REGULARPICKUP
    [service] => FEDEXGROUND

    No Response.
    Any suggestions?

    Thanks

  48. Ross says:

    Add this to the for loop to get ground service to appear:

    Change

    $fedex->setCarrierCode(“FDXE”);

    To

    if(($service == “FEDEXGROUND”) || ($service == “GROUNDHOMEDELIVERY”)){
    $fedex->setCarrierCode(“FDXG”);
    }else{
    $fedex->setCarrierCode(“FDXE”);
    }

  49. rishi says:

    Warning: require_once(ROOT_DIR/libraries/USPS/xmlparser.php) [function.require-once]: failed to open stream: No such file or directory in C:\xampp\htdocs\Fedex\fedex.php on line 2

    Fatal error: require_once() [function.require]: Failed opening required ‘ROOT_DIR/libraries/USPS/xmlparser.php’ (include_path=’.;C:\xampp\php\pear\’) in C:\xampp\htdocs\Fedex\fedex.php on line 2

    This is the problem i am facing kindly tell me how to resolve it

  50. Algirdas says:

    ROOT_DIR/libraries/USPS/xmlparser.php this path looks like incorrect. Change it to correct one in C:\xampp\htdocs\Fedex\fedex.php on line 2

Leave a Reply