PHP – USAePay Payment Gateway

This PHP class can be used to process credit card payments via USAePay Payment Gateway.

Code Example: Download Example

index.php

<?php
require('usaepay.php');
$tran = new umTransaction;
$tran->usesandbox=true; // for live account comment this line

$tran->key             = "1STE2TX3456789"; // USAePay Tranasacton Key
$tran->command         = "sale";
$tran->invoice         = "12345";

$tran->amount          = "50.55";
$tran->currency        = "USD";

$tran->billfname       = "Bill";
$tran->billlname       = "M";
$tran->billcompany     = "Internet Co.";
$tran->billstreet      = "12345 St. Jons";
$tran->billstreet2     = "12345 St. Jons";
$tran->billcity        = "Escodia";
$tran->billstate       = "CA";
$tran->billzip         = "92030";
$tran->billcountry     = "US";
$tran->billphone       = "111-111-1111";
$tran->email           = "bill@test.com";

$tran->shipfname       = "Bill";
$tran->shiplname       = "M";
$tran->shipcompany     = "Internet Co.";
$tran->shipstreet      = "12345 St. Jons";
$tran->shipstreet2     = "12345 St. Jons";
$tran->shipcity        = "Escodia";
$tran->shipstate       = "CA";
$tran->shipzip         = "92030";
$tran->shipcountry     = "US";

$tran->card            = "4111111111111111";
$tran->exp             = "012019"; // MMYYYY
$tran->cvv2            = "123";

$tran->street         = "12345 St. Jons";
$tran->zip            = "92030";

flush();
if($tran->Process()){
 echo "Payment successful made.";
 $confirmed = true;
} else {
 echo "<br><b>Card Declined</b> (" . $tran->result . ")<br>";
 echo "<b>Reason:</b> " . $tran->error . "<br>";
 if($tran->curlerror) echo "<b>Curl Error:</b> " . $tran->curlerror . "<br>";
}
?>

usaepay.php

<?php
define("USAEPAY_VERSION", "1.6.0");

/**
 * USAePay Transaction Class
 *
 */
class umTransaction {

 // Required for all transactions
 var $key;            // Source key
 var $pin;             // Source pin (optional)
 var $amount;        // the entire amount that will be charged to the customers card
 // (including tax, shipping, etc)
 var $invoice;
// invoice number.  must be unique.  limited to 10 digits.  use orderid if you need longer. 

 // Required for Commercial Card support
 var $ponum;            // Purchase Order Number
 var $tax;            // Tax

 // Amount details (optional)
 var $tip;             // Tip
 var $shipping;        // Shipping charge
 var $discount;         // Discount amount (ie gift certificate or coupon code)
 var $subtotal;         // if subtotal is set, then
 // subtotal + tip + shipping - discount + tax must equal amount
 // or the transaction will be declined.  If subtotal is left blank
 // then it will be ignored
 var $currency;        // Currency of $amount

 // Required Fields for Card Not Present transacitons (Ecommerce)
 var $card;            // card number, no dashes, no spaces
 var $exp;            // expiration date 4 digits no /
 var $cardholder;     // name of card holder
 var $street;        // street address
 var $zip;            // zip code

 // Fields for Card Present (POS)

 var $magstripe;
 // Must be set to true if processing a card present transaction (Default is false)
 var $cardpresent;
 /*The type of terminal being used:  Optons are  POS - cash register,
 StandAlone - self service terminal,  Unattended - ie gas pump,
 Unkown  (Default:  Unknown)
 */
 var $termtype;
 /* Support for mag stripe reader:   yes, no, contactless,
 unknown  (default is unknown unless magstripe has been sent)
 */
 var $magsupport;
 // Magstripe was read with contactless reader:  yes, no (default is no)
 var $contactless;
 var $dukpt;        // DUK/PT for PIN Debit
 var $signature;     // Signature Capture data

 // fields required for check transactions
 var $account;        // bank account number
 var $routing;        // bank routing number
 var $ssn;            // social security number
 var $dlnum;            // drivers license number (required if not using ssn)
 var $dlstate;        // drivers license issuing state
 var $checknum;        // Check Number
 var $accounttype;       // Checking or Savings
 var $checkformat;    // Override default check record format

