Creating a Credit Card Validation Class With PHP

This is an article discussion thread for discussing the SitePoint article, “Creating a Credit Card Validation Class With PHP

I followed the instructions exactly and it did not work. After hitting validate it returned to the same page with all the forms blank…

if(!isset($submit)) should be if(!isset($_POST[‘submit’]))

post by jaypee is only true if register globals is turned off on the server

what about the last three digits on the back, the code

how would i get every thing about .or how would go about it.

Good tutorial web site 4 every level website designer :slight_smile:

yeah what about the three digit code on the back?!!!

IS there any way of determining whether the card is a debit or credit card?

aye i need help on tha credit card ting check me out at gposs@hotmail.com

This helps me a lot in my new project… Thanks a lot

Jaymer M. Jayoma

plz help me find hoe to go thru all de steps to validate a credit card from your seven steps.mail me at handsomena204@yahoo.com

this is very useful, but what if im ask to do a billing system, aside from this function, how will i actually deduct balances from an account in reality? do i have to talk to the bank and connect to their system, etc? any help will do… thanks! foxlance_g@yahoo.com / lancevincent@gmail.com

I like this tutorial but found that cctest.php did not work properly. I also found it confusing that the coding is all over the article. I’ve combined and posted the class and the test file at http://jon.cutrer.org/. I’ve also fixed the errors in cctest.php

Here is a cc validation class works great for me

enter the number and it returnes card type and if valid also check the expirey date

this is an amazing resource

http://www.phpclasses.org/browse/

BILL007

Look up LUHNs formula, the same thing can be done in javascript in about 40 lines

If the expiry date is the current year but has expired, this class let’s it through.
For example, if the current date is 03/07, I can enter 01/07 as valid, when in fact it is expired.

I doesn’t work for me. There must be something I’m not doing right. When I click the validate button, the form fields just go blank. More like resettng the form. can anyone help me out?
Here’s how my code looks:
The class:
<?php

define(“CARD_TYPE_MC”, 0);
define(“CARD_TYPE_VS”, 1);
define(“CARD_TYPE_AX”, 2);
define(“CARD_TYPE_DC”, 3);
define(“CARD_TYPE_DS”, 4);
define(“CARD_TYPE_JC”, 5);

class CCreditCard
{
// Class Members
var $__ccName = ‘’;
var $__ccType = ‘’;
var $__ccNum = ‘’;
var $__ccExpM = 0;
var $__ccExpY = 0;
// Constructor
function CCreditCard($name, $type, $num, $expm, $expy)
{
// Set member variables
if(!empty($name))
{
$this->__ccName = $name;
}
else
{
die(‘Must pass name to constructor’);
}
// Make sure card type is valid
switch(strtolower($type))
{
case ‘mc’:
case ‘mastercard’:
case ‘m’:
case ‘1’:
$this->__ccType = CARD_TYPE_MC;
break;
case ‘vs’:
case ‘visa’:
case ‘v’:
case ‘2’:
$this->__ccType = CARD_TYPE_VS;
break;
case ‘ax’:
case ‘american express’:
case ‘a’:
case ‘3’:
$this->__ccType = CARD_TYPE_AX;
break;
case ‘dc’:
case ‘diners club’:
case ‘4’:
$this->__ccType = CARD_TYPE_DC;
break;
case ‘ds’:
case ‘discover’:
case ‘5’:
$this->__ccType = CARD_TYPE_DS;
break;
case ‘jc’:
case ‘jcb’:
case ‘6’:
$this->__ccType = CARD_TYPE_JC;
break;
default:
die(‘Invalid type ’ . $type . ’ passed to constructor’);
}
// Don’t check the number yet,
// just kill all non numerics
if(!empty($num))
{
$cardNumber = ereg_replace(“[^0-9]”, “”, $num);

// Make sure the card number isnt empty
if(!empty($cardNumber))
{
$this->__ccNum = $cardNumber;
}
else
{
die(‘Must pass number to constructor’);
}
}
else
{
die(‘Must pass number to constructor’);
}
if(!is_numeric($expm) || $expm < 1 || $expm > 12)
{
die(‘Invalid expiry month of ’ . $expm . ’ passed to constructor’);
}
else
{
$this->__ccExpM = $expm;
}

// Get the current year
$currentYear = date(‘Y’);
settype($currentYear, ‘integer’);

if(!is_numeric($expy) || $expy < $currentYear || $expy
> $currentYear + 10)
{
die(‘Invalid expiry year of ’ . $expy . ’ passed to constructor’);
}
else
{
$this->__ccExpY = $expy;
}
}
function Name()
{
return $this->__ccName;
}

function Type()
{
switch($this->__ccType)
{
case CARD_TYPE_MC:
return ‘mastercard [1]’;
break;
case CARD_TYPE_VS:
return ‘Visa [2]’;
break;
case CARD_TYPE_AX:
return ‘Amex [3]’;
break;
case CARD_TYPE_DC:
return ‘Diners Club [4]’;
break;
case CARD_TYPE_DS:
return ‘Discover [5]’;
break;
case CARD_TYPE_JC:
return ‘JCB [6]’;
break;
default:
return ‘Unknown [-1]’;
}
}

function Number()
{
return $this->__ccNum;
}

function ExpiryMonth()
{
return $this->__ccExpM;
}

function ExpiryYear()
{
return $this->__ccExpY;
}
function SafeNumber($char = ‘x’, $numToHide = 4)
{
// Return only part of the number
if($numToHide < 4)
{
$numToHide = 4;
}

if($numToHide > 10)
{
$numToHide = 10;
}

$cardNumber = $this->__ccNum;
$cardNumber = substr($cardNumber, 0, strlen($cardNumber) - $numToHide);

for($i = 0; $i < $numToHide; $i++)
{
$cardNumber .= $char;
}

return $cardNumber;
}
function IsValid()
{
// Not valid by default
$validFormat = false;
$passCheck = false;
// Is the number in the correct format?
switch($this->__ccType)
{
case CARD_TYPE_MC:
$validFormat = ereg(“^5[1-5][0-9]{14}$”, $this->__ccNum);
break;
case CARD_TYPE_VS:
$validFormat = ereg(“^4[0-9]{12}([0-9]{3})?$”, $this->__ccNum);
break;
case CARD_TYPE_AX:
$validFormat = ereg(“^3[47][0-9]{13}$”, $this->__ccNum);
break;
case CARD_TYPE_DC:
$validFormat = ereg(“^3(0[0-5]|[68][0-9])[0-9]{11}$”, $this->__ccNum);
break;
case CARD_TYPE_DS:
$validFormat = ereg(“^6011[0-9]{12}$”, $this->__ccNum);
break;
case CARD_TYPE_JC:
$validFormat = ereg(“^(3[0-9]{4}|2131|1800)[0-9]{11}$”, $this->__ccNum);
break;
default:
// Should never be executed
$validFormat = false;
}
// Is the number valid?
$cardNumber = strrev($this->__ccNum);
$numSum = 0;

for($i = 0; $i < strlen($cardNumber); $i++)
{
$currentNum = substr($cardNumber, $i, 1);

// Double every second digit
if($i % 2 == 1)
{
$currentNum *= 2;
}

// Add digits of 2-digit numbers together
if($currentNum > 9)
{
$firstNum = $currentNum % 10;
$secondNum = ($currentNum - $firstNum) / 10;
$currentNum = $firstNum + $secondNum;
}

$numSum += $currentNum;
}
// If the total has no remainder it’s OK
$passCheck = ($numSum % 10 == 0);
if($validFormat && $passCheck) return true;
else return false;
}
}
?>

