<?php
/**
* Class: SkipJack
* URL:
* Class to perform payment transaction throuh Skipjack payment gateway.
* This class allows you
To check for authorization of payments
To check transaction status
*
* Vinay Yadav (vinayRas)
* hide@address.com,
* hide@address.com
* http://www.vinayras.com/
*
* @see http://www.skipjack.com
* @see http://www.skipjack.com/resources
*
* Requirements:
* CURL - Command line cURL
* skipjackResponse.php - by vinayRas
*
* Error Codes:
* -101 - Field ($value) is missing
* -111 - cURL error - couldnt execute command
* -100 - NO DATA RECIEVED
*/
/**
* Required for checking the response code returned
* while checking for authorization of payment.
*/
require("skipjackResponse.php");
class SkipJack {
/**
* Curl on the system.
*/
var $curlPath = "";
/**
* Skipjack payment gateway address
*
*/
var $ROOT_HOST = "https://developer.skipjackic.com";
var $URLS = array(
"AUTH" => "/scripts/evolvCC.dll?Authorize", /** Authorisation check URL */
"TSTAT" => "/scripts/evolvcc.dll?SJAPI_TransactionStatusRequest", /** Transaction Check URL */
"CSTAT" => "/scripts/evolvcc.dll?SJAPI_TransactionChangeStatusRequest" /** Change Status URL */
);
/**
* Codes used when queried for transaction status..
*/
var $transactStatus = array(
"current"=>array("Idle","Authorized","Denied","Settled","Credited","Deleted","Archived","Pre-Auth"),
"pending"=>array("Idle","Pending Credit","Pending Settlement","Pending Delete","Pending Authorization","Pending Settle Force (for Manual Accts)","Pending Recurring")
);
/**
* Error codes while querying for transactio status
*/
var $tranStatusErrorCodes = array(
"-1"=>"Invalid Command",
"-2"=>"Parameter Missing",
"-3"=>"Failed retrieving response",
"-4"=>"Invalid Status",
"-5"=>"Failed reading security flags",
"-6"=>"Developer serial number not found",
"-7"=>"Invalid Serial Number",
"-8"=>"Expiration year not four characters",
"-9"=>"Credit card expired"
);
/**
* You need to get a developer serial for testing purpose.
*/
var $serial = "";
/**
* AUTH => Authorization
* TSTAT => Transaction Status
* CSTAT => Change Transaction Status - NOT SUPPORTED
*
* Default mode is Authorization mode.
*/
var $mode = "AUTH";
/**
* Headers
*/
var $headers = array(
"User-Agent"=>"SkipJack 1.0",
"Referer"=>"",
"Host"=>"",
"Accept"=>"image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*",
);
/**
* Data that has to be posted. should be in the key=value pair.
*/
var $postData = array();
/**
* Response recieved - Its key=>value pair format
*/
var $responseData = array();
var $sendTime = 0; /* Time when request was sent through CURL */
var $getTime = 0; /* Timestamp when we recieved back the reply */
var $Debug = 1;
var $Error = "";
var $ErrorStr = "";
/**
* Constructor
*/
function SkipJack() {
$this->curlPath = trim(`which cur1l`);
if(empty($this->curlPath)) {
die("Cannot locate cURL binary on your system which is executable by the web-server");
}
/**
* List of 14 required post fields needed for validating a authorization transaction.
*/
$this->requiredPosts = array( 'sjname','Email','Streetaddress','City',
'State','Zipcode','Ordernumber','Accountnumber',
'Month','Year','Serialnumber',
'Transactionamount','Orderstring','Shiptophone'
);
$this->postData["Serialnumber"] = $this->serial;
$this->headers['Host'] = $this->ROOT_URL;
$this->headers['Referer'] = $_SERVER["PHP_SELF"];
}
/**
* This function makes sure that the data being sent is valid.
* Some 14 variables are required..
* For details take a look at SkipJack Integration Guide.
* @return
true - on sucess
field name which is missing
*/
function checkData() {
$tmpKey = array_keys($this->postData);
foreach($this->requiredPosts as $key => $value) {
if(!in_array($value,$tmpKey)) {
$this->setError(-101,"Field ($value) is missing");
return $value;
}
}
return true;
}
/**
* Authorize payment
*/
function checkAuthorization($data) {
if($this->checkData()) {
$this->setPostData($data);
return $this->putData();
}
return $this->getError();
}
/**
* Change Transaction status
*/
function checkTransStatus($data) {
$this->mode = "TSTAT";
$this->setPostData($data);
return $this->putData();
}
/**
* Change transaction status
*/
function changeTransStatus($data) {
}
/**
* Populates the postData array...
*
* If first argument is array, then all elements are assigned as
* key=value pair in postData array
*/
function setPostData($name,$value="") {
if(is_array($name)) {
foreach($name as $key => $value) {
$this->postData["$key"] = $value;
}
} else {
$this->postData["$name"] = $value;
}
}
/**
* Post Data to server..
*/
function putData($data = "") {
if(!empty($data)) {
$this->setPostData($data);
}
$data = $this->postData;
if($this->Debug) {
echo "<br>Sending request to $this->ROOT_HOST ".$this->URLS[$this->mode];
}
/**
* preparing the request string
*/
foreach($data as $key => $value) {
$request .= " -d ".urlencode($key)."=".urlencode($value)." ";
}
/**
* Build header information
*/
/*
foreach($this->headers as $headerName => $headerValue) {
$headers .= " -H $headerName: $headerValue";
}
*/
$this->sendTime = time();
/**
* Execute using command line curl.
*/
if($this->Debug) {
echo "$this->curlPath $request $headers ".$this->ROOT_HOST.$this->URLS[$this->mode];
flush();
}
exec("$this->curlPath $request $headers ".$this->ROOT_HOST.$this->URLS[$this->mode],$results,$return);
$this->getTime = time();
if($return)
{
$this->setError(-111,"Error: cURL could not retrieve the document, error $return.");
if($this->Debug) {
$this->showError();
echo "<br>$this->curlPath $request $headers ".$this->ROOT_HOST.$this->URLS[$this->mode];
}
return false;
}
if($this->Debug) {
print_r($results);
}
$this->response = $results;
return $this->parseData();
}
/**
* parse the output
*/
function parseData() {
if($this->mode == "AUTH") {
return $this->parseAuthorizationData();
} else if($this->mode == "TSTAT") {
return $this->parseTStatusnData();
} else if($this->mode == "CSTAT") {
return $this->parseChangeStatusData();
}
}
/**
* Parse output..given out by authorization
*/
function parseAuthorizationData() {
$this->response = $this->response[0];
if($this->Debug) {
echo "<br>Begining Parsing response data";
}
$response = $this->response;
$response = eregi_replace("<!--|-->",",",$response);
$response = eregi_replace(",,",",",$response);
$responseArr = explode(",",$response);
foreach($responseArr as $key => $val) {
if(!empty($val)) {
$valArr = explode("=",$val);
$this->responseData[$valArr[0]] = $valArr[1];
}
}
if($this->Debug) {
print_r($this->responseData);
echo "<br>End of Parsing response data";
}
//$this->responseData;
return $this->getStatus();
} // end of function parseData
/**
* parse output by Transaction status
* Response Format:
*
Serial Number, Amount, Transaction Status Code,Transaction Status Message,
Order Number, Transaction Date, Transaction Id, Approval Code, Batch Number
*
* Transaction Status Code - The first digit, is the current status, the second digit is the pending status.
*
* @see http://www.skipjack.com/resources/status/GetStatus-Train.htm
*
* return false on failure
*/
function parseTStatusnData() {
if($this->Debug) {
echo "<br>Begining Parsing response data";
}
/**
* The first row of the result informs about the status..
*/
if(!is_array($this->response)) {
$this->setError("-100","NO DATA RECIEVED");
return false;
}
$chkArr = explode(",",$this->response[0]);
$chkArr[1] = eregi_replace("\"","",$chkArr[1]); // "
if($chkArr[1] == "0") {
/**
* There may be several results sets
*/
foreach($this->response as $key => $result) {
if($this->Debug) {
echo "<br>Result - $result";
}
$result = eregi_replace("\"","",$result); // "
$tmpArray = explode(",",$result);
$currStatus = substr($tmpArray[2],0,1);
$pendingStatus = substr($tmpArray[2],1,1);
if(!empty($tmpArray[0])) {
$reponseArr[] = array(
"SerialNumber"=>$tmpArray[0],
"amount"=>$tmpArray[1],
"transactionStatusCode"=>$tmpArray[2],
"currStatus"=>array($currStatus,$this->transactStatus["current"][$currStatus]),
"pendingStatusCode"=>array($pendingStatus,$this->transactStatus["pending"][$pendingStatus]),
"status"=>$tmpArray[3],
"orderNumber"=>$tmpArray[4],
"date"=>$tmpArray[5],
"transactionID"=>$tmpArray[6],
"approvalCode"=>$tmpArray[7],
"batchNumber"=>$tmpArray[8],
);
}
}
return $reponseArr;
} else {
$this->setError($chkArr[1],$this->tranStatusErrorCodes[$chkArr[1]]);
if($this->Debug) {
$this->showError();
}
return false;
}
}
/**
* Change status response
*
* Serial Number, Amount, Desired Status, Status Response, Status Response Message, Order Number,Transaction Id
*/
function parseChangeStatusData() {
}
/**
* Check the response data
* skipjackResponseCheck class is needed here...
*
* @return array(status code, status message)
*
*/
function getStatus() {
$sr = new skipjackResponseCheck($this->responseData);
return array($sr->statusCode,$sr->getStatus());
}
/**
* Set the error
* Scope: Private
*/
function setError($errno,$errstr) {
$this->Error = $errno;
$this->ErrorStr = $errstr;
}
/**
*
*/
function getError() {
return array($this->Error,$this->ErrorStr);
}
/**
* Display errors
*/
function showError() {
print("[$this->Error] $this->ErrorStr");
}
} // end of class
?>