Thursday, February 2, 2012


If anyone else out there ever has work with the LinkPointTransaction.dll assembly, I pity you.  It is not an enjoyable experience.

I've been working on updating an eCommerce site, and before I started working with the payment code, I wanted to run a simple test transaction against LinkPoint so that I could gain familiarity with it before I started changing code around.  Hopefully my story will help others in their struggle.

I first had to sign up for a developer account.  That was fairly simple, and shortly thereafter I received three emails with 3 different accounts - apparently they have 3 different ways you can issue transactions.

1. Web Service API.  This is a SOAP endpoint.
2. Virtual Terminal.  This is where you log into their website and type in transactions manually
3. Connect.  This is where you use LinkPointTransaction.dll to connect to their services

Once I figured out what the 3 different options were, I figured out that the app I was working on used #3.  (Side Note:  If you're starting from scratch, I would recommend checking out the SOAP endpoint so that you don't have to work with assemblies, COM objects, and custom SSL libraries that are several years old).  I then went looking for documentation.  I found the documentation site, but it took me a little while to figure out which PDF was the right one.  I finally figured out that the API user manual was the right one.  I had initially thought that the API user manual would have been the manual for the Web Service API, but I was wrong - the API user manual is for the Connect option.

I then went looking for some sample code.  I found the FirstData sample code site, and saw two promising options - one for 'C and .Net', and one for 'Visual Basic and .Net'.  I'm a C# programmer, but Visual Basic sounded better to me than C.  However, it turns out that the 'C and .Net' download is actually for C#.   I downloaded the 'C and .Net' sample code.

The manual proved to be helpful, but it lacked a certain amount of accuracy and clarity on certain points that tripped me up.  First off, it said that you had to have some OpenSSL libraries.  Which were not provided.  Rather, it pointed you to and said you could download the source files and build it yourself.  It then had two links that pointed to documentation on First Data's site on how to do so.  Unfortunately, the links were broken.  After running around in circles for a while on this one, I ran across a comment from someone that said that you didn't really need OpenSSL.  So I went ahead without OpenSSL, and it didn't seem to affect things.

I then wrote this sample code to test the service:

string keyfile = "C:\\Users\\Developer\\Desktop\\0123456789.pem";
string host = "";
 int port = 1129;
 string xml = "<order><billing><city>Schenectady</city><addrnum>1234</addrnum><state>NY</state><address1>1234 Main Street</address1><zip>12345</zip><country>US</country><name>Tom Sanders</name><phone>706-555-1212</phone></billing><payment><chargetotal>32.00</chargetotal></payment><merchantinfo><configfile>0123456789</configfile></merchantinfo><transactiondetails><oid>5112-634637326017218618</oid><transactionorigin>ECI</transactionorigin><ip></ip></transactiondetails><creditcard><cardexpyear>12</cardexpyear><cardexpmonth>6</cardexpmonth><cvmvalue>123</cvmvalue><cardnumber>372700997251009</cardnumber><cvmindicator>provided</cvmindicator></creditcard><items><item><quantity>1</quantity><price>32.00</price><id>1</id><description>Large Widget</description></item></items><orderoptions><result>GOOD</result><ordertype>SALE</ordertype></orderoptions></order>";
 LinkPointTxn LPTxn = new LinkPointTxn();
 string resp = LPTxn.send(keyfile, host, port, outXml);

When I first tried to run it, I saw an error about not being able to find lpssl.dll.  I looked, and it was right there in the bin folder.  After pulling out Process Monitor, I discovered that, rather than looking for lpssl.dll in the bin folder, it was looking in the system path (%PATH%).  So I had two options - either move the lpssl.dll to a folder that is already in the path, or add the bin folder to the path.

Once that was resolved, I ran the test, and it worked great.  I ran it again, and I saw an AccessViolationException with the message of "Attempted to read or write protected memory.  This is often an indication that other memory is corrupt."

I double checked to be sure that the XML I generated was proper, and I double checked the various bits and pieces in the manual, and everything looked good.  But about half the time it would work great, and half the time it would fail.

So I called up FirstData support at 888-477-3611 x2 x4 (also at  I sent my sample code to them and they found the problem: the result tag.  Apparently, you need to set this to LIVE, not to GOOD(see update below).   According to section 3.4 of the documentation:

This field puts the account in live mode or test mode.  Set to Live for live mode, Good for an approved response in test mode, Decline for a declined response in test mode, or Duplicate for a duplicate response in test mode.
But the tech support lead said that the documentation was wrong, and it only worked consistently if you put it in LIVE mode.  That's fine with me, as the other modes are only used for testing anyway.

From what I can tell, there are multiple ways you can do test transactions instead of real transactions (where a real transaction actually moves real money around):
1. Create and use a Test Account.  There are no real credit card numbers or real bank account numbers used in this scenario.  It's all pretend.
2. Use a non-LIVE result mode (as seen in section 3.4 of the API documentation).  You can set Good, Decline, or Duplicate to force the API method to return that as the transaction status, thus simulating successful transactions and failures.
3. Use dummy credit card numbers.  These will only work 'in a test environment.'

4. Use the Customer Test Environment, which will allow you to specify precisely which of a large number of possible transactions results you want to be returned.

I'm not really sure exactly how these different options fit together, but I know that the problem I had was with option #2, as I was using GOOD for the result tag.

Once I changed it from GOOD to LIVE, everything worked fine (consistently)(see update below).  I'm guessing that this problem is tied to the fact that these assemblies are 6 years old and were developed by a company that got bought out by a company that got bought out by the company that currently provides these services.

Here is the final test code that works:

string keyfile = "C:\\Users\\Developer\\Desktop\\0123456789.pem";
string host = ""; 
 int port = 1129; 
 string xml = "<order><billing><city>Schenectady</city><addrnum>1234</addrnum><state>NY</state><address1>1234 Main Street</address1><zip>12345</zip><country>US</country><name>Tom Sanders</name><phone>706-555-1212</phone></billing><payment><chargetotal>32.00</chargetotal></payment><merchantinfo><configfile>0123456789</configfile></merchantinfo><transactiondetails><oid>5112-634637326017218618</oid><transactionorigin>ECI</transactionorigin><ip></ip></transactiondetails><creditcard><cardexpyear>12</cardexpyear><cardexpmonth>6</cardexpmonth><cvmvalue>123</cvmvalue><cardnumber>372700997251009</cardnumber><cvmindicator>provided</cvmindicator></creditcard><items><item><quantity>1</quantity><price>32.00</price><id>1</id><description>Large Widget</description></item></items><orderoptions><result>LIVE</result><ordertype>SALE</ordertype></orderoptions></order>"; 
 LinkPointTxn LPTxn = new LinkPointTxn(); 
 string resp = LPTxn.send(keyfile, host, port, outXml);

Update (2012-02-07):

After further testing, I kept running into the AccessViolationException, even when in LIVE mode.  So I called up tech support again, and they informed me that their libraries only work on 32 bit machines - apparently, the LinkPoint libraries don't run well on 64 bit machines, even if they are running in 32 bit compatibility mode.  So I built out a new development VM on Windows 7 x86, and it seems to be working now.


No comments: