Forum OpenACS Q&A: Payment Service Contract

Collapse
Posted by Richard Hamilton on
Sorry this is so long but I think that there is info here that some will find useful.

Payment Service Contract, multi-currency/ non-US.

OpenACS as it stands has support for PayFlowPro and Authorize.net thanks to Janine, Bart and Brad. Both of these payment gateways support dollar transactions through the US banking system i.e. Merchant Services accounts which must pay into US dollar based bank accounts.

I am based in the UK and, with the intention of using the existing payment gateways, have spent six months working through the issues. I have incorporated in the US, set up a company bank account, applied for a Merchant Services account and configured the system successfully in test mode with Verisign, but have pretty much concluded that whilst I could probably eventually succeed in getting a dollar based system working for my own corporation, I couldn't set one up for anyone else easily without running into all sorts of legal convolutions and liabilities. In fact even if someone incorporates in the US, unless they are a US citizen (and therefore sueable under US jurisdiction when the guano hits the fraud detector), the merchant account providers are not likely to be interested.

There is also the issue of multi-currency transactions. I have (after much twisting of arms) discovered that The Chase Manhattan, First Data South network has protocol support for specifying any currency for authorisation. However, whilst certain gateways can support the necessary currency code in the authorisation request, we run up against another basic fact of life, which is that when you mention anything other that dollars to a US bank, their eyes glaze over. The upshot of this is that whilst you could in theory authorise in pounds sterling, Japanese Yen or Euros using this network, you would have to deposit the funds into a US dollar bank account and thus incur the costs of currency exchange at the time prevailing, thereby completely undermining the purpose of avoiding billing in dollars in the first place! The non US banking networks (particularly those in the UK, Europe and (believe it or not) Africa are geared up to allowing individuals and companies to open accounts in any currency). That of course means that you can set up a bank account and a merchant account in the required currency in any country, and then authorise in that currency using your chosen gateway. That means that you can work in an environment where you (or your clients) already have a banking relationship which obviously makes life easier.

Achieving this goal would open up the ACS and its payment gateways to a world of multi-currency transactions which would be a really competitive step. (There are options such as Payment Planet but they are technically substandard, not as scaleable as the existing OpenACS gateways solutions, you have to hand off the connection to someone else's server, and they are very expensive).

A very important factor for me though is that the gateway meets the pre-requisites laid down in Philip's book i.e. that the system is properly integrated in the way that the authorise and payflow gateways are rather than rigged by linking to the gateway's server like some of the dumbed down options, or reliant upon running a complete Java Virtual Machine or having to lauch o/s processes with all the attendant waste of resources, just for the priviledge of talking to their wonderful gateway, even though your site does not require it. I have spent some time searching for UK options that provide low level integration by way of c libraries for which I could develop a service contract implementation based on Janine and Bart's Payment Gateway Service Contract.

I have found two possibilities:
One is CyberSource, who have recently launched enhanced services including direct bank account debits and other adjuncts, and offer an SDK which provides a c library which we could incorporate. An added benefit is that they are finally doing what Philip wrote about and are using public/private key authentication for the authorisation requests, a function supported by their sdk.
The downside is that they are three to four times more expensive than a US provider and have a minimum transactions fee each month of £150 ($220) in addition to a monthly charge of £150 and a £700 setup charge. They are geared for very high volume, low value transactions and I believe that whilst we should ideally develop a gateway, they will not be the provider of choice for most projects smaller than a Fortune 500 or UK equivalent.

The other is SecPay. They have moved away from their c library based sdk towards a Java based and IIS bound 'alternative' and although they no longer provide their c libs for download on their site, are willing to make them available upon request (which I have asked them to do). The prices in this case are closer to US prices, though SecPay do not support quite the same level of fraud control as CyberSource.

That then brings me to my questions!

I am going to embark on my first package...........

I have therefore studied the existing code for the service contract module, the payment gateway module and the payflowpro module and have drawn what I think is some kind of understanding of it all. What would be really helpful is if someone could either confirm or put me straight on the following:

My understanding is:
a) That the service contract defines a generic set of functions/ services that any package such as the ecommerce package can expect to use. Having viewed the pages in the service contract mocule I belive that a complete payment gateway service contract is as follows :

