At one point or another everyone gets to a project where they’ve got to get credit card details from a client to process a payment. The security aspect of this is a whole book on it’s own, but that’s not the point of this post. I’ve always been fascinated how ID numbers (or social security numbers) work and how they can be validated.
I decided a few months ago to do some research into writing a simple credit card verification function. Obviously this doesn’t cater for the fact that it might be a stolen or canceled card, but it will give you an idea if the credit card number, validation numbers and expiration date are correct.
First I started by finding out what the patterns are for the varies credit card companies. I found this on Sitepoint. Although he has a complete class on that site, what is the fun in it all if you don’t write your own code to understand it a bit better?
Apart from passing the Mod 10 algorithm, each credit card company has further checks:
Ok, so what is the Mod 10 Algorithm? It is a algorithm that will be able to spot errors of the digits in the credit card number. It’s not specifically made for credit card numbers, but has got other uses. Check out Wikipedia.org for more information. To explain it, let’s look at the steps thereof.
Step of the Mod 10 Algorithm for the number 4111111111111111:
This is also called a MOD operator. The MOD operator divides a number by another number and then gives you the remainder.
Those are the 2 tests a credit card number must pass. First checking if it’s got correct digits according to the type of credit card and then checking if the digits pass the Mod 10 algorithm.
Let’s look at the code for this.
function mod10_check($number) { /* validate mod10 check on the number */ $rcode = strrev($number); $csum = 0; for ($i = 0; $i < strlen($rcode); $i++) { $current_num = intval($rcode[$i]); if($i & 1) { /*every 2nd digit - odd*/ $current_num *= 2; } /* split the digits and add up */ $csum += $current_num % 10; if ($current_num > 9) { $csum += 1; } } if ($csum % 10 == 0) { return true; } else { return false; } } function validate_ccnumber($ccnumber) { /* validate; return card type if valid. */ $c_type = ""; $c_reg = array( "/^4\d{12}(\d\d\d){0,1}$/" => "visa", "/^5[12345]\d{14}$/" => "mastercard", "/^6011\d{12}$/" => "discover", "/^30[012345]\d{11}$/" => "diners", "/^3[68]\d{12}$/" => "diners", ); foreach ($c_reg as $reg => $type) { if (preg_match($reg, $ccnumber)) { $c_type = $type; break; } } if (!$c_type) { //card type not found return false; } if (mod10_check($ccnumber)) { return $c_type; } else { return false; } }
I’ve split this up into 2 functions, namely mod10_check and validate_ccnumber. You can incorporate them into one function, I just found it easier this way so that I can reuse mod10_check later on separately.
So first I make use of regular expressions to determine which card type it is. I’ve only made use of the well known cards here, but it is easy to add additional card regular expressions as you see fit.
If the card type is found and checks out okay, we do the final check which is the Mod10 algorithm. If that also checks out, we return the card type from the function.
Sample usage:
if ($result = validate_ccnumber('4111111111111111')) { echo $result; } else { echo "invalid"; }