609 lines
20 KiB
PHP
609 lines
20 KiB
PHP
<?php
|
|
|
|
/**
|
|
* AgileBill - Open Billing Software
|
|
*
|
|
* This body of work is free software; you can redistribute it and/or
|
|
* modify it under the terms of the Open AgileBill License
|
|
* License as published at http://www.agileco.com/agilebill/license1-4.txt
|
|
*
|
|
* For questions, help, comments, discussion, etc., please join the
|
|
* Agileco community forums at http://forum.agileco.com/
|
|
*
|
|
* @link http://www.agileco.com/
|
|
* @copyright 2004-2008 Agileco, LLC.
|
|
* @license http://www.agileco.com/agilebill/license1-4.txt
|
|
* @author Tony Landis <tony@agileco.com>
|
|
* @package AgileBill
|
|
* @version 1.4.93
|
|
*/
|
|
|
|
include_once(PATH_MODULES.'checkout/base_checkout_plugin.class.php');
|
|
|
|
class plg_chout_USA_EPAY extends base_checkout_plugin
|
|
{
|
|
# Get the config values for this checkout plugin:
|
|
function plg_chout_USA_EPAY($checkout_id=false) {
|
|
|
|
$this->name = 'USA_EPAY';
|
|
$this->type = 'gateway'; // redirect, gateway, or other
|
|
$this->recurr_only = false;
|
|
$this->checkout_id = $checkout_id;
|
|
$this->support_cur = Array ('USD');
|
|
$this->getDetails($checkout_id);
|
|
}
|
|
|
|
# Validate the user submitted billing details at checkout:
|
|
function validate($VAR) {
|
|
return true;
|
|
}
|
|
|
|
|
|
# Perform the checkout transaction (new purchase):
|
|
function bill_checkout( $amount, $invoice, $currency_iso, $acct_fields, $total_recurring=false, $recurr_bill_arr=false) {
|
|
|
|
# Validate currency
|
|
if(!$this->validate_currency($currency_iso)) return false;
|
|
|
|
$ret=false;
|
|
if(!$this->validate_card_details($ret)) return false;
|
|
|
|
|
|
$tran=new umTransaction;
|
|
$tran->key = $this->cfg['key'];
|
|
$tran->testmode = $this->cfg['mode'];
|
|
$tran->ip = USER_IP;
|
|
$tran->card = $this->billing["cc_no"];
|
|
$tran->exp = $this->billing["exp_month"] . $this->billing["exp_year"];
|
|
$tran->amount = $amount;
|
|
$tran->invoice = $invoice;
|
|
$tran->cardholder = $this->account["first_name"] . ' ' . $this->account["last_name"];
|
|
$tran->street = $this->account["address1"] . ' ' . $this->account["address2"];
|
|
$tran->zip = $this->account["zip"];
|
|
$tran->description = "Invoice $invoice";
|
|
$tran->cvv2 = $this->billing["ccv"];
|
|
if($tran->Process()) {
|
|
$ret['status'] = 1;
|
|
$ret['avs'] = $tran->avs;
|
|
$ret['msg'] = $tran->authcode . ' '. $tran->cvv2;
|
|
} else {
|
|
$ret['status'] = 0;
|
|
$ret['msg'] = "Card Declined (" . $tran->result . ")";
|
|
$ret['msg'] .= " ". $tran->error;
|
|
if($tran->curlerror) {
|
|
echo "<b>Curl Error:</b> " . $tran->curlerror . "<br>";
|
|
exit;
|
|
}
|
|
}
|
|
|
|
if($ret['status'] == 1) {
|
|
return $ret;
|
|
} else {
|
|
global $VAR;
|
|
@$VAR['msg']=$ret["msg"];
|
|
return false;
|
|
}
|
|
}
|
|
|
|
# Stores new billing details, & return account_billing_id (gateway only)
|
|
function store_billing($VAR, $account=SESS_ACCOUNT) {
|
|
return $this->saveCreditCardDetails($VAR);
|
|
}
|
|
|
|
# Perform a transaction for an (new invoice):
|
|
function bill_invoice($VAR) {
|
|
return true;
|
|
}
|
|
|
|
# Issue a refund for a paid invoice (captured charges w/gateway)
|
|
function refund($VAR) {
|
|
return true;
|
|
}
|
|
|
|
# Void a authorized charge (gateways only)
|
|
function void($VAR) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// USA ePay PHP Library.
|
|
// v1.4.1 - December 27th, 2004
|
|
//
|
|
// Copyright (c) 2001-2004 USAePay
|
|
// Written by Tim McEwen (tim@usaepay.com)
|
|
//
|
|
|
|
/**
|
|
* 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
|
|
|
|
// 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; // mag stripe data. can be either Track 1, Track2 or Both (Required if card,exp,cardholder,street and zip aren't filled in)
|
|
var $cardpresent; // Must be set to true if processing a card present transaction (Default is false)
|
|
var $termtype; // The type of terminal being used: Optons are POS - cash register, StandAlone - self service terminal, Unattended - ie gas pump, Unkown (Default: Unknown)
|
|
var $magsupport; // Support for mag stripe reader: yes, no, unknown (default is unknown unless magstripe has been sent)
|
|
|
|
// 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
|
|
|
|
// 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 $ip; // ip address of remote host
|
|
var $testmode; // test transaction but don't process it
|
|
var $timeout; // transaction timeout. defaults to 45 seconds
|
|
var $gatewayurl; // url for the gateway
|
|
var $ignoresslcerterrors; // Bypasses ssl certificate errors. It is highly recommended that you do not use this option. Fix your openssl installation instead!
|
|
|
|
// 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
|
|
var $recurring; // Save transaction as a recurring transaction: yes/no
|
|
var $schedule; // How often to run transaction: daily, weekly, biweekly, monthly, bimonthly, quarterly, annually. Default is monthly.
|
|
var $numleft; // The number of times to run. Either a number or * for unlimited. Default is unlimited.
|
|
var $start; // When to start the schedule. Default is tomorrow. Must be in YYYYMMDD format.
|
|
var $end; // 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 $billamount; // Optional recurring billing amount. If not specified, the amount field will be used for future recurring billing payments
|
|
|
|
// 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 $software; // Allows developers to identify their application to the gateway (for troubleshooting purposes)
|
|
|
|
|
|
// 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
|
|
|
|
// 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 $curlerror; // curl 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 v1.4.0";
|
|
|
|
}
|
|
|
|
/**
|
|
* Verify that all required data has been set
|
|
*
|
|
* @return string
|
|
*/
|
|
function CheckData()
|
|
{
|
|
if(!$this->key) return "Source Key is required";
|
|
if($this->command=="capture")
|
|
{
|
|
if(!$this->refnum) return "Reference Number is required";
|
|
} else {
|
|
if($this->command=="check" || $this->command=="checkcredit") {
|
|
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";
|
|
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;
|
|
}
|
|
|
|
|
|
// check to make sure we have curl
|
|
if(!function_exists("curl_version"))
|
|
{
|
|
$this->result="Error";
|
|
$this->resultcode="E";
|
|
$this->error="Libary Error: CURL support not found";
|
|
$this->errorcode=10130;
|
|
return false;
|
|
}
|
|
|
|
//init the connection
|
|
$ch = curl_init(($this->gatewayurl?$this->gatewayurl:"https://www.usaepay.com/secure/gate.php"));
|
|
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);
|
|
# }
|
|
|
|
|
|
// format the data
|
|
$data = "UMkey=" . rawurlencode($this->key) . "&" .
|
|
"UMcommand=" . rawurlencode($this->command) . "&" .
|
|
"UMauthCode=" . rawurlencode($this->origauthcode) . "&" .
|
|
"UMcard=" . rawurlencode($this->card) . "&" .
|
|
"UMexpir=" . rawurlencode($this->exp) . "&" .
|
|
"UMbillamount=" . rawurlencode($this->billamount) . "&" .
|
|
"UMamount=" . rawurlencode($this->amount) . "&" .
|
|
"UMinvoice=" . rawurlencode($this->invoice) . "&" .
|
|
"UMorderid=" . rawurlencode($this->orderid) . "&" .
|
|
"UMponum=" . rawurlencode($this->ponum) . "&" .
|
|
"UMtax=" . rawurlencode($this->tax) . "&" .
|
|
"UMtip=" . rawurlencode($this->tip) . "&" .
|
|
"UMshipping=" . rawurlencode($this->shipping) . "&" .
|
|
"UMdiscount=" . rawurlencode($this->discount) . "&" .
|
|
"UMsubtotal=" . rawurlencode($this->subtotal) . "&" .
|
|
"UMname=" . rawurlencode($this->cardholder) . "&" .
|
|
"UMstreet=" . rawurlencode($this->street) . "&" .
|
|
"UMzip=" . rawurlencode($this->zip) . "&" .
|
|
"UMdescription=" . rawurlencode($this->description) . "&" .
|
|
"UMcvv2=" . rawurlencode($this->cvv2) . "&" .
|
|
"UMip=" . rawurlencode($this->ip) . "&" .
|
|
"UMtestmode=" . rawurlencode($this->testmode) . "&" .
|
|
"UMcustemail=" . rawurlencode($this->custemail) . "&" .
|
|
"UMcustreceipt=" . rawurlencode($this->custreceipt) . "&" .
|
|
"UMrouting=" . rawurlencode($this->routing) . "&" .
|
|
"UMaccount=" . rawurlencode($this->account) . "&" .
|
|
"UMssn=" . rawurlencode($this->ssn) . "&" .
|
|
"UMdlstate=" . rawurlencode($this->dlstate) . "&" .
|
|
"UMdlnum=" . rawurlencode($this->dlnum) . "&" .
|
|
"UMrecurring=" . rawurlencode($this->recurring) . "&" .
|
|
"UMbillamount=" . rawurlencode($this->billamount) . "&" .
|
|
"UMschedule=" . rawurlencode($this->schedule) . "&" .
|
|
"UMnumleft=" . rawurlencode($this->numleft) . "&" .
|
|
"UMstart=" . rawurlencode($this->start) . "&" .
|
|
"UMexpire=" . rawurlencode($this->end) . "&" .
|
|
"UMbillfname=" . rawurlencode($this->billfname) . "&" .
|
|
"UMbilllname=" . rawurlencode($this->billlname) . "&" .
|
|
"UMbillcompany=" . rawurlencode($this->billcompany) . "&" .
|
|
"UMbillstreet=" . rawurlencode($this->billstreet) . "&" .
|
|
"UMbillstreet2=" . rawurlencode($this->billstreet2) . "&" .
|
|
"UMbillcity=" . rawurlencode($this->billcity) . "&" .
|
|
"UMbillstate=" . rawurlencode($this->billstate) . "&" .
|
|
"UMbillzip=" . rawurlencode($this->billzip) . "&" .
|
|
"UMbillcountry=" . rawurlencode($this->billcountry) . "&" .
|
|
"UMbillphone=" . rawurlencode($this->billphone) . "&" .
|
|
"UMemail=" . rawurlencode($this->email) . "&" .
|
|
"UMfax=" . rawurlencode($this->fax) . "&" .
|
|
"UMwebsite=" . rawurlencode($this->website) . "&" .
|
|
"UMshipfname=" . rawurlencode($this->shipfname) . "&" .
|
|
"UMshiplname=" . rawurlencode($this->shiplname) . "&" .
|
|
"UMshipcompany=" . rawurlencode($this->shipcompany) . "&" .
|
|
"UMshipstreet=" . rawurlencode($this->shipstreet) . "&" .
|
|
"UMshipstreet2=" . rawurlencode($this->shipstreet2) . "&" .
|
|
"UMshipcity=" . rawurlencode($this->shipcity) . "&" .
|
|
"UMshipstate=" . rawurlencode($this->shipstate) . "&" .
|
|
"UMshipzip=" . rawurlencode($this->shipzip) . "&" .
|
|
"UMshipcountry=" . rawurlencode($this->shipcountry) . "&" .
|
|
"UMshipphone=" . rawurlencode($this->shipphone) . "&" .
|
|
"UMcardauth=" . rawurlencode($this->cardauth) . "&" .
|
|
"UMpares=" . rawurlencode($this->pares) . "&" .
|
|
"UMxid=" . rawurlencode($this->xid) . "&" .
|
|
"UMcavv=" . rawurlencode($this->cavv) . "&" .
|
|
"UMeci=" . rawurlencode($this->eci) . "&" .
|
|
"UMcustid=" . rawurlencode($this->custid) . "&" .
|
|
"UMcardpresent=" . ($this->cardpresent?"1":"0") . "&" .
|
|
"UMmagstripe=" . rawurlencode($this->magstripe) . "&" .
|
|
"UMtermtype=" . rawurlencode($this->termtype) . "&" .
|
|
"UMmagsupport=" . rawurlencode($this->magsupport) . "&" .
|
|
"UMrefNum=" . rawurlencode($this->refnum);
|
|
|
|
// Append md5hash if pin has been set.
|
|
if($this->pin)
|
|
{
|
|
$key=mktime();
|
|
$data.="&UMmd5hash=" . rawurlencode(md5($this->command . ":" . $this->pin . ":" . $this->amount . ":" . $this->invoice . ":" . $key)) . "&UMmd5key=" . $key;
|
|
}
|
|
|
|
// 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->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=explode("\n",$result);
|
|
$result=$tmp[count($tmp)-1];
|
|
|
|
// 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->error=(isset($tmp["UMerror"])?$tmp["UMerror"]:"");
|
|
$this->errorcode=(isset($tmp["UMerrorcode"])?$tmp["UMerrorcode"]:"10132");
|
|
|
|
// 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;
|
|
|
|
}
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
?>
|