Authorize - Authorize 
input transaction_id integer 
input amount string 
input card_type string 
input card_number string 
input card_exp_month string 
input card_exp_year string 
input card_name string 
input billing_street string 
input billing_city string 
input billing_state string 
input billing_zip string 
input billing_country string 
output response_code string 
output reason string 
output transaction_id string 
ChargeCard - ChargeCard 
input transaction_id integer 
input amount string 
input card_type string 
input card_number string 
input card_exp_month string 
input card_exp_year string 
input card_name string 
input billing_street string 
input billing_city string 
input billing_state string 
input billing_zip string 
input billing_country string 
output response_code string 
output reason string 
output transaction_id string 
Info - Information about the gateway 
output package_key string 
output version version 
output package_name string 
output cards_accepted string 
output success string 
output failure string 
output retry string 
output not_supported string 
output not_implemented string 
Return - Return 
input transaction_id integer 
input amount string 
input card_type string 
input card_number string 
input card_exp_month string 
input card_exp_year string 
input card_name string 
input billing_street string 
input billing_city string 
input billing_state string 
input billing_zip string 
input billing_country string 
output response_code string 
output reason string 
output transaction_id string 
Void - Void 
input transaction_id integer 
input amount string 
input card_type string 
input card_number string 
input card_exp_month string 
input card_exp_year string 
input card_name string 
input billing_street string 
input billing_city string 
input billing_state string 
input billing_zip string 
input billing_country string 
output response_code string 
output reason string 
output transaction_id string 


b) That an implementation of the service contract translates the client package's requests into calls specific to the gateway in use.

c) That the code in the verisign.so driver module defines three tcl functions that can be relied upon to exist in any gateway implementation and that these functions will contain the implementation specific code to drive the chosen gateway.

d) That by incuding the gateway sdk as a header file in verisign.c and calling its functions you are effectively expanding the library such that it is integrated with the AOLServer API.

f) That it should be possible to write a package using the sample gateway as a template that can be bound to the existing Payment Service Contract. The verisign.c program must be modified to call the appropriate functions from the SecPay or CyberSource APIs having included the libaries at the top of the *.c file with the >include ****.h< directive and must handle any implementation specific reply codes or messages.

I also have a question - and will no doubt have a lot more as I progress(!):

Purely for my own education, why was adding functions to the AOLServer API through verisign.so chosen as the solution rather than calling the gateway specific c libraries from tcl. Am I right in assuming that if you called a compiled c module direct from tcl within an AOLServer thread that a new o/s process would have had to be launched and that therefore the reason is to make the gateway code 'thread aware'.


I would very much appreciate it if anyone can point out any misunderstandings that I have before I get stuck in. Also advice, guidance or misc docs wil be gratefully received.

Regards
Richard
Collapse
Posted by Andrew Piskorski on
Richard, I don't know about the rest of your questions, but at least with AOLserver 3.x, if you wanted to provide Tcl access to a 3rd party C library the only way to do that was to write an AOLserver module creating the new Tcl commands. Except for any possible thread-safety issues in the 3rd party library, this isn't that hard.

I don't know where this AOLserver verisign module you mention is to be found (it's not in AOLserver SourceForge CVS), but that's presumably what it's for, and why it was designed the way you mention.

Now, AOLserver 4.0 supports the standard Tcl package require functionality, and (most) Tcl packages can be used exactly as-is. (The exceptions are currently packages which use global variables and expect those variables to be nicely cleaned up and reset to default states on http connection close, which AOLserver currently doesn't do.)

I am not sure, but I believe that AOLserver 4.0 may also be able to use Tcl packages which include C extensions in exactly the same way. In which case, the Verisign module you're talking could perhaps now bee coded as a Tcl extension package and used from both tclsh and AOLserver 4.0. But all this AOLserver 4.0 stuff is relatively new, so even if that works (and I'm not sure), you won't find many people around here who have done things that way yet.

