Fedex Address Validation API with Using Coldfusion

The FedEx shipping API is beautiful––soundly documented and trouble-free to work with. Before you use the FedEx API in your own application, you must register with FedEx to get an API Key, password, account number, and meter number. It is not difficult to do. Click here, and follow the instructions. Afterward, you can test the following code using your own API access key.

In the function below, I used the following values in the application scoop:
Key = application.AVkey
Password = application.AVpassword
Account Number =  application.AVaccount
Meter Number = application.AVmeter
application.AVserver = https://gateway.fedex.com/xml

You may want to set these same values in your Application file.

The first six arguments below (CompanyName, StreetLine1, etc.) are self-explanatory. The final argument, (FatalList), is the odd one. It lists the states from which messages may return from FedEx. If an address is returned, the function has decided that the address is incorrect and needs to be reentered FedEx will also suggest a correct address. If an empty string is returned, then your address passed with flying colors.

If your address is correct, this function will return an empty string. If not, this will send you an message with suggested address, if one available.

   1: <cffunction name="AddressValidation" access="remote" returntype="string">
   2:  <cfargument name="CompanyName" type="string" required="no" default="">
   3:  <cfargument name="StreetLine1" type="string" required="yes">
   4:  <cfargument name="StreetLine2" type="string" required="no" default="">
   5:  <cfargument name="City"    type="string" required="yes">
   6:  <cfargument name="State"    type="string" required="yes">
   7:  <cfargument name="PostalCode" type="string" required="yes">
   8:  <cfargument name="FatalList" type="string" required="No" default="BOX_NUMBER_REQUIRED,RR_OR_HC_BOX_NUMBER_NEEDED,UNABLE_TO_APPEND_NON_ADDRESS_DATA,INSUFFICIENT_DATA,HOUSE_OR_BOX_NUMBER_NOT_FOUND,POSTAL_CODE_NOT_FOUND,SERVICE_UNAVAILABLE_FOR_ADDRESS">
   9: <cftry>
  10: <cfsavecontent variable="local.XMLPacket"><cfoutput>
  11: <ns:AddressValidationRequest
  12:  xsi:schemaLocation="http://www.fedex.com/templates/components/apps/wpor/secure/downloads/xml/Aug09/Advanced/AddressValidationService_v2.xsd"
  13:  xmlns:ns ="http://fedex.com/ws/addressvalidation/v2"
  14:  xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance">
  15:  <ns:WebAuthenticationDetail>
  16:  <ns:UserCredential>
  17:     <ns:Key>#application.AVkey#</ns:Key>
  18:     <ns:Password>#application.AVpassword#</ns:Password>
  19:  </ns:UserCredential>
  20:  </ns:WebAuthenticationDetail>
  21:  <ns:ClientDetail>
  22:  <ns:AccountNumber>#application.AVaccount#</ns:AccountNumber>
  23:  <ns:MeterNumber>#application.AVmeter#</ns:MeterNumber>
  24:  </ns:ClientDetail>
  25:  <ns:Version>
  26:  <ns:ServiceId>aval</ns:ServiceId>
  27:  <ns:Major>2</ns:Major>
  28:  <ns:Intermediate>0</ns:Intermediate>
  29:  <ns:Minor>0</ns:Minor>
  30:  </ns:Version>
  31:  <ns:RequestTimestamp>#dateformat(now(),"yyyy-mm-dd")#T#TimeFormat(now(),"HH:mm:ss")#</ns:RequestTimestamp>
  32:  <ns:Options>
  33:  <ns:CheckResidentialStatus>1</ns:CheckResidentialStatus>
  34:  <ns:MaximumNumberOfMatches>5</ns:MaximumNumberOfMatches>
  35:  <ns:StreetAccuracy>MEDIUM</ns:StreetAccuracy>
  36:  <ns:DirectionalAccuracy>MEDIUM</ns:DirectionalAccuracy>
  37:  <ns:CompanyNameAccuracy>MEDIUM</ns:CompanyNameAccuracy>
  38:  <ns:ConvertToUpperCase>1</ns:ConvertToUpperCase>
  39:  <ns:RecognizeAlternateCityNames>1</ns:RecognizeAlternateCityNames>
  40:  <ns:ReturnParsedElements>1</ns:ReturnParsedElements>
  41:  </ns:Options>
  42:  <ns:AddressesToValidate>
  43:  <ns:AddressId>1</ns:AddressId>
  44:  <cfif len(arguments.CompanyName)><ns:CompanyName>#arguments.CompanyName#</ns:CompanyName></cfif>
  45:  <ns:Address>
  46:     <ns:StreetLines>#trim(arguments.StreetLine1)#</ns:StreetLines>
  47:     <cfif len(arguments.StreetLine2)><ns:StreetLines>#trim(arguments.StreetLine2)#</ns:StreetLines></cfif>
  48:     <ns:City>#arguments.City#</ns:City>
  49:     <ns:StateOrProvinceCode>#arguments.State#</ns:StateOrProvinceCode>
  50:     <ns:PostalCode>#arguments.PostalCode#</ns:PostalCode>
  51:     <ns:CountryCode>US</ns:CountryCode>
  52:  </ns:Address>
  53:  </ns:AddressesToValidate>
  54: </ns:AddressValidationRequest>
  55: </cfoutput></cfsavecontent>
  56:  <cfhttp url="#application.AVserver#" port="443" method ="POST" throwonerror="yes">
  57:     <cfhttpparam name="name" type="XML" value="#local.XMLPacket#">
  58:  </cfhttp>
  59: 
  60:  <cfset vari    = XMLParse(CFHTTP.FileContent)>
  61: 
  62:  <cfset local.msg    = "">
  63:  <cfset local.changed    = "">
  64:  <cfset vari = vari.AddressValidationReply.AddressResults.ProposedAddressDetails>
  65:  <!--- ************************************************************************** --->
  66:  <!--- check fatal error                                                         --->
  67:  <!--- ************************************************************************** --->
  68:  <cfloop from="1" to="#ArrayLen(vari.XmlChildren)#" index="i">
  69:     <cfif listlast(vari.XmlChildren[i].XmlName,':') eq 'Changes'>
  70:     <cfif listfind(arguments.FatalList,vari.XmlChildren[i].XmlText)>
  71:      <cfset local.msg = 'False'>
  72:     </cfif>
  73:     </cfif>
  74:  </cfloop>
  75: 
  76:  <!--- ************************************************************************** --->
  77:  <!--- Post box address                                                            --->
  78:  <!--- ************************************************************************** --->
  79:  <cfif IsDefined('vari.ParsedAddress.ParsedStreetLine.Elements.Name.XmlText') and vari.ParsedAddress.ParsedStreetLine.Elements.Name.XmlText eq 'postOfficeBoxNumber'>
  80:     <cfif not len(local.msg)>
  81:     <cfset local.msg = "FedEx cannot deliver to P.O. boxes">
  82:     </cfif>
  83:  </cfif>
  84:  <!--- ************************************************************************** --->
  85:  <!--- check if address changed                                                    --->
  86:  <!--- ************************************************************************** --->
  87:  <cfif not len(local.msg)>
  88:     <cfloop from="1" to="#ArrayLen(vari.ParsedAddress.ParsedStreetLine.XmlChildren)#" index="i">
  89:     <cfif vari.ParsedAddress.ParsedStreetLine.Elements[i].Changes.XmlText neq 'NO_CHANGES'>
  90:      <cfset local.changed = "1">
  91:     </cfif>
  92:     </cfloop>
  93:     <cfif vari.ParsedAddress.ParsedCity.Elements.Changes.XmlText neq 'NO_CHANGES'>
  94:     <cfset local.changed = "1">
  95:     </cfif>
  96:     <cfif vari.ParsedAddress.ParsedStateOrProvinceCode.Elements.Changes.XmlText neq 'NO_CHANGES'>
  97:     <cfset local.changed = "1">
  98:     </cfif>
  99:     <cfif vari.ParsedAddress.ParsedStateOrProvinceCode.Elements.Changes.XmlText neq 'NO_CHANGES'>
 100:     <cfset local.changed = "1">
 101:     </cfif>
 102:     <cfif vari.ParsedAddress.ParsedPostalCode.Elements.Changes.XmlText neq 'NO_CHANGES'>
 103:     <cfset local.changed = "1">
 104:     </cfif>
 105:  </cfif>
 106:  <!--- ************************************************************************** --->
 107:  <!--- Fedex Retrun Same Address . a Workaround                                 --->
 108:  <!--- ************************************************************************** --->
 109:  <cfset local.match = 0>
 110:  <cfset local.StreetLines = trim(replace('#arguments.StreetLine1# #arguments.StreetLine2#',' ',' ','all'))>
 111:  <cfif local.StreetLines eq vari.Address.StreetLines.XmlText>
 112:     <cfset local.match = local.match+1>
 113:  </cfif>
 114:  <cfif trim(arguments.City) eq vari.Address.City.XmlText>
 115:     <cfset local.match = local.match+1>
 116:  </cfif>
 117:  <cfif trim(arguments.State) eq vari.Address.StateOrProvinceCode.XmlText>
 118:     <cfset local.match = local.match+1>
 119:  </cfif>
 120:  <cfif trim(listfirst(arguments.PostalCode,'-')) eq listfirst(vari.Address.PostalCode.XmlText,'-')>
 121:     <cfset local.match = local.match+1>
 122:  </cfif>
 123: 
 124:  <!--- ************************************************************************** --->
 125:  <!--- get the new address                                                        --->
 126:  <!--- ************************************************************************** --->
 127:  <cfif val(local.changed) and local.match neq 4>
 128:     <cfset ProposedAddress = ArrayNew(1)>
 129:     <cfloop from="1" to="#ArrayLen(vari.Address.XmlChildren)#" index="i">
 130:     <cfset ArrayAppend(ProposedAddress,vari.Address.XmlChildren[i].XmlText)>
 131:     </cfloop>
 132:     <cfset local.ProposedAddress = ArrayToList(ProposedAddress,'<br />')>
 133:  <cfelse>
 134:     <cfset local.ProposedAddress = "">
 135:  </cfif>
 136: 
 137:  <cfset local.out = "#local.msg##local.ProposedAddress#">
 138:  <cfcatch>
 139:  <cfset local.out = "FedEx cannot verify Your address at this time. Please try again.">
 140:  </cfcatch>
 141: </cftry>
 142:  <cfreturn trim(local.out)>
 143:  </cffunction>