Next is the test page:

<?php include(‘class.creditcard.php’); ?>
<?php
if(!isset($submit))
{
?>

<h2>Validate Credit Card</h2>
<form name=“frmCC” action=“testcc.php” method=“post”>

Cardholders name: <input type=“text” name=“ccName”><br>
Card number: <input type=“text” name=“ccNum”><br>
Card type: <select name=“ccType”>
<option value=“1”>mastercard</option>
<option value=“2”>Visa</option>
<option value=“3”>Amex</option>
<option value=“4”>Diners</option>
<option value=“5”>Discover</option>
<option value=“6”>JCB</option>
</select><br>

Expiry Date: <select name=“ccExpM”>

<?php

for($i = 1; $i &lt; 13; $i++)
{ echo '&lt;option&gt;' . $i . '&lt;/option&gt;'; }

?>

</select>

<select name=“ccExpY”>

<?php

for($i = 2002; $i &lt; 2013; $i++)
{ echo '&lt;option&gt;' . $i . '&lt;/option&gt;'; }

?>

</select><br><br>

<input type=“submit” name=“submit” value=“Validate”>
</form>

<?

}
else
{
// Check if the card is valid
$cc = new CCreditCard($ccName, $ccType, $ccNum, $ccExpM, $ccExpY);

?>

<h2>Validation Results</h2>
<b>Name: </b><?=$cc->Name(); ?><br>
<b>Number: </b><?=$cc->SafeNumber(‘x’, 6); ?><br>
<b>Type: </b><?=$cc->Type(); ?><br>
<b>Expires: </b><?=$cc->ExpiryMonth() . ‘/’ .
$cc->ExpiryYear(); ?><br><br>

<?php

echo '&lt;font color="blue" size="2"&gt;&lt;b&gt;';  

if($cc-&gt;IsValid())
echo 'VALID CARD';
else
echo 'INVALID CARD';

echo '&lt;/b&gt;&lt;/font&gt;';

}
?>

It may be that your server doesn’t have the REGISTER_GLOBALS option set (as it’s insecure) and so the code given will fail. The register_globals option causes PHP to automatically set variables from form inputs (e.g. a form field with the name “submit” will cause $submit to be set, and so on). However, this could cause security problems and many hosts disable it.

In the test page, change “if(!isset($submit))” to “if(!isset($_REQUEST[‘submit’]))”. Nobody should assume that register_globals is set any more, as it will be removed in PHP6.

This is a very old article so its no surprise some code in it is not forward compatible.