 // Option parameters
 var $origauthcode;    // required if running postauth transaction.
 var $command;        // type of command to run; Possible values are:
 // sale, credit, void, preauth, postauth, check and checkcredit.
 // Default is sale.
 var $orderid;    // Unique order identifier.  This field can be used to reference
 // the order for which this transaction corresponds to. This field
 // can contain up to 64 characters and should be used instead of
 // UMinvoice when orderids longer that 10 digits are needed.
 var $custid;   // Alpha-numeric id that uniquely identifies the customer.
 var $description;    // description of charge
 var $cvv2;            // cvv2 code
 var $custemail;        // customers email address
 var $custreceipt;    // send customer a receipt
 var $ignoreduplicate; // prevent the system from detecting and folding duplicates
 var $ip;            // ip address of remote host
 var $testmode;        // test transaction but don't process it
 var $usesandbox;    // use sandbox server instead of production
 var $timeout;       // transaction timeout.  defaults to 45 seconds
 var $gatewayurl;       // url for the gateway
 var $proxyurl;        // proxy server to use (if required by network)
 /*
 Bypasses ssl certificate errors.  It is highly recommended that you do
 not use this option.  Fix your openssl installation instead!
 */
 var $ignoresslcerterrors;
 /*
 manually specify location of root ca bundle
 (useful of root ca is not in default location)
 */
 var $cabundle;
 /*
 manually select transport to use (curl or stream),
 by default the library will auto select based on what is available
 */
 var $transport;    

 // Card Authorization - Verified By Visa and Mastercard SecureCode
 var $cardauth;        // enable card authentication
 var $pares;         // 

 // Third Party Card Authorization
 var $xid;
 var $cavv;
 var $eci;

 // Recurring Billing
 //  Save transaction as a recurring transaction:  yes/no
 var $recurring;
 /*
 How often to run transaction: daily, weekly, biweekly,
 monthly, bimonthly, quarterly, annually.  Default is monthly.
 */
 var $schedule;
 // The number of times to run. Either a number or * for unlimited.
 // Default is unlimited.
 var $numleft;
 // When to start the schedule.  Default is tomorrow.
 // Must be in YYYYMMDD  format.
 var $start;
 /*
 When to stop running transactions. Default is to run forever.
 If both end and numleft are specified, transaction will stop
 when the ealiest condition is met.
 */
 var $end;
 //  Optional recurring billing amount.
 var $billamount;
 var $billtax;
 var $billsourcekey;

 // Billing Fields
 var $billfname;
 var $billlname;
 var $billcompany;
 var $billstreet;
 var $billstreet2;
 var $billcity;
 var $billstate;
 var $billzip;
 var $billcountry;
 var $billphone;
 var $email;
 var $fax;
 var $website;

 // Shipping Fields
 var $shipfname;
 var $shiplname;
 var $shipcompany;
 var $shipstreet;
 var $shipstreet2;
 var $shipcity;
 var $shipstate;
 var $shipzip;
 var $shipcountry;
 var $shipphone;

 var $comments; // Additional transaction details or comments 

 var $software; // Allows developers to identify their application to the gateway 

 // response fields
 var $rawresult;        // raw result from gateway
 var $result;        // full result:  Approved, Declined, Error
 var $resultcode;     // abreviated result code: A D E
 var $authcode;        // authorization code
 var $refnum;        // reference number
 var $batch;        // batch number
 var $avs_result;        // avs result
 var $avs_result_code;        // avs result
 var $avs;                      // obsolete avs result
 var $cvv2_result;        // cvv2 result
 var $cvv2_result_code;        // cvv2 result
 var $vpas_result_code;      // vpas result
 var $isduplicate;      // system identified transaction as a duplicate
 // transaction amount after server has converted it to merchants currency
 var $convertedamount;
 var $convertedamountcurrency;  // merchants currency
 var $conversionrate;  // the conversion rate that was used
 var $custnum;  //  gateway assigned customer ref number for recurring billing

 // Cardinal Response Fields
 var $acsurl;    // card auth url
 var $pareq;        // card auth request
 var $cctransid; // cardinal transid

 // Errors Response Feilds
 var $error;         // error message if result is an error
 var $errorcode;     // numerical error code
 var $blank;            // blank response
 var $transporterror;     // transport error

 // Constructor
 function umTransaction()
 {
 // Set default values.
 $this->command="sale";
 $this->result="Error";
 $this->resultcode="E";
 $this->error="Transaction not processed yet.";
 $this->timeout=45;
 $this->cardpresent=false;
 if(isset($_SERVER['REMOTE_ADDR'])) $this->ip=$_SERVER['REMOTE_ADDR'];
 $this->software="USAePay PHP API v" . USAEPAY_VERSION;

 }

