Products | Scripts | Services | Tutorials | Books | Links | Contact | Bulletin Board

The EPI - E-Payment Interface

Overview | Concept | Licensing | Download | Installation | Sample Code | FAQ

Install and configure the EPI

Synopsis

Here is a basic script for submitting a credit card transaction:

#!/usr/local/bin/perl
unshift @INC, '/var/www/cgi-bin';
use strict;
use EPI; # load the standard EPI routine
use CGI qw/:standard/; # load standard CGI routines
eval(_Run());
die ("Fatal Error: $@") if $@;
sub _Run {
  $| = 1;
  my $in = new CGI();
  print $in->header();
  print $in->start_html("Example Credit Card Submission Form");
  my $Merchant = new EPI({
    -MERCHANT_ID            => 'myshopid', 
    -GATEWAY_NAME           => 'AuthorizeNet',
    -GATEWAY_CONNECT_METHOD => 'SubmitLWPUserAgent', # or SubmitNetSSLeay
    -LOG_ACTIVITY           => 1, # defaults to 0
    -LOG_FILE_PATH          => './logs', # required if the above is set on 1
}); my $Result = $Merchant->_process({ -USER_ADDRESS => $in->param('CCAddress'), -USER_ZIP => $in->param('CCZip'), -USER_FULL_NAME => $in->param('CCName'), -CARD_NUMBER => $in->param('CCNumber'), -CARD_EXP_MONTH => $in->param('CCExpMonth'), -CARD_EXP_YEAR => $in->param('CCExpYear'), -ORDER_AMOUNT => $in->param('Total'), -ACTION => 'SALE', -PAYMENT_METHOD => 'CreditCard', }); if ($Result->{-OK}) { print qq~<h2>Transaction Successful</h2>
<p>Order Number: $Result->{-ORDER_NUMBER} <p>Transaction ID: $Result->{-TRANSACTION_ID} </body></html>~; } elsif ($Result->{-MISSING_INPUT_FIELDS}) { print qq~<h2>Missing Fields</h2>
<p>Please fill in all the fields! <p>Press the Back button on your browser, fill in all the required fields, and try again </body></html>~; } else { print qq~<body>
<h2>Transaction Failed</h2> <p>Error encountered during processing: <p>$Result->{-ERROR} <p>Press the Back button on your browser, correct the errors, and try again </body></html>~; } 1; }

This, of course, assumes everything is in the path, in a real-life example
if you use mod_perl, PerlEX or IIS, you will have to add at the beginning of the script a couple things like:

BEGIN{chdir("w:/cgi")}
unshift @INC, 'w:/cgi/Library';
use lib qw (./Library);

assuming that you use NT, and have the EPI.pm in the directory 'Library'.

The _process() routine takes an extra argument, that is what Perl library is to be used when making SSL connections(It is irrelevant for Cybercash or PCCharge). The parameter can have one of the values:

  • NetSSLeay
  • LWPUserAgent

The merchant routine will require then one of these libraries.

Defining the interface

As we see in the example above, there are three hashes that we have to deal with:

The Merchant Configuration hash.
Here are described the default settings of the merchant interface, like the merchant ID, password, host to link to, port, protocol, AVS settings, etc.

The Transaction Data hash
Here we pass the transaction type (sale, credit), the payment method (CreditCard, ECheck), and the form fields needed for this transaction.

The Response hash
This hash contains the results of the processing, eventual errors and/or warnings, the order number, transaction number, and eventual debugging data.

The Merchant Configuration hash

Every merchant gateway will have needs for setting certain default values, that are not transaction-dependent, and define the basic operation mode. The required fields vary from gateway to gateway, and can be looked up in the gateway module itself.

Here is a list of some of the generic parameters that can be passed through this hash.

-MERCHANT_ID

This is the merchant assigned name with the specific gateway.

-MERCHANT_PASSWORD

Some gateways require a password for all transactions, some require the password only for some of the operations, like crediting charges.

-MERCHANT_PASSWORD2

Some gateways require a second password for certain transactions, like voids, or settling pre-authenticated transactions.

-MERCHANT_EMAIL

This is the merchant email, sometimes needed by gateways to send the order confirmation to the merchant.

