One of the key components of an e-commerce web site is credit card
processing capabilities. One such credit card processing service,
that is supported by PHP, is
CashRegister,
from
CyberCash. The CashRegister
service enables merchants to make financial transactions over the
Internet in real-time. CashRegister works by first you (the merchant)
receiving an order request from a customer and sending an authorization
request to the CashRegister server. Next the CashRegister server returns
either an approved or declined message back to you. If the authorization
is approved the order request is completed and the customer receives
their goods or services. Communications are encrypted using SSL and
Triple DES at the various stages in the process. For a more detailed
overview check out the
CyberCash web site.
The interface to CyberCash that we will be using is in this article
is CyberClass. CyberClass was developed by myself and is an adaptation
and enhancement to the original CyberLib written by Timothy Whitfield.
CyberClass is a duplication of CyberCash's standard API, is
object-oriented and includes automatic configuration.
If you decide that you want to use the CashRegister as a credit card payment solution, the first step
is to register at the
New Merchant CashRegister
Registration. Once you have successfully registered you will have received a user name, password and
Merchant ID. Next you will need to get your private encryption key, which are used to encrypt your
communications. To do so, go to the
Merchant Control Panel,
then the Merchant Key Exchange and get your encryption keys.
Setting up CyberCash
The next step is to setup your CyberCash merchant server by installing software from
CyberCash and compiling CyberCash support into PHP.
CyberCash provides the Merchant Connection Kit (MCK). This is used to connect you (the merchant)
to the CyberCash servers (found
here).
You will need to download and install this package onto your server. When you install the MCK package
it will create a mck-3.2.* directory. Change into this directory and run it's ./configure script.
MCK will then prompt you for your configuration information. Most of the script inputs are unused
by CyberClass. The prompts important to CyberClass for you to input are your CyberCash ID (Merchant ID),
your Merchant Key and whether the configured files should be installed; you can enter 'no'. When the
script is finished it will have created a merchant configuration file located in
/path_to/mck-3.2.*/your_merchant_id/conf/merchant_conf. This will be used by CyberClass later.
Next comes task of compiling CyberCash library support into PHP. This requires that you
download and compile the PHP source code.
If you are not familiar with compiling PHP from the source, get more information at the
Getting Started - Installation section
in the PHP Manual. To include CyberCash support, add '--with-cybercash=/path_to/mck-3.2.*' to the
list of ./configure arguments. Make sure as the script is running you see the status line 'checking
for CyberCash support... yes'. Finally, do the standard make, make install and any other external configuration.
CashRegister comes with plenty of documentation which you will need to get most of. Go to the
CashRegister Documentation page
and begin downloading. At least get the Command API Developer's Guide, the Message Block API Developer's
Guide and the Error Message Guide to aid you in development.
Lastly, download
CyberClass,
the PHP library interface to CashRegister.
Developing with CyberCash
The focus of this next section is to introduction you to the CyberCash development model. This is
not a complete development guide but a means to understand how CyberCash development in done with
PHP and CyberClass. At this stage your account should be in testing mode. Testing mode is used to
simulate the processing environment. This allows you to test and develop your CyberCash enabled web
site while billing remains inactive. Later, when you are ready go live with your site, go to the Merchant
Control Panel, click on the "Go Live" option and your site will be financially activated (given all the
necessary step are completed).
The CyberCash SendCC2_1Server() function is the primary method for sending requests to the
CyberCash servers. Through this function you can send API Commands. API Commands are a set of
commands used for executing financial transactions and functions; they require a specific list of
key/values and return a list of key/values. I find it is easiest to learn from example so lets get
down to business and make an authorization with CyberClass.
<?php
/*
CyberCash PHP CyberClass authorization example
*/
/* Include the CyberClass module */
include("class.cyberclass.php");
/* A CyberClass instance is created with the first
argument pointing to your 'merchant_conf' file */
$transaction = new cyberclass("/path_to/merchant_conf");
/* The SendCC2_1Server() member function is called */
$response = $transaction->SendCC2_1Server(
/* The Command API 'mauthonly' is called to
perform an authorization */
'mauthonly',
/* mauthonly's array of key/value argument pairs */
array(
'order-id' => '11223344',
'amount' => 'usd 12.50',
'card-number' => '4111111111111111',
/* The credit card number '4111111111111111' is the VISA testing number */
'card-exp' => '12/05', /* MM/YY date format */
'card-name' => 'Bill Clinton',
'card-address' => '1600 Pennsylvania Avenue',
'card-city' => 'Washington',
'card-state' => 'DC',
'card-zip' => '20500',
'card-country' => 'USA'
);
/* Print the result */
foreach($response as $key => $val){
echo "response['$key'] = $val<br>\n";
}
?>
The script should produce something like the following output.
<?php
response['cust-txn'] = 404909166
response['merch-txn'] = 404909166
response['avs-code'] = z
response['ref-code'] = 009600123491
response['auth-code'] = AC7435
response['action-code'] = 000
response['MStatus'] = success
response['paid-amount'] = usd 12.50
response['card-number'] = 411111
response['card-type'] = vs
response['order-id'] = 11223344
response['card-exp'] = 12/05
response['aux-msg'] = Financial Institution Response: authorization approved.
?>
This example is fairly straight forward and should give you a taste
of CyberCash development. You send your request to CyberCash and receive
a response. The MStatus variable is present in all responses and returns
the status of the issued command. This is the first variable you should
consider in determining the success of a command.
There are many CyberCash API commands besides mauthonly. However in most cases it is not
necessary to develop with them. CyberCash provides the
Merchant Manager, a web based merchant administration
interface. It pretty much does everything possible in CyberCash, with the exception of integration
with your web site. So most of your CyberCash tasks can be taken care of through the Merchant Manager.
If you still need more and power develop your own CyberCash application. Examine the appropriate API
command documentation, do some experimentation with it until you've figured it out and develop an
application. For a complete list of the Command API check out the Command API Developer's Guide Chapter 2.
Web site Integration
Now that you are familiar the CyberCash API the next stage is to
integrate CyberCash into your web site. When you receive an authorization request there are
several tasks that need to be done.
- Verify the input variables
- Send an authorization request to CyberCash
- Log to a database the order request and the CyberCash authorization status
- If the authorization status is successful proceed to fulfill the goods or services requested
- Else display an error and exit
- Present the customer with an order receipt
Below is an example of an authorization wrapper function. This takes care of CyberClass interfacing,
database logging (done with MySQL) and error handling.
<?php
/*
CyberClass authorization wrapper function
// SQL table definition used in insert order logs into
CREATE TABLE cc_order_log (
order_id CHAR(16),
amount CHAR(12),
order_desc tinytext,
trans_time datetime,
card_name CHAR(100),
card_address CHAR(100),
card_city CHAR(30),
card_state CHAR(30),
card_zip CHAR(15),
card_country CHAR(30),
part_card_num CHAR(6),
mstatus CHAR(20),
merr_code CHAR(10),
merr_msg tinytext,
merch_txn CHAR(12),
ref_code CHAR(14)
)
*/
include("class.cyberclass.php");
function cyberauth($order){
/* Make the cyberclass instance */
$transaction = new cyberclass('/etc/merchant_conf');
/* Make the credit card authorization request */
$cybercash_result = $transaction->SendCC2_1Server('mauthonly',$order);
$part_card_num = substr($order['card-number'], 0, 2) .
substr($order['card-number'],
strlen($order['card-number']) - 4, 4);
/* Make copy of order */
$db = $order;
/* Run addslashes() on data */
reset($db);
while($key = key($db)){
$db[$key] = addslashes($db[$key]);
next($db);
}
$dbMErrCode = addslashes($cybercash_result[MErrCode]);
$dbMErrMsg = addslashes($cybercash_result[MErrMsg]);
/* Log the transaction results */
$insert = "INSERT INTO cc_order_log VALUES ('{$order['order-id']}',
'{$db['amount']}',
'{$db['order_desc']}',
NOW(),
'{$db['card-name']}',
'{$db['card-address']}',
'{$db['card-city']}',
'{$db['card-state']}',
'{$db['card-zip']}',
'{$db['card-country']}',
'$part_card_number',
'{$cybercash_result['MStatus']}',
'$dbMErrCode',
'$dbMErrMsg',
'{$cybercash_result['merchtxn']}',
'{$cybercash_result['refcode']}'
)";
if(mysql("your_db", $insert) == false){
mail('youremail@yourcompany.tld',
'Cyberauth Database Log Error','', $insert);
}
if($cybercash_result['MStatus'] == "success"){
/* Success */
$return_result['success'] = true;
}elseif(eregi("failure", $cybercash_result[MStatus])){
/* Failure */
$return_result['success'] = false;
$return_result['message'] =
"There was an error processing your credit card
transaction. {$cybercash_result['MErrCode']} -
{$cybercash_result['MErrMsg']}.";
}elseif($cybercash_result['MStatus'] == "success-duplicate"){
/* Repeat */
$return_result['success'] = false;
$return_result['message'] =
"There was an error processing your credit card
transaction. The transaction you created is a
duplication of a previous transaction.";
}else{
/* Unknown Error */
$return_result['success'] = false;
$return_result['message'] =
"There was an unknown error while processing the
credit card transaction.";
}
/* Return results */
$return_result['order-id'] = $order_id;
$return_result['part-card-number'] = $part_card_num;
$return_result['card-type'] = $cybercash_result['card-type'];
$return_result['merchtxn'] = $cybercash_result['merchtxn'];
$return_result['refcode'] = $cybercash_result['refcode'];
return $return_result;
}
?>
To setup and use the cyberauth function create the cc_order_log table in your database by
running the given SQL create table command. The cyberauth script is an example and can be
adjusted to work with any database. Adjust other various items in the script such as the path
to the merchant_conf file, the database and email notification.
Next let's look at an outline example of an order processing script using the cyberauth.
<?php
include('cyberauth.php');
/*
Verify your user input
*/
/* Make authorization request */
$result = cyberauth(array(
'order-desc' => "$order-description",
'amount' => "usd $order-price",
'card-number' => "$card-num",
'card-name' => "$card-name",
'card-exp' => "$card-month/$card-year",
'card-address' => "$card-address",
'card-city' => "$card-city",
'card-state' => "$card-state",
'card-zip' => "$card-zip",
'card-country' => "$card-country"
)
);
/* If the authorization was a success */
if($result['success']){
/* Fulfill the order */
/* Show and email receipt */
}else{
/* Else return error */
echo $result['message'];
exit();
}
?>
As it goes in this outline, the user input is first verified. If you catch input errors here
it will keep CyberCash from returning missing field and other errors. Next the authorization
request is sent to CyberCash. If it is successful then the customer receives there goods or
services. If it was otherwise an error is displayed to the customer and the script exits .
Lastly, display the customer's order receipt. Emailing a receipt to the customer's email address
is also a good thing to do.
Conclusion
CyberCash is an extensive topic. Many issues were not addressed in this article because they
do not specifically relate to PHP and CyberCash and are covered in the CyberCash documentation.
To get a full understanding of CyberCash development and management you need to read the
documentation provided by CyberCash.
In the future I see CyberClass transitioning into a PEAR
(
PHP Extension and Add-on Repository)
module or the like. Also, development of integrated CyberCash applications
would be better for flexibility and customization in things like authorizations, voids,
returns and batches. The applications could tie into the PEAR DB.php module to properly log
the transactions on any database that DB.php supports.
So there is certainly room left for growth for PHP CyberCash support, but I believe with
time PHP can have better support for CyberCash than CyberCashes supported languages if
developers continue to share their code and experience.
-- Nathan