picture of Nathan Cassano
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'] = 
 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 Responseauthorization 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.
  1. Verify the input variables
  2. Send an authorization request to CyberCash
  3. Log to a database the order request and the CyberCash authorization status
  4. If the authorization status is successful proceed to fulfill the goods or services requested
  5. Else display an error and exit
  6. 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'], 02) . 
    
substr($order['card-number'], 
    
strlen($order['card-number']) - 44); 

/* 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