-SUPPORTED_PAYMENT_METHODS

This key contains the reference to an array of the accepted payment methods for this merchant/gateway. Here is a list of the allowed parameters:

  • CreditCard - Normal Credit Card
  • PurchaseCard - Business (Purchase) Credit Card
  • ECheck - Electronic Check Processing through the Paymentech processor
  • ACH - Automatic Clearing House processor

Notice that some gateways only accept credit cards, or only a choice of items from this list. Should new payment methods appear for a certain gateway, we will list them here.

-GATEWAY_NAME

The gateway name is one of the following:

  • PCCharge - GO Software PC Charge product
  • AuthorizeNet - the version 3.0 of the Authorizenet gateway
  • VeriSign - the PayFlowLink/PayFlowPro gateways for VeriSign
  • CyberCash - interfaces with the Command API of the CyberCash MCK
  • IntelliPay - The IntelliPay gateway
  • ...

With the time, more gateways will be added

-GATEWAY_CONNECT_METHOD

If required by a gateway, this specifies the method used to perform the transaction on the server side. Supported values:

  • SubmitNetSSLeay
  • SubmitLWPUserAgent

Some packages use Net::SSLeay to submit the data to the gateway url. This is specified in the package header, along with the URL where it connects. You will need the following software installed (latest version shown):

  • Net::SSLeay v1.21
  • OpenSSL v0.9.6g

Note that Net::SSLeay requires a matching version of OpenSSL. Please check the Net::SSLeay web page for the correct version required:

http://symlabs.com/Net_SSLeay/

For the people that cannot make use of the Net::SSLeay (NT folks), there is an alternative submission method using LWP::UserAgent and Crypt::SSLeay. If you are using the ActiveState Perl, you can use the package manager to install both of the above.

To install either modules from CPAN, you will have to ask your ISP to do it. This operation requires root or Administrator access, since you are installing software in the common Perl distribution.

-GATEWAY_HOST

Some gateways, like Authorizenet, PCCharge, need the host address of the gateway to be addressed. This is in form of either an IP address, or as a host.domain.com. Notice that some gateways use the defaults, and do not need readjustment. For the time being, only PCCharge requires this value, or it defaults
to the localhost (127.0.0.1).

-GATEWAY_PORT

If the gateway connects to a host in secure mode, this would be set on 443. Some gateways might use an alternative port for that.

-GATEWAY_URL

This is the path part of the calling URL, i.e. the script name that is being called, in the form: '/cgi-bin/processor.cgi'. Most gateways use the defaults for this one.

-GATEWAY_URL2

As the previous one, it is a path, and is eventually used in tandem with the second password, to perform certain transactions, like voids, or settling pre-authenticated transactions.

-GATEWAY_CARD_PROCESSOR

The processor that your merchant account uses for cards (NOVA, FDC,...)

-VALIDATE_CARD

Setting this field on 1 enables our script to check the credit card fields for validity, and reject the transaction if the card number was wrong. Enable this if you want to reduce the traffic to the processor, or you want to set certain restrictions.

-ACCEPTED_CARDS

The card types being identified, verified, and validated are: MASTERCARD, VISA, DISCOVER, AMEX, JCB, DINERS, CARTEBLANCHE If you do not provide this value, the gateway defaults will be used.
Provide a list of the cards as an array reference.

-GATEWAY_AVS_ENABLED

Some gateways support the Address Verification System standard, that will return information about the correct identity of the user, and if configured so at the gateway, will also reject a transaction. Having this flag set, enables our script to check for the availability of the AVS-required data, before submitting it to the processor, thus sparing us some extra traffic.
Enable it by setting it on '1'

-DEBUG

This flag enables logging in the transaction log some extra information, like credit card numbers, expiration date, check numbers, bank accounts. Even if logging is enabled, disabling this item will obfuscate sensitive
data in the log.
Enable it by setting it on '1'

-LOG_ACTIVITY

Setting this flag enable logging the transactions to a file.
Enable it by setting it on '1'

-LOG_FILE_PATH

If the -LOG_ACTIVITY was set, you need to provide a valid path for the error log. A file will be created, with the name: 'GATEWAYNAME.log'