 /**
 * Verify that all required data has been set
 *
 * @return string
 */
 function CheckData()
 {
 if(!$this->key) return "Source Key is required";
 if(in_array(strtolower($this->command), array("cc:capture",
 "cc:refund", "refund", "check:refund","capture", "creditvoid")))
 {
 if(!$this->refnum) return "Reference Number is required";
 }  else {
 if(in_array(strtolower($this->command), array("check:sale","check:credit",
 "check", "checkcredit","reverseach") )) {
 if(!$this->account) return "Account Number is required";
 if(!$this->routing) return "Routing Number is required";
 } else {
 if(!$this->magstripe) {
 if(!$this->card) return "Credit Card Number is required ({$this->command})";
 if(!$this->exp) return "Expiration Date is required";
 }
 }
 $this->amount=ereg_replace("[^[:digit:].]","",$this->amount);
 if(!$this->amount) return "Amount is required";
 if(!$this->invoice && !$this->orderid) return "Invoice number or Order ID is required";
 if(!$this->magstripe) {
 //if(!$this->cardholder) return "Cardholder Name is required";
 //if(!$this->street) return "Street Address is required";
 //if(!$this->zip) return "Zipcode is required";
 }
 }
 return 0;
 }

 /**
 * Send transaction to the USAePay Gateway and parse response
 *
 * @return boolean
 */
 function Process()
 {
 // check that we have the needed data
 $tmp=$this->CheckData();
 if($tmp)
 {
 $this->result="Error";
 $this->resultcode="E";
 $this->error=$tmp;
 $this->errorcode=10129;
 return false;
 }

 // format the data
 $data =
 array("UMkey" => $this->key,
 "UMcommand" => $this->command,
 "UMauthCode" => $this->origauthcode,
 "UMcard" => $this->card,
 "UMexpir" => $this->exp,
 "UMbillamount" => $this->billamount,
 "UMamount" => $this->amount,
 "UMinvoice" => $this->invoice,
 "UMorderid" => $this->orderid,
 "UMponum" => $this->ponum,
 "UMtax" => $this->tax,
 "UMtip" => $this->tip,
 "UMshipping" => $this->shipping,
 "UMdiscount" => $this->discount,
 "UMsubtotal" => $this->subtotal,
 "UMcurrency" => $this->currency,
 "UMname" => $this->cardholder,
 "UMstreet" => $this->street,
 "UMzip" => $this->zip,
 "UMdescription" => $this->description,
 "UMcomments" => $this->comments,
 "UMcvv2" => $this->cvv2,
 "UMip" => $this->ip,
 "UMtestmode" => $this->testmode,
 "UMcustemail" => $this->custemail,
 "UMcustreceipt" => $this->custreceipt,
 "UMrouting" => $this->routing,
 "UMaccount" => $this->account,
 "UMssn" => $this->ssn,
 "UMdlstate" => $this->dlstate,
 "UMdlnum" => $this->dlnum,
 "UMchecknum" => $this->checknum,
 "UMaccounttype" => $this->accounttype,
 "UMcheckformat" => $this->checkformat,
 "UMrecurring" => $this->recurring,
 "UMbillamount" => $this->billamount,
 "UMbilltax" => $this->billtax,
 "UMschedule" => $this->schedule,
 "UMnumleft" => $this->numleft,
 "UMstart" => $this->start,
 "UMexpire" => $this->end,
 "UMbillsourcekey" => ($this->billsourcekey?"yes":""),
 "UMbillfname" => $this->billfname,
 "UMbilllname" => $this->billlname,
 "UMbillcompany" => $this->billcompany,
 "UMbillstreet" => $this->billstreet,
 "UMbillstreet2" => $this->billstreet2,
 "UMbillcity" => $this->billcity,
 "UMbillstate" => $this->billstate,
 "UMbillzip" => $this->billzip,
 "UMbillcountry" => $this->billcountry,
 "UMbillphone" => $this->billphone,
 "UMemail" => $this->email,
 "UMfax" => $this->fax,
 "UMwebsite" => $this->website,
 "UMshipfname" => $this->shipfname,
 "UMshiplname" => $this->shiplname,
 "UMshipcompany" => $this->shipcompany,
 "UMshipstreet" => $this->shipstreet,
 "UMshipstreet2" => $this->shipstreet2,
 "UMshipcity" => $this->shipcity,
 "UMshipstate" => $this->shipstate,
 "UMshipzip" => $this->shipzip,
 "UMshipcountry" => $this->shipcountry,
 "UMshipphone" => $this->shipphone,
 "UMcardauth" => $this->cardauth,
 "UMpares" => $this->pares,
 "UMxid" => $this->xid,
 "UMcavv" => $this->cavv,
 "UMeci" => $this->eci,
 "UMcustid" => $this->custid,
 "UMcardpresent" => ($this->cardpresent?"1":"0"),
 "UMmagstripe" => $this->magstripe,
 "UMdukpt" => $this->dukpt,
 "UMtermtype" => $this->termtype,
 "UMmagsupport" => $this->magsupport,
 "UMcontactless" => $this->contactless,
 "UMsignature" => $this->signature,
 "UMsoftware" => $this->software,
 "UMignoreDuplicate" => $this->ignoreduplicate,
 "UMrefNum" => $this->refnum);

 // Create hash if pin has been set.
 if(trim($this->pin))
 {
 // generate random seed value
 $seed = microtime(true) . rand();

 // assemble prehash data
 $prehash = $this->command . ":" . trim($this->pin) . ":" . $this->amount . ":" .
            $this->invoice . ":" . $seed;

 // if sha1 is available,  create sha1 hash,  else use md5
 if(function_exists('sha1')) $hash = 's/' . $seed . '/' . sha1($prehash) . '/n';
 else $hash = 'm/' . $seed . '/' . md5($prehash) . '/n';

 // populate hash value
 $data['UMhash'] = $hash;
 }                

 // Figure out URL
 $url = ($this->gatewayurl?$this->gatewayurl:"https://www.usaepay.com/gate");
 if($this->usesandbox) $url = "https://sandbox.usaepay.com/gate";

 // Post data to Gateway
 $result=$this->httpPost($url, $data);
 if($result===false) return false;

 // result is in urlencoded format, parse into an array
 parse_str($result,$tmp);

 // check to make sure we received the correct fields
 if(!isset($tmp["UMversion"]) || !isset($tmp["UMstatus"]))
 {
 $this->result="Error";
 $this->resultcode="E";
 $this->error="Error parsing data from card processing gateway.";
 $this->errorcode=10132;
 return false;
 }

 // Store results
 $this->result=(isset($tmp["UMstatus"])?$tmp["UMstatus"]:"Error");
 $this->resultcode=(isset($tmp["UMresult"])?$tmp["UMresult"]:"E");
 $this->authcode=(isset($tmp["UMauthCode"])?$tmp["UMauthCode"]:"");
 $this->refnum=(isset($tmp["UMrefNum"])?$tmp["UMrefNum"]:"");
 $this->batch=(isset($tmp["UMbatch"])?$tmp["UMbatch"]:"");
 $this->avs_result=(isset($tmp["UMavsResult"])?$tmp["UMavsResult"]:"");
 $this->avs_result_code=(isset($tmp["UMavsResultCode"])?$tmp["UMavsResultCode"]:"");
 $this->cvv2_result=(isset($tmp["UMcvv2Result"])?$tmp["UMcvv2Result"]:"");
 $this->cvv2_result_code=(isset($tmp["UMcvv2ResultCode"])?$tmp["UMcvv2ResultCode"]:"");
 $this->vpas_result_code=(isset($tmp["UMvpasResultCode"])?$tmp["UMvpasResultCode"]:"");
 $this->convertedamount=(isset($tmp["UMconvertedAmount"])?$tmp["UMconvertedAmount"]:"");
 $this->convertedamountcurrency=
 (isset($tmp["UMconvertedAmountCurrency"])?$tmp["UMconvertedAmountCurrency"]:"");
 $this->conversionrate=(isset($tmp["UMconversionRate"])?$tmp["UMconversionRate"]:"");
 $this->error=(isset($tmp["UMerror"])?$tmp["UMerror"]:"");
 $this->errorcode=(isset($tmp["UMerrorcode"])?$tmp["UMerrorcode"]:"10132");
 $this->custnum=(isset($tmp["UMcustnum"])?$tmp["UMcustnum"]:"");

 // Obsolete variable (for backward compatibility) At some point they will no longer be set.
 $this->avs=(isset($tmp["UMavsResult"])?$tmp["UMavsResult"]:"");
 $this->cvv2=(isset($tmp["UMcvv2Result"])?$tmp["UMcvv2Result"]:"");

 if(isset($tmp["UMcctransid"])) $this->cctransid=$tmp["UMcctransid"];
 if(isset($tmp["UMacsurl"])) $this->acsurl=$tmp["UMacsurl"];
 if(isset($tmp["UMpayload"])) $this->pareq=$tmp["UMpayload"];

 if($this->resultcode == "A") return true;
 return false;

 }

