**free //============================================================== //=== USADRVAL: Service program to validate and standardize //=== a USA address. //=== Calls the USPS webtools API AddressValidateRequest. //==================================================================== // See US Postal Service documentation: // www.usps.com/business/web-tools-apis/address-information-api.htm#_Toc39492052 // www.usps.com/business/web-tools-apis/general-api-developer-guide.htm //==================================================================== // CRTRPGMOD MODULE(USADRVAL) // CRTSRVPGM SRVPGM(USADRVAL) EXPORT(*ALL) // CRTBNDDIR BNDDIR(ADRVAL_BND) TEXT('Address Validation Binding Dir') // ADDBNDDIRE BNDDIR(ADRVAL_BND) OBJ((USADRVAL *SRVPGM *DEFER)) // CRTDTAARA DTAARA(USPS_ID) TYPE(*CHAR) LEN(20) VALUE(your user id) //==================================================================== // Input address information is passed in a data structure. // The standardized address is returned, also in a data structure. // For ease of use, the same data structure layout is used for // input and output, but it doesn't have to be the same memory // in the caller. Use copy member USAdrValDS. //==================================================================== ctl-opt nomain bnddir('SQL_BND') option(*nodebugio: *srcstmt) ; //=== Prototypes ===================================================== /copy copy_mbrs,Srv_SQL_P //=== Parameter Data Structure Template ============================== /copy copy_mbrs,USAdrValDS // === Data area containing your USPS supplied User id. ============== // (The USPS supplied USER ID length is not clear, so I made it // longer than the 12-char one supplied to me..) dcl-ds USPS_ID dtaara len(20) qualified; end-ds; //=== USAdrVal ======================================================= dcl-proc USAdrVal export; dcl-pi USAdrVal likeds(USAdrValDS); pi likeds (USAdrValDS); end-pi; dcl-c SQLSUCCESS '00000'; dcl-c SQLNODATA '02000'; // XML returned from the USPS API dcl-s retXML char(2048) ccsid(*UTF8); // Returned outparm data structure dcl-ds po likeds(USAdrValDS); dcl-s ID varchar(20); // Get USPS UserID. in USPS_ID; ID = %trim(USPS_ID); clear po; // Call USPS Address Validate API. It returns an XML document. exec sql values QSYS2.HTTP_GET( 'http://production.shippingapis.com/ShippingAPI.dll' concat '?API=Verify&XML=' concat url_encode( '' concat '1' concat '
' concat '' concat :pi.Address1 concat '' concat '' concat :pi.Address2 concat '' concat '' concat :pi.City concat '' concat '' concat :pi.State concat '' concat '' concat :pi.Zip5 concat '' concat '' concat :pi.Zip4 concat '' concat '
' concat '
' ) ) into :retXML; if (SQLSTATE <> SQLSUCCESS); SQLProblem('USPS API Call'); endif; // Parse the XML document into program variables. Even if the API // returns an error the SQL should not fail since defaults are set exec sql select x.* into :po.Address1, :po.Address2, :po.City, :po.State, :po.Zip5, :po.Zip4 from xmltable ('AddressValidateResponse/Address' passing xmlparse(document :retXML) columns Address1 char(30) path 'Address1' default ' ', Address2 char(30) path 'Address2' default ' ', City Char(30) path 'City' default ' ', State char(2) path 'State' default ' ', zip5 char(5) path 'Zip5' default ' ', Zip4 char(4) path 'Zip4' default ' ' ) as x; if (SQLSTATE <> SQLSUCCESS); SQLProblem('XMLPARSE of Addr'); endif; // If a city was returned, assume it worked. if (po.City <> ' '); return po; endif; // If no city, then parse the error XML exec SQL select x.* into :po.Number, :po.Source, :po.Description from xmltable ('AddressValidateResponse/Address/Error' passing xmlparse(document :retXML) columns Number integer path 'Number', Source char(30) path 'Source', Description varChar(512) path 'Description' ) as x; if (SQLSTATE <> SQLSUCCESS); SQLProblem('XMLPARSE of Error'); endif; return po; end-proc USAdrVal;