I was also trying to solve this problem with Payeezy. I'm probably a day late and a dollar short, however I got this to work. I made several changes to what I was having trouble with and/or with Nick's original code:
- Removed the charset declaration in the transaction xml;
- Changed 'text' to 'application'
- For me to get the encryption to match the website's testing encryption, I changed the carriage return to
char(10)
, and
- Changed the first header entry from 'CGGE4_API' to 'GGE_API'
Just FYI, if you're using v11, you don't need any headers or hashing code, just the xml.
Here's my entire testing code, including some code to break down the returning xml.
Request Code:
<cfset hmac_key="WO9QVjnis6eBb5oOYmA_DSShc82gteFw">
<cfset trans="<?xml version='1.0' ?><Transaction><ExactID>XX55555-55</ExactID><Password>testtest11</Password><Card_Number>5454545454545454</Card_Number><CardHoldersName>Bix Dirigible</CardHoldersName><Transaction_Type>00</Transaction_Type><Expiry_Date>0916</Expiry_Date><DollarAmount>12.03</DollarAmount></Transaction>">
<cfset key_id="555555">
<cfset content_digest=lcase(Hash(trans,"SHA"))>
<cfset curDate = Now()>
<cfset utcDate = DateConvert("local2utc", curDate)>
<cfset udate=dateformat(utcdate,"yyyy-mm-dd")><cfset utime=timeformat(utcdate,"HH:mm:ss")>
<cfset x_time=udate&"T"&utime&"Z" >
<cfset submitfinalhmac="POST"&chr(10)&"application/xml"&chr(10)&content_digest&chr(10)&x_time&chr(10)&"/transaction/v12">
<cfoutput>
content_digest: #content_digest#<BR />
<BR />
<!--- Ben Nadel's encrypting code, http://www.bennadel.com/blog/1971-authenticating-twilio-request-signatures-using-coldfusion-and-hmac-sha1-hashing.htm --->
<cfset secretKeySpec = createObject("java", "javax.crypto.spec.SecretKeySpec" ).init( toBinary( toBase64( hmac_key ) ), "HmacSHA1" )/>
<cfset mac = createObject( "java", "javax.crypto.Mac" ).getInstance( "HmacSHA1" )/>
<cfset mac.init( secretKeySpec ) />
<cfset encryptedBytes = mac.doFinal( toBinary( toBase64( submitfinalhmac ) ) ) />
<cfset secureSignature = createObject( "java", "org.apache.commons.codec.binary.Base64" ).encodeBase64( encryptedBytes ) />
<cfset hmac_value = toString( secureSignature ) />
#hmac_value#
<BR /><BR />
</cfoutput>
<cfhttp method="Post" url="https://api.demo.globalgatewaye4.firstdata.com/transaction/v12"
useragent="Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.1599.69 Safari/537.36">
<cfhttpparam name="Authorization" type="header" value="GGE4_API #key_id#:#hmac_value#">
<cfhttpparam name="x-gge4-date" type="header" value="#x_time#">
<cfhttpparam name="x-gge4-content-sha1" type="header" value="#content_digest#">
<cfhttpparam name="content-type" type="header" value="application/xml">
<cfhttpparam name="accept" type="header" value="application/xml">
<cfhttpparam name="transaction_body" type="xml" value="#trans#" />
</cfhttp>
Response code:
<cfset postresult=HTMLEditFormat(cfhttp.fileContent)>
<cfset postresult=replace(postresult,"<","<","all")>
<cfset postresult=replace(postresult,">",">","all")>
<cfset postresult=replace(postresult,"##","-","all")>
<cfoutput>
#postresult#<BR />
<cfset badtransaction=0><cfset badtransactionmessage="">
<cfset rawerror="">
<cfif findnocase("bad request",postresult)><cfset rawerror=trim(gettoken(postresult,2,"-"))>
<cfset badtransactionmessage=badtransactionmessage&rawerror>
<cfset badtransaction=1>
</cfif>
<cfif findnocase("unauthorized request",postresult)><cfset rawerror=trim(gettoken(postresult,2,"."))>
<cfset badtransactionmessage=badtransactionmessage&rawerror>
<cfset badtransaction=1>
</cfif>
<cfset resultarray=arraynew(2)>
<cfset line=1>
<cfset enterflag=0>
<cfset startflag=0>
<cfloop index="getchar" from="1" to="#len(postresult)-22#">
<cfif mid(postresult,getchar,9) is "<exactid>" ><cfset startflag=1></cfif>
<cfif mid(postresult,getchar,19) is "</TransactionResult>" ><cfset startflag=0></cfif>
<cfif startflag is 1>
<cfif enterflag is 2>
<cfif mid(postresult,getchar,1) is "<"><cfset enterflag=0><cfset line++>
<cfelse>
<cfset resultarray[line][2]=resultarray[line][2]&mid(postresult,getchar,1)>
</cfif>
</cfif>
<cfif enterflag is 1>
<cfif mid(postresult,getchar,1) is ">" >
<cfset enterflag=2>
<cfelse>
<cfset resultarray[line][1]=resultarray[line][1]&mid(postresult,getchar,1)>
</cfif>
</cfif>
<cfif enterflag is 0>
<cfif mid(postresult,getchar,1) is "<" and mid(postresult,getchar+1,1) is not "/">
<cfset enterflag=1>
<cfset resultarray[line][1]="">
<cfset resultarray[line][2]="">
</cfif>
</cfif>
</cfif>
</cfloop>
<cfdump var="#resultarray#">
<cfset transactiontag="">
<cfset authorizationnum="">
<cfset transactionapproved="">
<cfset exactmessage="">
<cfset exactresponsecode="">
<cfset sequenceno="">
<cfset retrievalrefno="">
<cfset cardtype="">
<cfset bankmessage="">
<cfloop index="getresponses" from="1" to ="#arraylen(resultarray)#">
<cfif resultarray[getresponses][1] is "Transaction_Tag"><cfset transactiontag=resultarray[getresponses][2]></cfif>
<cfif resultarray[getresponses][1] is "Authorization_Num"><cfset AuthorizationNum=resultarray[getresponses][2]></cfif>
<cfif resultarray[getresponses][1] is "Transaction_Approved"><cfset TransactionApproved=resultarray[getresponses][2]></cfif>
<cfif resultarray[getresponses][1] is "EXact_Message"><cfset EXactMessage=resultarray[getresponses][2]></cfif>
<cfif resultarray[getresponses][1] is "EXact_Resp_Code"><cfset EXactResponseCode=resultarray[getresponses][2]></cfif>
<cfif resultarray[getresponses][1] is "SequenceNo"><cfset SequenceNo=resultarray[getresponses][2]></cfif>
<cfif resultarray[getresponses][1] is "Retrieval_Ref_No"><cfset RetrievalRefNo=resultarray[getresponses][2]></cfif>
<cfif resultarray[getresponses][1] is "CardType"><cfset CardType=resultarray[getresponses][2]></cfif>
<cfif resultarray[getresponses][1] is "bank_message"><cfset bankmessage=resultarray[getresponses][2]></cfif>
</cfloop>
<BR />
#transactiontag#<BR />
#authorizationnum# <BR />
#transactionapproved# <BR />
#exactmessage#<BR />
#exactresponsecode#<BR />
#sequenceno#<BR />
#retrievalrefno#<BR />
#cardtype#<BR />
#bankmessage#<BR />
<cfif trim(transactionapproved) is not "true" and trim(transactionapproved) is not "">
<cfset badtransaction=2>
<cfset badtransactionmessage=badtransactionmessage&bankmessage>
</cfif>
<cfif badtransaction gt 0>
---#badtransactionmessage#<BR />
</cfif>
</cfoutput>