 /**
 * Verify Proper Installation of USAePay class and required PHP Support
 *
 */
 function Test()
 {
 $curl_version=false;
 ?>
 <table border=1>
 <tr><th><b>Test</b></th><th><b>Result</b></th></tr>
 <tr><td valign="Top">Checking PHP Version</td>
 <td valign="top"><?php
 if(version_compare(phpversion(),"4.3.0")) {
 ?><font color="green">Ok</font><br>
 PHP version <?php echo phpversion()?> on <?php echo PHP_OS?> detected.
 <?php
 } else {
 ?><font color="red">Warning</font><br>
 PHP version <?php echo phpversion()?> detected. It is recommended that you
 upgrade to the most recent release of PHP.
 <?php
 }
 ?></td></tr>
 <tr><td valign="Top">Checking CURL Extension</td>
 <td valign="top"><?php
 if(function_exists("curl_version")) {
 $tmp=curl_version();
 // PHP 5 returns an array,  version 4 returns a string
 if(is_array($tmp)) {
 $curl_version=$tmp["version"];
 $curl_ssl_version=$tmp["ssl_version"];
 } else {
 $tmp=explode(" ", $tmp);
 foreach($tmp as $piece)
 {
 list($lib,$version)=explode("/",$piece);
 if(stristr($lib,"curl")) $curl_version=$version;
 elseif(stristr($lib,"ssl")) $curl_ssl_version=$version;
 }

 }
 ?><font color="green">Ok</font><br>
 Curl Extension (<?php echo $curl_version?>) detected.
 <?php
 } else {
 ?><font color="red">Error</font><br>
 Your PHP installation does not include the Curl Extension. You must either enable the curl
 extension in your php.ini file by removing the semi-colon from the line
  ";extension=php_curl.dll" or recompile
 php with the configuration flag: "--with-curl"
 <?php
 }
 ?>
 </td></tr>
 <tr><td valign="Top">Checking CURL SSL Support</td>
 <td valign="top"><?php
 if($curl_ssl_version) {
 ?><font color="green">Ok</font><br>
 SSL Version (<?php echo $curl_ssl_version?>) detected.
 <?php
 } else {
 ?><font color="red">Error</font><br>
 It appears that your curl installation does not include support for the HTTPS (ssl) protocal
 Proper SSL installation is required to communicate with the USAePay gateway securely.
 Please recompile curl
 with SSL support.
 <?php
 }
 ?>
 </td></tr>
 <tr><td valign="Top">Checking Communication with the Gateway</td>
 <td valign="top"><?php
 $ssl_failed=true;
 if(!$curl_version) {
 ?><font color="red">Error</font><br>
 No curl support
 <?php
 } else {
 $ch = curl_init(($this->gatewayurl?$this->gatewayurl:"https://www.usaepay.com/secure/gate.php") .
       "?VersionCheck=1&UMsoftware=" . rawurlencode($this->software));
 if(!$ch) {
 ?><font color="red">Error</font><br>
 Curl failed to connect to server:  (NULL $ch returned)
 <?php
 } else {

 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 if($this->cabundle) curl_setopt($ch, CURLOPT_CAINFO, $this->cabundle);                

 $result=curl_exec($ch);
 parse_str($result, $return);
 if($return["UMversion"]) {
 $ssl_failed=false;
 ?><font color="green">Ok</font><br>
 Successfully connected to the gateway.
 Detected version (<?php echo $return["UMversion"]?>) of the USAePay gateway API.
 <?php
 } else {
 $ch = curl_init(($this->gatewayurl?$this->gatewayurl:"https://www.usaepay.com/secure/gate.php") .
       "?VersionCheck=1&UMsoftware=" . rawurlencode($this->software));
 if($this->cabundle) curl_setopt($ch, CURLOPT_CAINFO, $this->cabundle);
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
 $result=curl_exec($ch);
 parse_str($result, $return);
 if($return["UMversion"]) {
 ?><font color="red">Warning</font><br>

 Successfully connected to the gateway but could not verify SSL certificate.  This usually
 indicates that you do not have curl set up with the proper root CA certificate.
 It is recommended that you install an up to date root ca bundle.  As a <b>temporary</b>
 work around you may disable the ssl cert check by adding the following to your script:<br><br><tt>
 $tran->ignoresslcerterrors=true;<br>
 <br></tt>
 <?php
 $ch = curl_init("https://www.verisign.com");
 if($this->cabundle) curl_setopt($ch, CURLOPT_CAINFO, $this->cabundle);
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 $result=curl_exec($ch);
 if(strlen($result)) {
 ?>
 SSL certificate for VeriSign was validated sucessfully. This would indicate that you have a
 root CA bundle installed but that it is outdated. See below.
 <?php
 } else {
 ?>
 Unable to verify SSL certificate for VeriSign.  This would indicate that you do not have a root
 CA bundle installed. See below.
 <?php
 }

 } else {
 $ch = curl_init("https://216.133.244.70/secure/gate.php?VersionCheck=1&UMsoftware=" .
 rawurlencode($this->software));
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
 $result=curl_exec($ch);
 parse_str($result, $return);
 if($return["UMversion"]) {
 ?><font color="red">Warning</font><br>

 Successfully connected to the gateway using a static IP but could not connect using hostname.
 This would indicate that you do not have DNS setup correctly.  Please correct your server
 configuration to include a valid DNS server. As a temporary work around you may add the following
 to your script:<br><br><tt>
 $tran->ignoresslcerterrors=true;<br>
 $tran->gatewayurl="https://216.133.244.70/gate.php";<br>
 <br></tt>
 <?php
 } else {
 ?><font color="red">Failed</font><br>
 Unable to establish connection to the USAePay Gateway.  It is possible that you are firewalling
 outbound traffic from your server.  To correct this problem,  you must add an allow entry in
 your firewall for ip <?php echo gethostbyname("www.usaepay.com")?> on port 443;
 <?php                                

 }

 }

 }
 }
 }
 ?>
 </td></tr>
 <?php if($ssl_failed) {?>

 <tr><td valign="Top">Looking for root CA Bundle</td>
 <td valign="top"><?php
 if(strstr(PHP_OS,"WIN")!==false) {
 foreach(array('c:\windows\ca-bundle.crt','c:\windows\curl-ca-bundle.crt') as $certpath)
 {
 if(is_file($certpath)) break;
 else unset($certpath);
 }

 if(!$certpath) $certpath="c:\windows\curl-ca-bundle.crt";
 } else {

 foreach(
 array("/usr/share/curl/curl-ca-bundle.crt",
 "/usr/local/share/curl/curl-ca-bundle.crt","/etc/curl/curl-ca-bundle.crt")
 as $certpath)
 {
 if(is_file($certpath)) break;
 else unset($certpath);
 }

 if(!$certpath) $certpath="/usr/share/curl/curl-ca-bundle.crt";
 }

 if(is_readable($certpath)) {
 ?><font color="green">Ok</font><br>
 A root CA bundle was found in "<?php echo $certpath?>".  Since the above test failed,  its possible
 that curl is not correctly configured to use this bundle.  You can correct the problem by add the
 following code to your script:<br><br><tt>
 $tran->cabundle='<?php echo $certpath?>';
 </tt>
 <br><br>
 It is also possible that your root CA bundle is out dated. Your root CA bundle was last updated
 <?php echo date("m/d/y", filemtime($certpath))?>.
 You can download a new file from:
 <a href="https://www.usaepay.com/topics/curl-ca-bundle.crt">

https://www.usaepay.com/topics/curl-ca-bundle.crt</a>

 </tt>
 <?php
 } else {
 ?><font color="red">Error</font><br>
 Unable to locate your root CA bundle file. You can correct this by downloading a bundle file from:
 <a href="https://www.usaepay.com/topics/curl-ca-bundle.crt">

https://www.usaepay.com/topics/curl-ca-bundle.crt</a>

 Once downloaded save this file to: <?php echo $certpath?> You may also need to add the following code:
 <br><br><tt>
 $tran->cabundle='<?php echo $certpath?>';
 </tt>
 <br><br>
 <?php
 }
 ?>
 </td></tr>
 <?php } ?>

 </table>
 <?php
 }

