<!--- 
  Filename:     VerisignPayflowPro.cfm
  Created by:   Nate Weiss (NMW)
  Please Note:  Creates the <CF_VerisignPayflowPro> Custom Tag
  Purpose:      Custom Tag wrapper around VeriSign's Java API
--->

<!--- Tag Parameters --->
<!--- *Payflow Server/Configuration --->
<CFPARAM NAME="ATTRIBUTES.ServerName" TYPE="string">
<CFPARAM NAME="ATTRIBUTES.ServerPort" TYPE="numeric" DEFAULT="443">
<CFPARAM NAME="ATTRIBUTES.ServerTimeout" TYPE="numeric" DEFAULT="30">
<CFPARAM NAME="ATTRIBUTES.ProxyServer" TYPE="string" DEFAULT="">
<CFPARAM NAME="ATTRIBUTES.ProxyPort" TYPE="numeric" DEFAULT="0">
<CFPARAM NAME="ATTRIBUTES.ProxyUsername" TYPE="string" DEFAULT="">
<CFPARAM NAME="ATTRIBUTES.ProxyPassword" TYPE="string" DEFAULT="">
<CFPARAM NAME="ATTRIBUTES.CertPath" TYPE="string" DEFAULT="">
<!--- *Vendor/Partner Credentials --->
<CFPARAM NAME="ATTRIBUTES.PayflowPartner" TYPE="string" DEFAULT="VeriSign">
<CFPARAM NAME="ATTRIBUTES.PayflowVendor" TYPE="string">
<CFPARAM NAME="ATTRIBUTES.PayflowPassword" TYPE="string">
<CFPARAM NAME="ATTRIBUTES.PayflowUser" TYPE="string" DEFAULT="#ATTRIBUTES.PayflowVendor#">
<!--- *Transaction Information --->
<CFPARAM NAME="ATTRIBUTES.ParmList" TYPE="string" DEFAULT="">
<CFPARAM NAME="ATTRIBUTES.TrxType" TYPE="string" DEFAULT="S">
<CFPARAM NAME="ATTRIBUTES.Tender" TYPE="string" DEFAULT="C">
<CFPARAM NAME="ATTRIBUTES.Acct" TYPE="string" DEFAULT="">
<CFPARAM NAME="ATTRIBUTES.ExpDate" TYPE="string" DEFAULT="">
<CFPARAM NAME="ATTRIBUTES.Amt" TYPE="string" DEFAULT="">
<CFPARAM NAME="ATTRIBUTES.Comment1" TYPE="string" DEFAULT="">
<CFPARAM NAME="ATTRIBUTES.Comment2" TYPE="string" DEFAULT="">
<CFPARAM NAME="ATTRIBUTES.AVSStreet" TYPE="string" DEFAULT="">
<CFPARAM NAME="ATTRIBUTES.AVSZip" TYPE="string" DEFAULT="">
<CFPARAM NAME="ATTRIBUTES.OrigID" TYPE="string" DEFAULT="">
<!--- *Return variable --->
<CFPARAM NAME="ATTRIBUTES.ReturnVariable" TYPE="variableName" DEFAULT="PayflowResult">

<!--- The transaction type should always be uppercase --->
<CFSET ATTRIBUTES.TrxType = UCase(ATTRIBUTES.TrxType)>

<!--- If a specific ParmList is provided to describe transation --->
<CFIF ATTRIBUTES.ParmList NEQ "">
  <CFSET ParmList = Attributes.ParmList>