Show/Hide Line Numbers . Full Screen . Plain


Name  
(required)
Email  
(required - never shown publicly)
Web Site  
Notify me of new comments via email.
Notify me of replies via email.
10 Comments :
Jon
on Friday 07 October 2011 04:04 PM
Thanks for the code. This looks like exactly what I need. I've setup the account as instructed and have entered my meeter #, account #, etc., in the code, but it doesn't seem to be authinticating. When I dump the CFHTTP.FileContent var from the call to https://gateway.fedex.com/xml, I get "Authentication Failed" for AddressValidationReply.Notifications.message. I have also tried using https://gatewaybeta.fedex.com.

Is there a different URL to post to? Or something I'm missing? Thanks!
on Friday 07 October 2011 05:36 PM
https://gateway.fedex.com/xml is correct. That still in my production server and it works. You get the authentication error because your code works correctly. I?m not sure do you have to add 'Address Validation' API accesses to your account, inside Fedex Member area or does Fedex take time to actually activate your account. (I have a vague memory I had to go through something like that).
Andy
on Tuesday 10 January 2012 12:14 PM
No. Still "Authentication Failed."

on Tuesday 10 January 2012 10:14 AM
Hi Andy, is your issue solved?

Andy
on Monday 02 January 2012 04:49 PM
I'm having the same "Authentication Failed" issue as Jon. Can anyone confirm this might be due to a Settings issue within the FedEx member account itself?

