CFX_PFPro_Java Download

Not sure I understand why PayPal would take down their only ColdFusion related download but in case you can't find a backup copy, here you go.

Download Files

CyberSource ColdFusion Solution

I have received this question so many times via email I decided to post a blog entry for it. CyberSource is a payment solution I have used in the past for a product called Bill Me Later but it can be used for a number of other solutions as well.

Here are the instructions for setting this payment solution up.

1. Download the Simple Order API (32-bit). I installed the Windows Java version.

2. Modify your jvm.config file. This depends on what version of ColdFusion you are using. Also, you will need to edit this file manually because the CyberSource arguments need to appear first. Do not edit the JVM arguments in the ColdFusion administrator because it will add them to the end which will not work.

ColdFusion MX 6.x

Notice that the following line below has been commented out because it interferes with the CyberSource JVM arguments.

#-Djavax.xml.parsers.SAXParserFactory=com.macromedia.crimson.jaxp.SAXParserFactoryImpl -Djavax.xml.parsers.DocumentBuilderFactory=com.macromedia.crimson.jaxp.DocumentBuilderFactoryImpl

#
# VM configuration
#
# Where to find JVM, if {java.home}/jre exists then that JVM is used
# if not then it must be the path to the JRE itself
java.home=D:/CFusionMX/runtime/jre
#
# If no java.home is specified a VM is located by looking in these places in this
# order:
#
# 1) bin directory for java.dll (windows) or lib/<ARCH>/libjava.so (unix)
# 2) ../jre
# 3) registry (windows only)
# 4) JAVA_HOME env var plus jre (ie $JAVA_HOME/jre)
#

# Arguments to VM
java.args=-server -DJINTEGRA_NATIVE_MODE -DJINTEGRA_PREFETCH_ENUMS -Xms256m -Xmx512m -Dsun.io.useCanonCaches=false -Xbootclasspath/a:"{application.home}/../lib/webchartsJava2D.jar" -XX:MaxPermSize=128m -XX:+UseParallelGC
#-Djavax.xml.parsers.SAXParserFactory=com.macromedia.crimson.jaxp.SAXParserFactoryImpl -Djavax.xml.parsers.DocumentBuilderFactory=com.macromedia.crimson.jaxp.DocumentBuilderFactoryImpl

#
# commas will be converted to platform specific separator and the result will be passed
# as -Djava.ext.dirs= to the VM
java.ext.dirs={jre.home}/lib/ext

#
# where to find shared libraries
java.library.path={application.home}/../lib,{application.home}/../jintegra/bin,{application.home}/../jintegra/bin/international,{application.home}/../lib/_nti40/bin
system.path.first=false

# JVM classpath
java.class.path=E:/WEBROOT/simapi-2.0.0/lib/cybsclients.jar,E:/WEBROOT/simapi-2.0.0/lib/cybssecurity.jar,E:/WEBROOT/simapi-2.0.0/lib/xalan.jar,E:/WEBROOT/simapi-2.0.0/lib/xercesImpl.jar,E:/WEBROOT/simapi-2.0.0/lib/xml-apis.jar,{application.home}/servers/lib,{application.home}/../lib/cfusion.jar,{application.home}/../lib,{application.home}/../runtime/lib/jrun.jar,{application.home}/../runtime/lib

ColdFusion MX 7.x

#
# VM configuration
#
# Where to find JVM, if {java.home}/jre exists then that JVM is used
# if not then it must be the path to the JRE itself
java.home=C:/CFusionMX7/runtime/jre
#
# If no java.home is specified a VM is located by looking in these places in this
# order:
#
# 1) bin directory for java.dll (windows) or lib/<ARCH>/libjava.so (unix)
# 2) ../jre
# 3) registry (windows only)
# 4) JAVA_HOME env var plus jre (ie $JAVA_HOME/jre)
#