NOTE ON THE ABOVE PARAMETERS

depending on the service you are using, you might need to provide more information about your account, or the way you want it configured when you build the object; please consult the documentation of the module/service.

The Transaction Data hash

Will be described soon.

The Response Data hash

$Response is a reference to the following type of hash:

{
  -OK             => 1     # opposite to -ERROR
-TRANSACTION_ID => $TID, # transaction number returned by PCCharge,
# which, in fact, is the same with the
# {-RAW_DATA}->{-AUTH}
-ORDER_NUMBER => $ONR, # auto-assigned order number
-TRANSACTION_ID => $TId, # The transaction ID, returned by capture only
-TRANSACTION_DATE => $TDate, # The date on which the transaction occurred
-TRANSACTION_ORDER_NUMBER => $TONum, # some gateways use this for credits
-RESPONSE_TIME => $Time, # the time of transaction, in generic format (sic!)
-ERROR => $ERR, # errors occurred during the processing
-WARNING => $WARN,# warnings to the submittal (like AVS problems)
-LOG_ENTRY => $log, # formatted output of the transaction
-SUBMIT_TIME => $T # the time when it was submitted (not responded)
-RAW_DATA => $raw, # data, as returned by the gateway
-RAW_FIELDS => \%Fields, # a hash of fields, by name (gateway names)
-AVS_RESULT => '', # the AVS code, as returned by the gateway
-MISSING_INPUT_FIELDS => \@MissingFields,
-INVALID_INPUT_FIELDS => \@InvalidFields,
-MERCHANT_NAME => $MName, # a merchant string, returned by some gateways
-MERCHANT_TRACE_NUMBER => $TNum, # The merchant trace number provided
# in the transaction. It is echoed back unchanged as part of the response }

To determine what fields are missing and display them back in your shopping cart, might get to be quite an arcane job, so we will return here the field names that we were missing, and you have to build an equivalence hash on your side, having to deal with either displaying a user-friendly description of the fields, mark the fields, or display just a plain message (that can make some users crazy :) ). Here is an example of such a hash:

%EPIToFormFieldsMap = (
# The EPI fields   => Your Form Fields
  -SHIP_FULL_NAME  => 'SName', 
  -SHIP_FIRST_NAME => 'SFirstName', 
  -SHIP_LAST_NAME  => 'SLastName', 
  -SHIP_ADDRESS    => 'SAddress', 
  ...
);

If you want to implement something fancy, you could use the hash for assigning values when you submit the transaction, like in the example below.

First, insert in the %Data all values that are NOT coming as form fields as well as those that were calculated and updated, being contained in a different variable as the form fields hash

Then, you update all the remaining fields, in case the $Data{$x} does not have a value already

my %Data = (
  -ACTION => 'SALE',
  -PAYMENT_METHOD => 'CreditCard',
);
while(($Key, $Val) = each %EPIToFormFieldsMap) {
  $Data{$Key} = $FX->{$Val} if ! $Data{$Key} && $FX->{$Val};
}
my $Result = $Merchant->_process($Data);
if (ref $Result->{-MISSING_INPUT_FIELDS}) { my @MissingFormFields = (); foreach(@{$Result->{-MISSING_INPUT_FIELDS}}) { push @MissingFormFields, $EPIToFormFieldsMap{$_}; } my $MissingFieldsList = join ', ', @MissingFormFields; print "The following form fields were missing: $MissingFieldsList"; }

As you see, we used the %EPIToFormFieldsMap for both processes

If your shop supports language-specific display, you might want to build the real field descriptions in the routine that has the language bits, something like:

foreach(@{$Result->{-MISSING_INPUT_FIELDS}}) {
  push @MissingFormFields, $DescriptionOfFormField{$EPIToFormFieldsMap{$_}};
}

You might want to put the %EPIToFormFieldsMap in the Setup.pm, and eventually assign it to a key for easier handling:

$S->{-SHOP_EPI_TO_FORM_FIELDS_MAP} = \%EPIToFormFieldsMap;

The language hash will be then put at best in the OrderFormVIEW.pm, which is different for every language. Of course, you will move the bit of code that displays the error, in the same file.