 function buildQuery($data)
 {
 if(function_exists('http_build_query')) return http_build_query($data);

 $tmp=array();
 foreach($data as $key=>$val) $tmp[] = rawurlencode($key) . '=' . rawurlencode($val);

 return implode('&', $tmp);

 }

 function httpPost($url, $data)
 {
 // if transport was not specified,  auto select transport
 if(!$this->transport)
 {
 if(function_exists("curl_version")) {
 $this->transport='curl';
 } else if(function_exists('stream_get_wrappers'))  {
 if(in_array('https',stream_get_wrappers())){
 $this->transport='stream';
 }
 }
 }

 // Use selected transport to post request to the gateway
 switch($this->transport)
 {
 case 'curl': return $this->httpPostCurl($url, $data);
 case 'stream': return $this->httpPostPHP($url, $data);
 }

 // No HTTPs libraries found,  return error
 $this->result="Error";
 $this->resultcode="E";
 $this->error="Libary Error: SSL HTTPS support not found";
 $this->errorcode=10130;
 return false;
 }

 function httpPostCurl($url, $data)
 {

 //init the connection
 //echo "<pre>";
 //print_r($data);
 //echo "</pre>";
 $ch = curl_init($url);
 if(!is_resource($ch))
 {
 $this->result="Error";
 $this->resultcode="E";
 $this->error="Libary Error: Unable to initialize CURL ($ch)";
 $this->errorcode=10131;
 return false;
 }

 // set some options for the connection
 curl_setopt($ch,CURLOPT_HEADER, 1);
 curl_setopt($ch,CURLOPT_POST,1);
 curl_setopt($ch,CURLOPT_TIMEOUT, ($this->timeout>0?$this->timeout:45));
 curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);

