1. Create a new file named datacash_request.phpin the businessfolder, and add the following code to it:
<?php
class DataCashRequest {
// DataCash Server URL private $_mUrl;
// Will hold the current XML document to be sent to DataCash private $_mXml;
// Constructor initializes the class with URL of DataCash public function __construct($url)
{
// Datacash URL
$this->_mUrl = $url;
}
/* Compose the XML structure for the pre-authentication request to DataCash */
public function MakeXmlPre($dataCashClient, $dataCashPassword,
$merchantReference, $amount, $currency,
$method, $cardNumber, $expiryDate,
$startDate = '', $issueNumber = '') {
$this->_mXml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"\x3F>
<Request>
<Authentication>
<password>$dataCashPassword</password>
<client>$dataCashClient</client>
</Authentication>
<Transaction>
<TxnDetails>
<merchantreference>$merchantReference</merchantreference>
<amount currency=\"$currency\">$amount</amount>
</TxnDetails>
<CardTxn>
<method>pre</method>
<Card>
<pan>$cardNumber</pan>
<expirydate>$expiryDate</expirydate>
<startdate>$startDate</startdate>
<issuenumber>$issueNumber</issuenumber>
</Card>
</CardTxn>
</Transaction>
</Request>";
}
// Compose the XML structure for the fulfillment request to DataCash public function MakeXmlFulfill($dataCashClient, $dataCashPassword,
$method, $authCode, $reference) {
$this->_mXml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"\x3F>
<Request>
<Authentication>
<password>$dataCashPassword</password>
<client>$dataCashClient</client>
</Authentication>
<Transaction>
<HistoricTxn>
<reference>$reference</reference>
<authcode>$authCode</authcode>
<method>$method</method>
</HistoricTxn>
</Transaction>
</Request>";
}
// Get the current XML public function GetRequest() {
return $this->_mXml;
}
// Send an HTTP POST request to DataCash using CURL public function GetResponse()
{
// Initialize a CURL session
$ch = curl_init();
// Prepare for an HTTP POST request curl_setopt($ch, CURLOPT_POST, 1);
// Prepare the XML document to be POSTed
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->_mXml);
// Set the URL where we want to POST our XML structure curl_setopt($ch, CURLOPT_URL, $this->_mUrl);
/* Do not verify the Common name of the peer certificate in the SSL handshake */
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
// Prevent CURL from verifying the peer's certificate curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
/* We want CURL to directly return the transfer instead of printing it */
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// Perform a CURL session
$result = curl_exec($ch);
// Close a CURL session curl_close ($ch);
// Return the response return $result;
} }
?>
2. Define the DataCash URL and login data at the end of your include/config.phpfile:
// Constant definitions for datacash
define('DATACASH_URL', 'https://testserver.datacash.com/Transaction');
define('DATACASH_CLIENT', 'your account client number');
define('DATACASH_PASSWORD', 'your account password');
3. Create the test_datacash.phpfile in your project’s home (the hatshopfolder), and add the following in it:
<?php
session_start();
if (empty ($_GET['step'])) {
require_once 'include/config.php';
require_once BUSINESS_DIR . 'datacash_request.php';
$request = new DataCashRequest(DATACASH_URL);
$request->MakeXmlPre(DATACASH_CLIENT, DATACASH_PASSWORD, 8880000 + rand(0, 10000), 49.99, 'GBP', 'pre', '3528000000000007', '11/08');
$request_xml = $request->GetRequest();
$_SESSION['pre_request'] = $request_xml;
$response_xml = $request->GetResponse();
$_SESSION['pre_response'] = $response_xml;
$xml = simplexml_load_string($response_xml);
$request->MakeXmlFulfill(DATACASH_CLIENT, DATACASH_PASSWORD, 'fulfill', $xml->merchantreference,
$xml->datacash_reference);
$response_xml = $request->GetResponse();
$_SESSION['fulfill_response'] = $response_xml;
} else {
header('Content-type: text/xml');
switch ($_GET['step']) {
case 1:
print $_SESSION['pre_request'];
break;
case 2:
print $_SESSION['pre_response'];
break;
case 3:
print $_SESSION['fulfill_response'];
break;
} exit;
}
?>
<frameset cols="33%, 33%, 33%">
<frame src="test_datacash.php?step=1">
<frame src="test_datacash.php?step=2">
<frame src="test_datacash.php?step=3">
</frameset>
4. Load the test_datacash.phpfile in your browser to see the results. If you use Opera, the output should look like Figure 15-1 because Opera only shows the contents of the XML elements. If you use another web browser, you would see properly formatted XML documents.
Figure 15-1.DataCash transaction results
5. Log on to https://testserver.datacash.com/reporting2to see the transaction log for your DataCash account (note that this view takes a while to update, so you might not see the transaction right away). This report is shown in Figure 15-2.
Figure 15-2.DataCash transaction report details
How It Works: The Code That Communicates with DataCash
The DataCashRequestclass is quite simple. First the constructor sets the HTTPS address where you send your requests:
// Constructor initializes the class with URL of DataCash public function __construct($url)
{
// Datacash URL
$this->_mUrl = $url;
}
When you want to make a pre-authentication request, you first need to call the MakeXmlPremethod to create the required XML for this kind of request. Some XML elements are optional (such as startdateor issuenumber, which get default values in case you don’t provide your own—have a look at the definition of the MakeXmlPre method), but the others are mandatory.
■ Note If you want to see exactly which elements are mandatory and which are optional for each kind of request, check the XML API FAQ document from DataCash.
The next kind of request you must be able to make to the DataCash system is a fulfill request. The XML for this kind of request is prepared in the MakeXmlFulfillmethod.
You then have the GetRequestmethod that returns the last XML document built by either MakeXmlPreor MakeXmlFulfill:
// Get the current XML public function GetRequest() {
return $this->_mXml;
}
Finally, the GetResponsemethod actually sends the latest XML request file, built by a call to either MakeXmlPreor MakeXmlFulfill, and returns the response XML. Let’s take a closer look at this method.
GetResponsestarts by initializing a CURL session and setting the POSTmethod to send your data:
// Send an HTTP POST request to DataCash using CURL public function GetResponse()
{
// Initialize a CURL session
$ch = curl_init();
// Prepare for an HTTP POST request curl_setopt($ch, CURLOPT_POST, 1);
// Prepare the XML document to be POSTed
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->_mXml);
// Set the URL where we want to POST our XML structure curl_setopt($ch, CURLOPT_URL, $this->_mUrl);
/* Do not verify the Common name of the peer certificate in the SSL handshake */
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
// Prevent CURL from verifying the peer's certificate curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
To return the transfer into a PHP variable, we set the CURLOPT_RETURNTRANSFERparameter to 1, send the request, and close the CURL session:
/* We want CURL to directly return the transfer instead of printing it */
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// Perform a CURL session
$result = curl_exec($ch);
// Close a CURL session curl_close ($ch);
// Return the response return $result;
}
The test_datacash.phpfile acts like this. When you load it in the browser, the script makes a pre-authentication request and a fulfill request and then saves the pre-authentication request XML, the pre-authentication response XML, and the fulfill response XML data in the session:
session_start();
if (empty ($_GET['step'])) {
require_once 'include/config.php';
require_once BUSINESS_DIR . 'datacash_request.php';
$request = new DataCashRequest(DATACASH_URL);
$request->MakeXmlPre(DATACASH_CLIENT, DATACASH_PASSWORD, 8880000 + rand(0, 10000), 49.99, 'GBP', 'pre', '3528000000000007', '11/08');
$request_xml = $request->GetRequest();
$_SESSION['pre_request'] = $request_xml;
$response_xml = $request->GetResponse();
$_SESSION['pre_response'] = $response_xml;
$xml = simplexml_load_string($response_xml);
$request->MakeXmlFulfill(DATACASH_CLIENT, DATACASH_PASSWORD, 'fulfill', $xml->merchantreference,
$xml->datacash_reference);
$response_xml = $request->GetResponse();
$_SESSION['fulfill_response'] = $response_xml;
}
The test_datacash.phppage will be loaded three more times because you have three frames that you want to fill with data:
<frameset cols="33%, 33%, 33%">
<frame src="test_datacash.php?step=1">
<frame src="test_datacash.php?step=2">
<frame src="test_datacash.php?step=3">
</frameset>
Depending on the value, you decide which of the XMLs that you previously saved in the user session should be displayed as follows:
else {
header('Content-type: text/xml');
switch ($_GET['step']) {
case 1:
print $_SESSION['pre_request'];
break;
case 2:
print $_SESSION['pre_response'];
break;
case 3:
print $_SESSION['fulfill_response'];
break;
} exit;
}
Integrating DataCash with HatShop
Now that you have a new class that performs credit card transactions, all you need to do is integrate its functionality into the order pipeline you built in the previous chapters. To fully integrate DataCash with HatShop, you’ll need to update the existing PsCheckFundsand PsTakePaymentsclasses.
You need to modify the pipeline section classes that deal with credit card transactions.
We’ve already included the infrastructure for storing and retrieving authentication codes and reference information, via the OrderProcessor.SetOrderAuthCodeAndReferencemethod.