# Arguments to VM
java.args=-server -DJINTEGRA_NATIVE_MODE -DJINTEGRA_PREFETCH_ENUMS -Xms256m -Xmx512m -Dsun.io.useCanonCaches=false -XX:MaxPermSize=128m -Dcoldfusion.rootDir={application.home}/../ -Dcoldfusion.libPath={application.home}/../lib -XX:+UseParallelGC -Dcoldfusion.classPath={application.home}/../../classes,{application.home}/../lib/updates,{application.home}/../lib/,{application.home}/../gateway/lib/,{application.home}/../wwwroot/WEB-INF/cfform/jars,C:/CFusionMX7/wwwroot/WEB-INF/classes,C:/CFusionMX7/wwwroot/WEB-INF/classes/VeriSign.jar

#
# commas will be converted to platform specific separator and the result will be passed
# as -Djava.ext.dirs= to the VM
java.ext.dirs={jre.home}/lib/ext

#
# where to find shared libraries
java.library.path={application.home}/../lib,{application.home}/../jintegra/bin,{application.home}/../jintegra/bin/international
system.path.first=false

#
# set the current working directory - useful for Windows to control
# the default search path used when loading DLLs since it comes
# before system directory, windows directory and PATH
java.user.dir={application.home}/../../lib

# JVM classpath
#java.class.path={application.home}/servers/lib,{application.home}/../lib/macromedia_drivers.jar,{application.home}/lib/cfmx_mbean.jar,{application.home}/lib
java.class.path=C:/WEBROOT/simapi-2.0.0/lib/cybsclients.jar,C:/WEBROOT/simapi-2.0.0/lib/cybssecurity.jar,C:/WEBROOT/simapi-2.0.0/lib/xalan.jar,C:/WEBROOT/simapi-2.0.0/lib/xercesImpl.jar,C:/WEBROOT/simapi-2.0.0/lib/xml-apis.jar,{application.home}/servers/lib,{application.home}/../lib/macromedia_drivers.jar,{application.home}/lib/cfmx_mbean.jar,{application.home}/lib

3. Restart ColdFusion

4. Run the following test script.

<cfobject type="java" name="oClient" class="com.cybersource.ws.client.Client" action="create">
<cfobject type="java" name="oClientProperties" class="java.util.Properties" action="create">
<cfobject type="java" name="oRequestProperties" class="java.util.Properties" action="create">
<cfobject type="java" name="oHashMapResponse" class="java.util.HashMap" action="create">

<cfscript>
   oClientProperties.setProperty("merchantID", "your merchant id");
   oClientProperties.setProperty("targetAPIVersion", "1.7");
   oClientProperties.setProperty("keysDirectory", "E:/WEBROOT/simapi-2.0.0/keys");
   oClientProperties.setProperty("sendToProduction", "false");
   oClientProperties.setProperty("enableLog", "true");
   oClientProperties.setProperty("logDirectory", "E:/WEBROOT/simapi-2.0.0/logs");
   oClientProperties.setProperty("logMaximumSize", "10");
   
   oRequestProperties.setProperty( "ccAuthService_run", "true" );
   oRequestProperties.setProperty( "merchantReferenceCode", "10000" );
   oRequestProperties.setProperty( "billTo_firstName", "John" );
   oRequestProperties.setProperty( "billTo_lastName", "Doe" );
   oRequestProperties.setProperty( "billTo_street1", "1295 Charleston Road" );
   oRequestProperties.setProperty( "billTo_city", "Mountain View" );
   oRequestProperties.setProperty( "billTo_state", "CA" );
   oRequestProperties.setProperty( "billTo_postalCode", "94043" );
   oRequestProperties.setProperty( "billTo_country", "US" );
   oRequestProperties.setProperty( "billTo_email", "nobody@cybersource.com" );
   oRequestProperties.setProperty( "billTo_ipAddress", "10.7.7.7" );
   oRequestProperties.setProperty( "billTo_phoneNumber", "650-965-6000" );
   oRequestProperties.setProperty( "shipTo_firstName", "Jane" );
   oRequestProperties.setProperty( "shipTo_lastName", "Doe" );
   oRequestProperties.setProperty( "shipTo_street1", "100 Elm Street" );
   oRequestProperties.setProperty( "shipTo_city", "San Mateo" );
   oRequestProperties.setProperty( "shipTo_state", "CA" );
   oRequestProperties.setProperty( "shipTo_postalCode", "94401" );
   oRequestProperties.setProperty( "shipTo_country", "US" );
   oRequestProperties.setProperty( "card_accountNumber", "4111111111111111" );
   oRequestProperties.setProperty( "card_expirationMonth", "12" );
   oRequestProperties.setProperty( "card_expirationYear", "2021" );
   oRequestProperties.setProperty( "purchaseTotals_currency", "USD" );
   oRequestProperties.setProperty( "purchaseTotals_grandTotalAmount", "56.78" );
   
   try {
      oHashMapResponse = oClient.runTransaction(oRequestProperties, oClientProperties);   
      if (oHashMapResponse.get("decision") EQ "ACCEPT")
         requestID = oHashMapResponse.get("requestID");
   } // try
   // do some error handling, probably need a couple-three catches    catch ("com.cybersource.ws.client.ClientException" e) {
      writeoutput("#e.getLogString()#");
   } // catch client exception    catch ("com.cybersource.ws.client.FaultException" e) {
      writeoutput("#e.getLogString()#");
   } // catch client exception    
   //oHashMapResponse = oClient.runTransaction(oRequestProperties, oClientProperties);    