 // Bypass ssl errors - A VERY BAD IDEA
 if($this->ignoresslcerterrors)
 {
 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
 }

 // apply custom ca bundle location
 if($this->cabundle)
 {
 curl_setopt($ch, CURLOPT_CAINFO, $this->cabundle);
 }

 // set proxy
 if($this->proxyurl)
 {
 curl_setopt ($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
 curl_setopt ($ch, CURLOPT_PROXY, $this->proxyurl);
 }        

 // rawurlencode data
 $data = $this->buildQuery($data);        

 // attach the data
 curl_setopt($ch,CURLOPT_POSTFIELDS,$data);

 // run the transfer
 $result=curl_exec ($ch);

 //get the result and parse it for the response line.
 if(!strlen($result))
 {
 $this->result="Error";
 $this->resultcode="E";
 $this->error="Error reading from card processing gateway.";
 $this->errorcode=10132;
 $this->blank=1;
 $this->transporterror=$this->curlerror=curl_error($ch);
 curl_close ($ch);
 return false;
 }
 curl_close ($ch);
 $this->rawresult=$result;

 if(!$result) {
 $this->result="Error";
 $this->resultcode="E";
 $this->error="Blank response from card processing gateway.";
 $this->errorcode=10132;
 return false;
 }

 // result will be on the last line of the return
 $tmp=split("\n",$result);
 $result=$tmp[count($tmp)-1];        

 return $result;
 }

