[ic] Summary of Payment modules

Angus Rogerson arogerso at uwaterloo.ca
Tue Apr 1 12:45:03 UTC 2014

Hello list,

We have used beanstream's hosted payment service for credit cards on our 5.4.x interchange for a number of years. As we upgrade to 5.8.0 we started looking at updating the interface to beanstream. As part of that process I have reviewed the payment modules distributed with the current release IC 5.8.0. I have summarized my notes below in the hope that it may be helpful for others choosing a module to use, choosing a module as a basis for a module they may develop, or possibly for the IC 6 team.

The payment module appears to have been developed with server-server processing in mind. That is, when the customer selects credit card payment and fills in their credit card information, the payment module sends the information to the credit card processor's server, waits for a response, assesses the results and either completes or fails the interchange transaction.

The payment module exports two functions, and allows export of a third. It requires a sub be defined for the particular gateway, either as a GlobalSub or in Vend::Payment::Gateway.

The main function is the charge function which is called when an &charge or [charge ] are processed. It sets up the data, calls an appropriate processor specific function defined as a GlobalSub or in Vend::Payment::Gateway then interprets the results and sets up interchange to complete or fail the transaction. 

The payment module also defines:
	- charge_param (@EXPORT): looks up a parameter in the Route repository, mv_payment_* in options, MV_PAYMENT_* in Variables
	- map_actual (@EXPORT_OK): returns an array of of 'actual' values needed by the gateway, derived from interchange Values or CGI:Values based on a standard mapping, plus charge_param('remap') to change names and MV_PAYMENT_BILLING_SET, MV_PAYMENT_BILLING_INDICATOR to control billing information.
	- gen_order_id: generates an order id for the transaction
	- post_data: builds a URL string and posts it using one of wget, SSLeay, LWP and returns %result
	- test* : set up test environments

Each payment gateway module typically exports a single function, named for the gateway, which is called by Vend::Payment charge(), and may use the various functions defined in the payment module. Many developers have chosen to reimplement code found in the payment module.

Most (all?) modules create a module Payment::ABC to force the require to notice that the module is missing, but simply add subs to the Payment module to implement their functionality. Some programmers note this as a bug in their documentation, presumably preferring a stricter OO implementation.

Some modules implement other protocols (not server-server) such as hosted payment, transparent redirect, multi-step server-server, tokens etc. Typically this is involves two invocations of the charge function, each with different parameters. First, the user completes the interchange portion of the transaction and selects a payment mode which requires a hosted/redirect protocol. The charge function calls the gateway function which bounces the user to the gateway's website. The gateway servers do their thing and eventually bounce the user back to interchange. On the return to interchange, the charge function is called again. This time the gateway function recognizes that the user is returning from the gateway's servers and assess the results and completes or fails the transaction. 

In these cases the gateway function typically has a large if-then-else structure to perform the bounce to the server and to select from one or more appropriate responses depending on how the gateway returned the user to the interchange. Typically, developers do not claim compatibility on a call level, and additional configuration steps are required including creating pages for return targets from the gateway and modifying etc/log_transaction to handle the two step protocols.

Some modules use a check_sub to test whether the transaction meets AVS/CVV requirements. Apparently these gateways perform the tests but do not fail a transaction based on the AVS/CVV test results. These require a protocol to pre-authorize and check AVS/CVV then complete the transaction if the AVS/CVV results are satisfactory.

There are three main techniques used for redirecting to a gateway's server:

- insert an iframe in the page delivered by interchange, with the gateway's server's form displayed in the iframe
- display an interchange page with a [bounce ] tag sending the user to the gateway's server
- in perl code, use $Tag->tag() to send the user to the gateway's server

Users typically return to interchange by defining a page in pages/ which contains a [charge ]? Different modules have different ways of completing the interchange transaction, some returning from the charge through Vend::Payment and some requiring changes in etc/log_transaction.

Below is a list summarizing the types of techniques used. There may be better examples of some of the things mentioned - no offence is intended to any developer whose code I misrepresented. For developers unlucky enough to not be able to find the module they need, this list might help find a starting point for developing a new module.

	Server-server post_data	
	Server-server using external module: Business::OnlinePayment	
	5 types of XML for different transactions including 3DS, acs	
	more OO than most
	check_sub for AVS/CVV
	incl support for Paypal express checkout
	Server-server using external module: OpenECHO	
	Server-server post_data	
	Server-server post_data	
	Server-server post_data	
	notes problems with &, < and >
	processes variety of callbacks from Google both in transactions and from admin interface
	documents setup of buttons and routes
	uses $Tag->tag to bounce to google
	uses callback page charge route="googlecheckout" gcorequest="callback"
	variety of multistep protocols for charge, add_order_number, refund, cancel	
	$Tag->tag redirect	
	recommends CyberSource.pm
	Server-server post_data	
	Server-server using lpperl
	check_sub for AVS/CVV	
	Server-server using external module (MCVE) and low level calls	
	request then poll for response
	complex module, not by zolotek
	bounce pages: pages/ord/paypalcheckout.html
	return pages with
		[charge route="payflowpro" action="get"] 
		[charge route="payflowpro" action="set"]
		[bounce href="[area href=__CHECKOUT_PAGE__]"]
	check_sub for AVS/CVV	
	lots of steps, tokens, back and forth	
	Server-server post_data	
	does not support 3DS
	checks for server availability and fails over to offline processing otherwise, also logs $0 transactions
	Server-server post_data	
	iframe to go to bank
	tdsreturn.html: charge route="sagepay" sagepayrequest="3dsreturn"
	multi-step - check for 3DSecure available for card, then process transaction
	Server-server post_data	
	recommends PayflowPro	
	Server-server post_data	
	Server-server using external module: Net::TCILink	
	see examples of use of %result for different success and error conditions	
	uses call back pages
	logs temporary transaction before going to bank
	redirects to bank using Tag->tag
	bank takes call back page and displays it on their page

 If you are developing a new module, I would suggest looking at:
	Vend::Payment - for what it has to offer
	TestPayment - for the interchange side of how to complete or fail a transaction, use of the %result array
	iTransact or Tclink - for the shortest (not necessarily best) examples of Server-Server
	SagePay - use Tag->tag to bounce to a page with an embedded iFrame (See Quick Start Summary #7), then using [charge] to return from there to interchange  (See Quick Start Summary #7), good documentation
	WorldPay - for logging temporary transaction while waiting for the bank to return a response
	Protx2 - for a server-server module with documentation on "cooperating with GoogleCheckout and PaypalExpress"
	PayfloPro - for multiple callback pages with different charge route actions and bounces
	Netbilling - if you have a provider which requires polling for a response
	CyberSource - for a more OO approach, using buttons and bounce to go places
When you have a handle on things, then read one or more of the 'big' modules which do most things, but are a little harder read because they are so big:

HTH someone sometime.


Angus Rogerson, BMath, BScN, RN

Duct Tape Programmer
University of Waterloo | Retail Services | Information Systems

Visit Us Online & Right On Campus www.retailservices.uwaterloo.ca

More information about the interchange-users mailing list