This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
khosb/plugins/checkout/CLASS_SKIPJACK/skipjack.php
2008-11-26 14:50:40 -08:00

503 lines
18 KiB
PHP

<?
// -----------------------------------------------------------------------------
// Skipjack PHP Interface
//
// Original version written by Greg MacLellan
// Online Creator Inc May 11, 2001
//
// This script requires the cURL Library for PHP
//
// It was tested on Apache 1.3.19 + PHP 4.0.5 + OpenSSL 0.9.6 + libcURL 7.7.3
//
// New version: July 10, 2004 - Ashbec LLC
// Syntax errors removed / debugged for updated environment:
// Linux
// Apache 1.3.28 / PHP 4.3.3 / cURL 7.10.5 / OpenSSL 0.9.6b / zlib 1.1.4
// - fixed syntax error in define
// - initialized $str before parsing
// - added new szReturnCode/Message values (-96 thru -100)
// - added current AVS return codes, handled unknown codes
// Only SkipJack_Authorize and Change_Status have been tested in the new environment.
// Status has not been tested.
//
// New version: November 29, 2004 - Ashbec LLC
// - Added code to gracefully?? exit if there is no response from Skipjack
// (Fakes a communications error.)
// - Set 60 second timeout on cURL execution
//
// Copyright 2004, Ashbec LLC. Rights to distribute and use without charge is hereby granted.
// Right to sell this version of the software is expressly reserved to Ashbec LLC.
//
// function SkipJack_Authorize($request)
// function SkipJack_Status($request)
// function SkipJack_ChangeStatus($request)
// -----------------------------------------------------------------------------
//
// protocol + host for the server
// define("SJPHPAPI_ROOT_URL", "https://developer.skipjackic.com"); // test
// define("SJPHPAPI_ROOT_URL", "https://www.skipjackic.com"); // production
// -----------------------------------------------------------------------------
function SkipJack_Authorize($request) {
$skipjackurl = SJPHPAPI_ROOT_URL."/scripts/evolvcc.dll?Authorize";
$ch = curl_init(); // initalize cURL
curl_setopt($ch, CURLOPT_URL, $skipjackurl); // connect to skipjack
// special processing:
// format the price "5352.20" => "535220"
/* $request["Transactionamount"] = number_format($request["Transactionamount"], 2, "", ""); (doesn't work) */
// take the $request array and turn it into name=value&name=value pairs
if (count($request) > 0) {
reset($request);
$str = NULL;
while (list($name, $value) = each($request)) {
$str .= "&".$name."=".$value;
}
$str = substr($str,1);
}
curl_setopt($ch, CURLOPT_POST, 1); // we're doing a post
curl_setopt($ch, CURLOPT_POSTFIELDS, $str); // name=value pairs from above
curl_setopt($ch, CURLOPT_USERAGENT, "SJ-PHP-API (Ashbec LLC)");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // return results
curl_setopt($ch, CURLOPT_TIMEOUT, 60); // max time
$results = curl_exec ($ch); // connect and grab the results
curl_close ($ch);
$ReturnValues = array("AUTHCODE",
"szSerialNumber",
"szTransactionAmount",
"szAuthorizationDeclinedMessage",
"szAVSResponseCode",
"szAVSResponseMessage",
"szOrderNumber",
"szAuthorizationResponseCode",
"szIsApproved",
"szCVV2ResponseCode",
"szCVV2ResponseMessage",
"szReturnCode"
);
$szReturnCode = array("1"=>"Status Complete (1)",
"0"=>"Call Failed (0)",
"-1"=>"Invalid length (-1)",
"-35"=>"Invalid credit card number (-35)",
"-37"=>"Failed communication (-37)",
"-39"=>"Serial number is too short (-39)",
"-51"=>"The zip code is invalid",
"-52"=>"The shipto zip code is invalid",
"-53"=>"Length of expiration date (-53)",
"-54"=>"Length of account number date (-54)",
"-55"=>"Length of street address (-55)",
"-56"=>"Length of shipto street address (-56)",
"-57"=>"Length of transaction amount (-57)",
"-58"=>"Length of name (-58)",
"-59"=>"Length of location (-59)",
"-60"=>"Length of state (-60)",
"-61"=>"Length of shipto state (-61)",
"-62"=>"Length of order string (-62)",
"-64"=>"Invalid phone number (-64)",
"-65"=>"Empty name (-65)",
"-66"=>"Empty email (-66)",
"-67"=>"Empty street address (-66)",
"-68"=>"Empty city (-68)",
"-69"=>"Empty state (-69)",
"-70"=>"Empty zip code (-70)",
"-71"=>"Empty order number (-71)",
"-72"=>"Empty account number (-72)",
"-73"=>"Empty expiration month (-73)",
"-74"=>"Empty expiration year (-74)",
"-75"=>"Empty serial number (-75)",
"-76"=>"Empty transaction amount (-76)",
"-79"=>"Length of customer name (-79)",
"-80"=>"Length of shipto customer name (-80)",
"-81"=>"Length of customer location (-81)",
"-82"=>"Length of customer state (-82)",
"-83"=>"Length of shipto phone (-83)",
"-84"=>"Pos Error duplicate ordernumber (-84)",
"-91"=>"Pos Error CVV2 (-91)",
"-92"=>"Pos Error Approval Code (-92)",
"-93"=>"Pos Error Blind Credits Not Allowed (-93)",
"-94"=>"Pos Error Blind Credits Failed (-94)",
"-95"=>"Pos Error Voice Authorizations Not Allowed (-95)",
"-96"=>"Voice Authorization Failed (-96)",
"-97" => "Fraud Rejection - rule violation (-97)",
"-98" => "Invalid Discount Amount (-98)",
"-99" => "Invalid Pin Block (-99)",
"-100" => "Invalid Key Serial Number (-100)"
);
$szAVSResponse = array("X" => "Exact match, 9 digit zip",
"Y" => "Exact match, 5 digit zip",
"M" => "Exact address match, international.",
"D" => "Exact address match, international.",
"A" => "Address matches, ZIP code does not",
"B" => "Address match without postal code, international.",
"W" => "ZIP Code (9) matches, address does not",
"Z" => "ZIP Code (5) matches, address does not",
"P" => "Postal code match only, international.",
"N" => "No address or zip match",
"U" => "Address verification unavailable",
"I" => "Address information not verified by issuer, international.",
"R" => "Retry - Issuer system unavailable or timed out",
"E" => "Error - AVS data is invalid",
"C" => "Incompatible address format, international.",
"G" => "Non-U.S. Issuer does not participate in AVS (verification unavailable)",
"S" => "Service not supported by US issuing Bank"
);
// parse through results for $ReturnValues in "<!--ReturnValue=value-->"
if (empty($results)) { // No response from SkipJack. Fake an error.
$response['AUTHCODE'] = NULL;
$response['szSerialNumber'] = NULL;
$response['szTransactionAmount'] = NULL;
$response['szAuthorizationDeclinedMessage'] = "No response from SkipJack financial network.";
$response['szAVSResponseCode'] = "R";
$response['szAVSResponseMessage'] = "No response from SkipJack financial network.";
$response['szOrderNumber'] = NULL;
$response['szAuthorizationResponseCode'] = 0;
$response['szIsApproved'] = 0;
$response['szCVV2ResponseCode'] = "P";
$response['szCVV2ResponseMessage'] = "Not processed";
$response['szReturnCode'] = -37;
} else { // Parse the real results
while (list($key,$code) = each($ReturnValues)) {
$pos = strpos($results, $code);
if ($pos) {
$value = substr($results, $pos + strlen($code) + 1, strpos($results, "-->", $pos) - $pos - strlen($code) - 1);
$response[$code] = $value;
}
}
}
// a couple extra response strings
if (!empty($szAVSResponse[$response['szAVSResponseCode']])) {
$response["textAVSResponseCode"] = $szAVSResponse[$response['szAVSResponseCode']];
} else {
$response["textAVSResponseCode"] = "Unknown AVS code: " . $response['szAVSResponseCode'];
}
if (!empty ($szReturnCode[$response["szReturnCode"]])) {
$response["textReturnCode"] = $szReturnCode[ $response["szReturnCode"] ];
} else {
$response["textReturnCode"] = "Unknown return code: " . $response['szReturnCode'];
}
return $response;
}
function SkipJack_Status($request) {
$skipjackurl = SJPHPAPI_ROOT_URL."/scripts/evolvcc.dll?SJAPI_TransactionStatusRequest";
$ch = curl_init(); // initalize cURL
curl_setopt($ch, CURLOPT_URL, $skipjackurl); // connect to skipjack
// take the $request array and turn it into name=value&name=value pairs
$str = NULL;
while (list($name, $value) = each($request)) {
$str .= "&".$name."=".$value;
}
$str = substr($str,1);
curl_setopt($ch, CURLOPT_POST, 1); // we're doing a post
curl_setopt($ch, CURLOPT_POSTFIELDS, $str); // name=value pairs from above
curl_setopt($ch, CURLOPT_USERAGENT, "SJ-PHP-API (Ashbec LLC)");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // return results
$results = curl_exec ($ch); // connect and grab the results
curl_close ($ch);
// fields in response record
$responseRecFields = array("SerialNumber",
"ErrorCode",
"NumRecs");
// response record error codes
$responseRecErrorCodes = array("0"=>"Success",
"-1"=>"Invalid Command",
"-2"=>"Parameter Missing",
"-3"=>"Failed retrieving response",
"-4"=>"Invalid Status",
"-5"=>"Failed reading security tags",
"-6"=>"Developer serial number not found",
"-7"=>"Invalid Serial Number",
"-8"=>"Expiration year not four characters",
"-9"=>"Credit card expired",
"-10"=>"Invalid starting date (recurring payment)",
"-11"=>"Failed adding recurring payment",
"-12"=>"Invalid Frequency (recurring payment)");
// fields in status records
$responseFields = array("SerialNumber",
"Amount",
"TransStatusCode",
"TransStatusMsg",
"OrderNumber",
"TransactionDate",
"TransactionID");
$StatusText = array("0"=>"Idle",
"1"=>"Authorized",
"2"=>"Denied",
"3"=>"Settled",
"4"=>"Credited",
"5"=>"Deleted",
"6"=>"Archived",
"7"=>"Pre-Auth");
$PendingStatusText = array("0"=>"Idle",
"1"=>"Pending Credit",
"2"=>"Pending Settlement",
"3"=>"Pending Delete",
"4"=>"Pending Authorization",
"5"=>"* Pending Settlement");
// first, we get the response record
$temp = substr($results, 0, strpos($results,"\n") - 1);
while (list($key,$val) = each($responseRecFields)) {
$firstquote = strpos($temp,"\"");
$secondquote = strpos($temp, "\"", $firstquote + 1);
$responserecord[$val] = substr($temp, $firstquote + 1, $secondquote - 1 - $firstquote);
$temp = substr($temp, $secondquote + 1);
}
// additional text messages
$responserecord["textErrorCode"] = $responseRecErrorCodes[$responserecord["ErrorCode"]];
// get just the results into this string
$results = substr($results, strpos($results, "\n") + 1);
// if we didn't get some error
if ($responserecord["ErrorCode"] == 0) {
// parse through results and create array
$i = 0;
while (strlen($results) > 0) {
$temp = substr($results, 0, strpos($results,"\n") - 1);
$results = substr($results, strpos($results, "\n") + 1);
// parse through individual string and create array
reset($responseFields);
while (list($key,$val) = each($responseFields)) {
$firstquote = strpos($temp,"\"");
$secondquote = strpos($temp, "\"", $firstquote + 1);
$response[$i][$val] = substr($temp, $firstquote + 1, $secondquote - 1 - $firstquote);
$temp = substr($temp, $secondquote + 1);
}
// create additional text responses
$response[$i]["intStatus"] = substr($response[$i]["TransStatusCode"],0,1);
$response[$i]["textStatus"] = $StatusText[ $response[$i]["intStatus"] ];
$response[$i]["intPendingStatus"] = substr($response[$i]["TransStatusCode"],1,1);
$response[$i]["textPendingStatus"] = $PendingStatusText[ $response[$i]["intPendingStatus"] ];
$i++;
}
return array("Status"=>$responserecord, "Response"=>$response);
} else {
return array("Status"=>$responserecord, "Text"=>$results);
}
}
function SkipJack_ChangeStatus($request) {
$skipjackurl = SJPHPAPI_ROOT_URL."/scripts/evolvcc.dll?SJAPI_TransactionChangeStatusRequest";
$ch = curl_init(); // initalize cURL
curl_setopt($ch, CURLOPT_URL, $skipjackurl); // connect to skipjack
// take the $request array and turn it into name=value&name=value pairs
$str = NULL;
while (list($name, $value) = each($request)) {
$str .= "&".$name."=".$value;
}
$str = substr($str,1);
curl_setopt($ch, CURLOPT_POST, 1); // we're doing a post
curl_setopt($ch, CURLOPT_POSTFIELDS, $str); // name=value pairs from above
curl_setopt($ch, CURLOPT_USERAGENT, "SJ-PHP-API (OnlineCreator)");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // return results
$results = curl_exec ($ch); // connect and grab the results
curl_close ($ch);
// fields in response record
$responseRecFields = array("SerialNumber",
"ErrorCode",
"NumRecs");
// response record error codes
$responseRecErrorCodes = array("0"=>"Success",
"-1"=>"Invalid Command",
"-2"=>"Parameter Missing",
"-3"=>"Failed retrieving response",
"-4"=>"Invalid Status",
"-5"=>"Failed reading security tags",
"-6"=>"Developer serial number not found",
"-7"=>"Invalid Serial Number",
"-8"=>"Expiration year not four characters",
"-9"=>"Credit card expired",
"-10"=>"Invalid starting date (recurring payment)",
"-11"=>"Failed adding recurring payment",
"-12"=>"Invalid Frequency (recurring payment)");
// fields in status records
$responseFields = array("SerialNumber",
"Amount",
"DesiredStatus",
"StatusResponse",
"StatusResponseMsg",
"OrderNumber",
"TransactionID");
// so we can return a 1/0 response code
$SuccessCodes = array("SUCCESSFUL"=>"1",
"UNSUCCESSFUL"=>"0",
"NOTALLOWED"=>"0");
// first, we get the response record
$temp = substr($results, 0, strpos($results,"\n") - 1);
while (list($key,$val) = each($responseRecFields)) {
$firstquote = strpos($temp,"\"");
$secondquote = strpos($temp, "\"", $firstquote + 1);
$responserecord[$val] = substr($temp, $firstquote + 1, $secondquote - 1 - $firstquote);
$temp = substr($temp, $secondquote + 1);
}
// additional text messages
$responserecord["textErrorCode"] = $responseRecErrorCodes[$responserecord["ErrorCode"]];
// get just the results into this string
$results = substr($results, strpos($results, "\n") + 1);
// if we didn't get some error
if ($responserecord["ErrorCode"] == 0) {
// parse through results and create array
// with ChangeStatusRequest, this is usually only one value,
// but for consistency, we'll handle more if we need to
$i = 0;
while (strlen($results) > 0) {
$temp = substr($results, 0, strpos($results,"\n") - 1);
$results = substr($results, strpos($results, "\n") + 1);
// parse through individual string and create array
reset($responseFields);
while (list($key,$val) = each($responseFields)) {
$firstquote = strpos($temp,"\"");
$secondquote = strpos($temp, "\"", $firstquote + 1);
$response[$i][$val] = substr($temp, $firstquote + 1, $secondquote - 1 - $firstquote);
$temp = substr($temp, $secondquote + 1);
}
// create additional text responses
$response[$i]["intSuccess"] = $SuccessCodes[ $response[$i]["StatusResponse"] ];
$i++;
}
return array("Status"=>$responserecord, "Response"=>$response);
} else {
return array("Status"=>$responserecord, "Text"=>$results);
}
}
/*
// sample transaction:
$request = array("sjname" => "Skipjack PHP Test",
"Email" => "Transaction@skipjack.com",
"Streetaddress" => "2230 Park Ave",
"City" => "Cincinnati",
"State" => "OH",
"Zipcode" => "45206",
"Country" => "USA",
"Ordernumber" => "1PHP",
"Accountnumber" => "5121212121212124",
"Month" => "03",
"Year" => "2003",
"Serialnumber" => "xxxxxxxxxxxx", // html Vital, NBova or production
"Transactionamount" => "3.45",
"Orderstring" => "1~Item 1~3.45~3~N~||",
"Shiptophone" => "888-368-8507");
echo "<pre>";
var_dump($request);
var_dump(SkipJack_Authorize($request));
echo "</pre>";
*/
/*
Sample Status Request:
$request["szSerialNumber"] = "xxxxxxxxxxxx";
$request["szDeveloperSerialNumber"] = "xxxxxxx";
//$request["szOrderNumber"] = "1PHP";
$request["szDate"] = "";
echo "<pre>";
var_dump($request);
echo "</pre><br>";
echo "<pre>";
var_dump ( SkipJack_Status($request) );
echo "</pre>";
echo "<br><hr><Br>";
*/
/*
Sample Status Change:
unset($request);
$request["szSerialNumber"] = "xxxxxxxxxxxx";
$request["szDeveloperSerialNumber"] = "xxxxxx";
$request["szOrderNumber"] = "1PHP";
$request["szDesiredStatus"] = "SETTLE";
$request["szForceSettlement"] = "1";
echo "<pre>";
var_dump($request);
echo "</pre><br>";
echo "<pre>";
var_dump ( SkipJack_ChangeStatus($request) );
echo "</pre><br>";
*/
?>