<!--- Otherwise, construct ParmList from attributes about sale --->  
<CFELSE>
  <!--- These are the Transaction types we know how to handle --->
  <CFSET SupportedTrxTypes = "S,C,A,D,V,F,I">
  
  <!--- Throw error if unsupported transaction type is attempted --->
  <CFIF ListFind(SupportedTrxTypes, ATTRIBUTES.TrxType) EQ False>
    <CFTHROW 
      MESSAGE="Unsupported Transaction Type."
      DETAIL="Tag supports these TrxType values only: #SupportedTrxTypes#">
  </CFIF>

  <!--- Construct Payflow Parameter List to describe the transation --->
  <CFSET ParmList = "TRXTYPE=#ATTRIBUTES.TrxType#" 
    & "&PARTNER=#ATTRIBUTES.PayflowPartner#&VENDOR=#ATTRIBUTES.PayflowVendor#"
    & "&USER=#ATTRIBUTES.PayflowUser#&PWD=#ATTRIBUTES.PayflowPassword#">
    
  <!--- Add credit card/amount information for most transactions --->  
  <CFIF ListFind("S,C,A,F", ATTRIBUTES.TrxType)>
    <CFSET ParmList = ParmList 
      & "&TENDER=#ATTRIBUTES.Tender#&ACCT=#ATTRIBUTES.Acct#"
      & "&EXPDATE=#ATTRIBUTES.ExpDate#&AMT=#ATTRIBUTES.AMT#">
  <!--- For other transactions, add the original transcation number --->
  <CFELSE>
    <CFSET ParmList = ParmList 
      & "&ORIGID=#ATTRIBUTES.OrigID#">
  </CFIF>


    
  <!--- Add comments to the parameter list, if supplied --->
  <CFIF ATTRIBUTES.Comment1 NEQ "">
    <CFSET ParmList = ListAppend(ParmList, "COMMENT1[#Len(ATTRIBUTES.Comment1)#]=#ATTRIBUTES.Comment1#", "&")>
  </CFIF>
  <CFIF ATTRIBUTES.Comment2 NEQ "">
    <CFSET ParmList = ListAppend(ParmList, "COMMENT2[#Len(ATTRIBUTES.Comment2)#]=#ATTRIBUTES.Comment2#", "&")>
  </CFIF>
  <CFIF ATTRIBUTES.AVSStreet NEQ "">
    <CFSET ParmList = ListAppend(ParmList, "Street[#Len(ATTRIBUTES.AVSStreet)#]=#ATTRIBUTES.AVSStreet#", "&")>
  </CFIF>
  <CFIF ATTRIBUTES.AVSZip NEQ "">
    <CFSET ParmList = ListAppend(ParmList, "ZIP[#Len(ATTRIBUTES.AVSZip)#]=#ATTRIBUTES.AVSZip#", "&")>
  </CFIF>

</CFIF>


<!--- Create an instance of the Payflow Pro API Object --->
<CFOBJECT 
  TYPE="JAVA"
  ACTION="Create"
  NAME="pn"
  CLASS="com.Verisign.payment.PFProAPI">

<!--- Set the certificate path, if provided --->  
<CFIF ATTRIBUTES.CertPath NEQ "">
  <CFSET pn.SetCertPath(ATTRIBUTES.CertPath)>
</CFIF>  

<!--- Create the Payflow processing context --->
<CFSET pn.CreateContext(
  ATTRIBUTES.ServerName, 
  ATTRIBUTES.ServerPort, 
  ATTRIBUTES.ServerTimeout, 
  ATTRIBUTES.ProxyServer, 
  ATTRIBUTES.ProxyPort, 
  ATTRIBUTES.ProxyUsername, 
  ATTRIBUTES.ProxyPassword)>

<!--- Submit the transation and keep Payflow's response --->
<CFSET ResultString = pn.SubmitTransaction(ParmList)>

<!--- We are done with Payflow object now, so destroy it --->
<CFSET pn.DestroyContext()>
<CFSET pn = "">

<!--- Create structure to hold Payflow's response --->
<!--- This will get returned to the calling template --->
<CFSET stResult = StructNew()>
<CFSET stResult.ParmList = ParmList>
<CFSET stResult.ResultString = ResultString>

<!--- Copy each value found in the ResultString --->
<!--- to a corresponding key in the stResult structure --->
<CFLOOP LIST="#ResultString#" INDEX="ThisPair" DELIMITERS="&">
  <CFSET PairName = ListFirst(ThisPair, "=")>
  <CFSET PairValue = URLDecode(ListRest(ThisPair, "="))>
  <CFSET stResult[PairName] = PairValue>
</CFLOOP>

<!--- Return the result to the calling template --->
<CFSET "Caller.#ATTRIBUTES.ReturnVariable#" = stResult> 