Helpful Information
 
 
Category: Post a PHP snippet
Credit Card Class

This is a class I wrote for validating UK credit and debit cards from multiple sources, it defaults to "post" but other input sources can be specified (or you can modify it to accept the values as parameters of the constructor.
It includes validation for Visa, Mastercard, Switch, Solo and Amex but more card type can be added easily, if you dont have a validation pattern for the card type just return from the function (see the Solo example) and the type validation will be skipped.



<?
class creditCard
{
var $type;
var $number;
var $name;
var $issue;
var $startDate;
var $expDate;
var $secCode;
var $errors = array();
var $valid = true;
var $maskedNumber;
var $isDebit = false;

function creditCard($source="post")
{
switch($source)
{
case "post":
extract($_POST);
$this->type = $type;
$this->number = $number;
$this->name = $name;
$this->issue = $issue;
$this->startDate = $startMonth."/".$startYear;
$this->expDate = $expMonth."/".$expYear;
$this->secCode = $secCode;
$this->maskedNumber = $this->maskNumber();
break;
case "db":
//fill in your own db query here
break;
}


}

function validate()
{
$this->checkNumber();
$this->checkType();
$this->checkExp();
$this->checkCVV();
$this->checkName();
if($this->isDebit)
{
$this->checkDebit();
}
}

function checkNumber()
{
$number = strrev($this->number);
$number = ereg_replace("[^0-9]", "", $number);
$arrNumber = str_split($number);
for($i = 0; $i<count($arrNumber); $i++)
{
if(($i%2) == 0)
{
$arrNumber[$i+1] *=2;
}
}
$number = implode("", $arrNumber);
foreach(str_split($number) as $digit)
{
$sum += $digit;

}
$valid = (($sum % 10)==0);
$this->errors[] =($valid)?"":"The card number you entered is not valid";
$this->valid = ($valid) ? $this->valid : false;
}

function checkType()
{
switch(strtolower($this->type))
{
case "mastercard":
$strPattern = "/^((5[1-5]\d{2})(-?\s?\d{4}){3})$/i";
break;
case "visa":
$strPattern = "/^((4\d{3})(-?\s?\d{4}){3})$/i";
break;
case "switch":
$strPattern = "/^((67\d{2})(-?\s?\d{4}){3})$/i";
$this->isDebit = true;
break;
case "solo":
$this->isDebit = true;
return;
break;
case "amex":
$strPattern = "/^((3[4,7])\d{2}-?\s?\d{6}-?\s?\d{5})$/i";
break;
default:
$this->errors[] = "The card type you selected is not valid";
}

$valid = (@preg_match($strPattern, $this->number));
$this->errors[] = ($valid)?"":"The card number you entered did not match the card type you selected";
$this->valid = ($valid) ? $this->valid : false;
}

function checkExp()
{
$arrDate = explode("/", $this->expDate);
if(count($arrDate)< 2 )
{
return false;
}
$expDate = @mktime(0,0,0,$arrDate[0],date('t',mktime(0,0,0,2,1,2004)),$arrDate[1]);
$valid = ($expDate > mktime());
$this->errors[] = ($valid) ? "" : "Your card has expired";
$this->valid = ($valid) ? $this->valid : false;
}

function checkStart()
{
$arrDate = explode("/", $this->startDate);
$startDate = mktime(0,0,0,$arrDate[0], 1, $arrDate[1]);
return (($startDate < mktime())&& ($startDate > 0));
}

function checkDebit()
{
if(((is_numeric($this->issue))&&($this->issue > 0))||$this->checkStart())
{
return;
}
else
{
$this->valid = false;
$this->errors[] = "Debit cards require a start date or an issue number.";
}
}

function checkCVV()
{
$valid = ((is_numeric($this->secCode))&&(strlen($this->secCode)==3));
$this->valid = ($valid) ? $this->valid : false;
$this->errors[] = ($valid)? "":"Your security code should be 3 digits in length and is found on the back of your card";
}

function checkName()
{
$valid = (@preg_match("/^[a-z\.]*\s?([a-z\-\']+\s)+[a-z\-\']+$/i", $this->name));
$this->errors[] = "Please enter your name as it appears on your card";
$this->valid = ($valid) ? $this->valid : false;
}

function maskNumber()
{
$arrNumber = str_split($this->number);
for($i = 0; $i<count($arrNumber); $i++)
{
if((is_numeric($arrNumber[$i]))&&($i< (count($arrNumber)-4)))
{
$maskedNumber .="x";
}
else
{
$maskedNumber .= $arrNumber[$i];
}
}
return $maskedNumber;
}

}

example usage:


if(isset($_POST['submit']))
{
$CC = new creditCard;
$CC->validate();
if($CC->valid)
{
echo $CC->maskedNumber;
}
else
{
foreach($CC->errors as $error)
{
if(!empty($error))
{
echo $error."<br />";
}
}
}
}

you have a typo here:

case "masterCard":
you are doing strtolower right above it

you have a typo here:

case "masterCard":
you are doing strtolower right above it
ta ;)
Edited.

That expiration date validator could be a problem across timezones, but otherwise very nice.

That expiration date validator could be a problem across timezones, but otherwise very nice.
If it comes down to hours you're cutting it a bit fine anyway ;) Dont know about anyone else but I usually get my new card at least a week before my old card expires.










privacy (GDPR)