 function httpPostPHP($url, $data)
 {

 // rawurlencode data
 $data = $this->buildQuery($data);        

 // set stream http options
 $options = array(
 'http'=> array(
 'method'=>'POST',
 'header'=> "Content-type: application/x-www-form-urlencoded\r\n"
 . "Content-Length: " . strlen($data) . "\r\n",
 'content' => $data,
 'timeout' => ($this->timeout>0?$this->timeout:45),
 'user_agent' => 'uePHPLibary v' . USAEPAY_VERSION . ($this->software?'/' . $this->software:'')
 ),
 'ssl' => array(
 'verify_peer' => ($this->ignoresslcerterrors?false:true),
 'allow_self_signed' => ($this->ignoresslcerterrors?true:false)
 )
 );

 if($this->cabundle) $options['ssl']['cafile'] = $this->cabundle;

 if(trim($this->proxyurl)) $options['http']['proxy'] = $this->proxyurl;

 // create stream context
 $context = stream_context_create($options);

 // post data to gateway
 $fd = fopen($url, 'r', null, $context);
 if(!$fd)
 {
 $this->result="Error";
 $this->resultcode="E";
 $this->error="Unable to open connection to gateway";
 $this->errorcode=10132;
 $this->blank=1;
 if(function_exists('error_get_last')) {
 $err=error_get_last();
 $this->transporterror=$err['message'];
 } else if(isset($GLOBALS['php_errormsg'])) {
 $this->transporterror=$GLOBALS['php_errormsg'];
 }
 //curl_close ($ch);
 return false;
 }        

 // pull result
 $result = stream_get_contents($fd);

 // check for a blank response
 if(!strlen($result))
 {
 $this->result="Error";
 $this->resultcode="E";
 $this->error="Error reading from card processing gateway.";
 $this->errorcode=10132;
 $this->blank=1;
 fclose($fd);
 //$this->curlerror=curl_error($ch);
 //curl_close ($ch);
 return false;
 }        

 fclose($fd);
 return $result;

 }
}