</cfscript>

<cfdump var="#oHashMapResponse#">

That should be it. Also make sure you set the following directories to your specific path.

keysDirectory
logDirectory

My Favorite ColdFusion Tags

I was just doing a little coding and thought I would post on a few of my favorite ColdFusion tags. I know what you're saying, how can you just have a few, they're all great! Yes, I know this!

1. cfcomponent - The mother of all ColdFusion tags!

2. cfdump - Very helpful in debugging.

3. cfswitch - Fastest way to switch on a value.

4. cftry/cfcatch - Best way to suppress and deal with errors.

5. cfquery - Most likely the widest used tag in my arsenal.

6. cfqueryparam - One of the best methods to force validation and stop hack attempts.

7. cfsilent - One of the ways to cut whitespace from your resulting ColdFusion pages.

8. cfsavecontent - A nice little nugget to know when you need to save and reuse a block of whatever.

9. cfoutput - Obviously can't forget about this baby, again, useful all over the place.

10. cfloop - Used in conjunction with the former tag anf with lists mainly.

New PayflowPro ColdFusion Component

Well it's been a long road trying to figure out why I could never get CFX_PayflowPro to work on ColdFusion 8. Nevertheless with Dan Vega and Mark Mandel's support I now have a full featured component that can do the following.

  • Authorizations
  • Delayed Captures
  • Sales
  • Voids
  • Credits
  • Voice Authorizations
  • Inquiries

I won't post the entire tag in code view but I will make it available as part of Dan Vega's RIAForge project very soon. In the meantime, here is a zip file containing both my verisign.cfc and Dan's project together.

Download Code

Note: In order for this component to work out of the box you must copy the entire payflowpro directory right under the verisign.cfc component which is the way it unzips. Also, place the following code snippet in your application.cfc.

<cfif NOT IsDefined("server.init") OR StructKeyExists(url,"reinit")>
         
<!--- Load paths --->
<cfset loadPaths = arrayNew(1)>
<cfset loadPaths[1] = "\path\to\payflowpro\lib\Verisign.jar">

<!--- Create loader --->
<cfset loader = createObject("component","path.to.payflowpro.com.compoundtheory.javaloader.JavaLoader").init(loadPaths)>
      
<!--- Create class instance --->
<cfset server.pfpro = loader.create("path.to.payflowpro.com.Verisign.payment.PFProAPI")>

<!--- Set server variable --->
<cfset server.init = true>

</cfif>

Here is a sample transaction that processes a sale.