Collapse
Posted by Richard Hamilton on
Andrew,

Thanks, that makes sense and confirms my interpretation. The verisign.so driver was written by Janine Sisk and was based on the Cybercash interface written by Brad Duell . It is an included package in OpenACS 4.5 and OpenACS 4.6.

I am still using AOLServer ad33.13 primarily because I use nsvhr which Jerry Asher patched for ad33.13, so the AOLServer 4.0 stuff is not an option at present.

Hopefully, once I have established that the assumptions listed above are correct (or been put straight) I may be in a position to make a stab at writing a new implementation.

Regards
Richard
Collapse
Posted by Brad Duell on
Richard,

Most of your findings seem to be correct.  I think by following one of the existing gateways that Bart or Janine developed you'll be able to do exactly what you're proposing.

I don't know much about the C extensions in AOLServer 4 that Andrew mentioned, in fact we haven't been developing on v.4 for very long, but extensions sound promising.

Finally, the module that I wrote for Verisign's SDK and ACS was based upon the Cybercash module that Jin S. Choi of Arsdigita originally developed, re-worked by Janine for her gateway, and re-worked again by me upon implementing the gateway on our production site.  See http://www.ncacasi.org/contrib/ and the diff at https://openacs.org/bugtracker/openacs/patch?patch_number=90

Good luck with the new gateway!  Feel free to drop me a line with any questions if you decide to implement a module instead of using the extensions that Andrew talked about.

Collapse
Posted by Bart Teeuwisse on
Richard,

I would recommend expanding the current payment service contract so that it can handle mutiple currencies as that should be a super set of the current single currency design.

Please note that -at the moment- the payment service contract is currency agnostic. It is not aware what currency is being used. If Authorize.net had a UK branch operating in Pound Sterling you could use the Authorize.net Gateway. However, it is not possible to accept Pound Sterling when communicating with an US based credit card processor through the payment service contract.

So by all means, expand the service contract specification so that it handles multiple currencies. Without giving it much thought, this could be as easy as including the currency in the various financial operations. I will then adapt the Authorize.net Gateway to be compliant with the new definition.

Good luck.

/Bart

Collapse
Posted by Richard Hamilton on
Brad,

I do plan to implement it as a module, so I am sure that I will need to take you up on your offer of answering some questions as I progress.

Bart,

I will look through the two c libraries (SecPay and CyberSource) and will propose some additions to the payment gateway service contract. Perhaps then, once that has survived scrutiny I can set about writing an implementation.

Am I better to use the Authorize.net Gateway as a guide or stick to the Payflow one?

Richard
Collapse
Posted by Bart Teeuwisse on
Richard,

use both modules as a guide. Authorize.net Gateway is better documented where as Payflow uses a C library to connect to the credit card processor. The modules implement the same service contract and thus have much in common.

/Bart

Collapse
Posted by Richard Hamilton on
I have found another payment processor that has implemented an XML based protocol. They provide some unsuitable pre-written integration options but have confirmed that those can be bypassed and their functionality replicated on any platform by just posting them xml formed requests.

If I were to write a set of tcl functions that take the payment request parameters and form an xml string to send to their server using AOLServer API calls I think that we would have a fast efficient and scaleable process. By the way, is tls the only way to do an ns_httpget over ssl or is there an ns_httpsget or equivalent?. How else could I ensure that the xml request goes out encrypted?

I wondered whether you think that this is as good an option as writing a *.so module (as with the verisign solution) to allow access to c libraries for making connections to payment providers. In other words for purely technical reasons do we prefer the verisign module or the authorize module?

Richard

Collapse
Posted by Brad Duell on
I think that the fewer the components, the better off a system is.

I'd be interested in seeing how encrypted XML works - seems like it would definately be a lighter implementation.