//  umVerifyCreditCardNumber
//  Validates a credit card and returns the type of card.
//
//    Card Types:
//         1    Mastercard
//         2    Visa
//         3    American Express
//         4    Diners Club/Carte Blanche
//        10    Discover
//        20    enRoute
//        28    JCB    

/**
 * Evaluates a creditcard number and if valid, returns the card type code
 *
 * @param ccnum string
 * @return int
 */
function umVerifyCreditCardNumber($ccnum)
{
 global $umErrStr;

 //okay lets do the stupid
 $ccnum=str_replace("-","",$ccnum);
 $ccnum=str_replace(" ","",$ccnum);
 $ccnum=str_replace("/","",$ccnum);

 if(!ereg("^[[:digit:]]{1,200}$", $ccnum))
 {$umErrStr="Cardnumber contains characters that are not numbers";  return 0;}
 if(!ereg("^[[:digit:]]{13,16}$", $ccnum))
 {$umErrStr="Cardnumber is not between 13 and 16 digits long";  return 0;}

 // Run Luhn Mod-10 to ensure proper check digit
 $total=0;
 $y=0;
 for($i=strlen($ccnum)-1; $i >= 0; $i--)
 {
 if($y==1) $y=2; else $y=1;         //multiply every other digit by 2
 $tmp=substr($ccnum,$i,1)*$y;
 if($tmp >9) $tmp=substr($tmp,0,1) + substr($tmp,1,1);
 $total+=$tmp;
 }
 if($total%10) {$umErrStr="Cardnumber fails Luhn Mod-10 check digit";  return 0;}

 switch(substr($ccnum,0,1))
 {
 case 2: //enRoute - First four digits must be 2014 or 2149. Only valid length is 15 digits
 if((substr($ccnum,0,4) == "2014" || substr($ccnum,0,4) == "2149") && strlen($ccnum) == 15) return 20;
 break;
 case 3:
 //JCB - Um yuck, read the if statement below, and oh by the way 300 through 309 overlaps with diners club. bummer.
 if((substr($ccnum,0,4) == "3088" ||    substr($ccnum,0,4) == "3096" || substr($ccnum,0,4) == "3112"
 || substr($ccnum,0,4) == "3158" ||    substr($ccnum,0,4) == "3337" ||
 (substr($ccnum,0,8) >= "35280000" ||substr($ccnum,0,8) <= "358999999")) && strlen($ccnum)==16)
 {
 return 28;
 } else {
 switch(substr($ccnum,1,1))
 {
 case 4:
 case 7:
 // American Express - First digit must be 3 and second digit 4 or 7. Only Valid length is 15
 if(strlen($ccnum) == 15) return 3;
 break;
 case 0:
 case 6:
 case 8:
 //Diners Club/Carte Blanche - First digit must be 3 and second digit 0, 6 or 8. Only valid length is 14
 if(strlen($ccnum) == 14) return 4;
 break;
 }
 }
 break;
 case 4: // Visa - First digit must be a 4 and length must be either 13 or 16 digits.
 if(strlen($ccnum) == 13 || strlen($ccnum) == 16)
 {
 return 2;
 }
 break;

 case 5:
// Mastercard - First digit must be a 5 and second digit must be int the range 1 to 5 inclusive.
//Only valid length is 16
 if((substr($ccnum,1,1) >=1 && substr($ccnum,1,1) <=5) && strlen($ccnum) == 16)
 {
 return 1;
 }
 break;
 case 6: // Discover - First four digits must be 6011. Only valid length is 16 digits.
 if(substr($ccnum,0,4) == "6011" && strlen($ccnum) == 16) return 10;
 }

 // couldn't match a card profile. time to call it quits and go home.  this goose is cooked.
 $umErrStr="Cardnumber did not match any known creditcard profiles";
 return 0;
}
?>

Post to Twitter Post to Digg Post to Facebook Post to Google Buzz Send Gmail

1 Comment

  1. avatarharveybirdman

    You made some clear points there.

Leave a Comment

Your email address will not be published. Required fields are marked *