Brian
on Tuesday 14 June 2011 04:09 PM
Sam - got this working (i think). Issue was that the URL I was posting too wasn't correct.

Changed it to post to the XML expectant URL on the Fedex side and this seems to be working now. Appreciate your help.
Brian
on Tuesday 14 June 2011 09:17 AM
Ok, thanks. I'll figure out what's what then. FWIW, this is the error msg I keep getting back from the fedex server:

<?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><soapenv:Fault><faultcode>soapenv:Client</faultcode><faultstring>The message must be an instance of: {http://schemas.xmlsoap.org/soap/envelope/}Envelope</faultstring><detail><con:fault xmlns:con="http://www.bea.com/wli/sb/context"><con:errorCode>9999</con:errorCode><con:reason>The message must be an instance of: {http://schemas.xmlsoap.org/soap/envelope/}Envelope</con:reason><con:details><err:InvalidEnvelope xmlns:err="http://www.bea.com/wli/sb/errors"><err:localpart>AddressValidationRequest</err:localpart><err:namespace>http://fedex.com/ws/addressvalidation/v2</err:namespace></err:InvalidEnvelope></con:details></con:fault></detail></soapenv:Fault></soapenv:Body></soapenv:Envelope>
on Tuesday 14 June 2011 01:39 PM
It’s possible the address string breaking the xml. XmlFormat() it or try out with a plain string like, 800, 42 street, NY, 10004 …
Brian
on Monday 13 June 2011 03:23 PM
Saman - does this function still work for you? We're testing out something similar with Fedex and I came across this code. It looks perfect for what we need.

When i dropped it into our environment with our Fedex API keys etc, I'm getting an error using this function. So I figured I'd reach out and see if this was still working for you or if something had changed and this function wasn't working anymore with Fedex.

Thanks,
Brian
on Monday 13 June 2011 05:26 PM
I just tested this code with my fedex keys, and it still works.