<cfinvoke component="path.to.verisign" method="processSale" returnvariable="PayFlowProResult">
<cfinvokeargument name="HOST_ADDRESS" value="test-payflow.verisign.com">
<cfinvokeargument name="HOST_PORT" value="443">
<cfinvokeargument name="TIMEOUT" value="30">
<cfinvokeargument name="USER" value="username">
<cfinvokeargument name="PWD" value="password">
<cfinvokeargument name="PARTNER" value="partner">
<cfinvokeargument name="VENDOR" value="vendor">
<cfinvokeargument name="TRXTYPE" value="S">
<cfinvokeargument name="TENDER" value="C">
<cfinvokeargument name="ACCT" value="4111111111111111">
<cfinvokeargument name="EXPDATE" value="1207">
<cfinvokeargument name="AMT" value="1.00">
<cfinvokeargument name="INVNUM" value="123456">
<cfinvokeargument name="CUSTCODE" value="123456">
<cfinvokeargument name="LOCALTAXAMT" value="0.00">
</cfinvoke>

<cfdump var="#PayFlowProResult#">

ColdFusion 8 & CFXPayflowPro

Well unfortunately I have a bit of work ahead of me because the custom tag I'm using for PayPal payments doesn't work in ColdFusion 8. I have probably spent nearly 40 hours on attempting to get it to work but no luck. But alas there is hope! Dan Vega created a new way to call the processor through the JavaLoader created by Mark Mandel from Compound Theory. It's pretty slick but I plan on packaging it a little nicer and cleaner so I can more readily reuse it across about 20 sites. Nice work Dan and Mark!

Here is a sneak peak at the code. You can download your copy at cfpayflowpro.riaforge.org.

<!--- PayFlow Pro Paramaters --->
<cfset pp = structNew()>
<cfset pp.user = "user">
<cfset pp.vendor = "">
<cfset pp.partner = "VeriSign">
<cfset pp.pwd = "password">
<cfset pp.trxtype = "S">
<cfset pp.tender = "C">
<cfset pp.acct = "4111111111111111">
<cfset pp.expdate = "0108">
<cfset pp.accttype = "Visa">
<cfset pp.amt = "1.00">
<cfset pp.currency = "USD">
<cfset pp.cvv2 = "111">
<cfset pp.street = "210 Main St.">
<cfset pp.city = "O Fallon">
<cfset pp.state = "MO">
<cfset pp.country = "US">
<cfset pp.zip = "63368">
<cfset pp.firstname = "Dave">
<cfset pp.lastname = "Cordes">
<cfset pp.clientip = CGI.REMOTE_ADDR>   
<cfset pp.comment1 = "comm1,java test">
<cfset pp.comment2 = "comm2,java test">
<cfset pp.custref = "">
<cfset pp.invnum = "123456">
   
<!--- pass a reference to our payflow component --->
<cfset payflowpro = createObject("component","com.paypal.PayflowPro").init(server.pfpro)>

<!--- set the certificate path --->
<cfset payflowpro.setCertPath("E:\WEBROOT\payflowpro\certs")>
   
<!--- setup the context --->
<cfset payflowpro.createContext("test-payflow.verisign.com",443,30)>
   
<!--- pass the transaction parameters --->
<cfset payflowpro.setParamList(pp)>
   
<!--- submit the transaction, the response from the gateway is a delimited string --->
<cfset response = payflowpro.submitTransaction()>
   
<!--- destroy the context --->
<cfset payflowpro.destroyContext()>

<!--- parse the response --->
<cfset rh = createObject("component","com.paypal.ResponseHandler").init(response)>
   
<cfset answer = rh.responseToStruct()>

<cfdump var="#response#"><br /><br />
<cfdump var="#answer#">

ColdFusion Scorpio Server Monitoring

According to Adobe, ColdFusion 8 codenamed Scorpio will be released sometime in the middle of 2007. Along with many new features Adobe had built a server monitoring interface to see the inner workings of the server. This should be an invaluable tool. I myself have always wanted to know a more detailed picture of what goes on. Here is presentation form Adobe that they showed at MAX recently last year.

ColdFusion Development Frameworks

Steve Nelson, the original founder of Fusebox, is getting everyone excited over his new ColdFusion framework built on the power and speed of CFCs. I myself have my own framework built on a hybrid of CFCs and Fusebox so I am eager to see what this framework is all about. Apparently he is going to unveil it in less than a week at the Frameworks Conference in Bethesda, Maryland. Let the ColdFusion goodness out Steve!

BlogCFC was created by Raymond Camden. This blog is running version 5.8.001.