Credit Card Validation
Credit Card Validation
What do we actually mean when we say "validate a credit card number"? Quite simply it means that we run a credit card number through a special algorithm known as the Mod 10 algorithm.
This algorithm processes some simple numerical data validation routines against the number, and the result of this algorithm can be used to determine whether or not a credit card number is valid. There are several different types of credit cards that one can use to make a purchase, however they can all be validated using the Mod 10 algorithm.
As well as passing the Mod 10 algorithm, a credit card number must also pass several different formatting rules. A list of these rules for each of the six most popular credit cards is shown below:
- mastercard: Must have a prefix of 51 to 55, and must be 16 digits in length.
- Visa: Must have a prefix of 4, and must be either 13 or 16 digits in length.
- American Express: Must have a prefix of 34 or 37, and must be 15 digits in length.
- Diners Club: Must have a prefix of 300 to 305, 36, or 38, and must be 14 digits in length.
- Discover: Must have a prefix of 6011, and must be 16 digits in length.
- JCB: Must have a prefix of 3, 1800, or 2131, and must be either 15 or 16 digits in length.
As mentioned earlier, in this article we will create a PHP class that will hold the details of a credit card number and expose a function that indicates whether or not the number of that credit card is valid (i.e. whether it passed the Mod 10 algorithm or not). Before we create that class however, let's look at how the Mod 10 algorithm works.
Test Credit Card NumbersThese credit card numbers can be used to test a transaction at ECHO. They are numbers that banks will reject as invalid without problem and are intended for system testing.
These test numbers work just like live accounts, but none of the transactions are actually settled and no money moves. Be sure to use valid data or you will get errors on things like card numbers, checking information, check writer ID info, etc. Please do not use a real credit card with test accounts unless you run a $1.00 transaction. If you do more, your card will have the funds held by each authorization until it expires. The test card will always give a result, the address verification and security code will match regardless of the input values. Furthermore, it will authorize with no expiration date. If you need to see different address verification and security code results, you must use a live credit card. In this case, please use low dollar amounts ($1.00).
Test VISA credit card number: 4005550000000019
Test Credit Card Numbers | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Test Credit Card Numbers: | |
Visa: | 4111-1111-1111-1111 |
MasterCard: | 5431-1111-1111-1111 |
Amex: | 341-1111-1111-1111 |
Discover: | 6011-6011-6011-6611 |
| |
| |
Credit Card Prefix Numbers: | |
Visa: | 13 or 16 numbers starting with 4 |
MasterCard: | 16 numbers starting with 5 |
Discover: | 16 numbers starting with 6011 |
AMEX: | 15 numbers starting with 34 or 37 |
The Mod 10 Algorithm
There are three steps that the Mod 10 algorithm takes to determine whether or not a credit card number is valid. We will use the valid credit card number 378282246310005 to demonstrate these steps:
Step One
The number is reversed and the value of every second digit is doubled, starting with the digit in second place:
378282246310005
becomes...
500013642282873
and the value of every second digit is doubled:
5 0 0 0 1 3 6 4 2 2 8 2 8 7 3
x2 x2 x2 x2 x2 x2 x2
-------------------------------------------
0 0 6 8 4 4 14
Step Two
The values of the numbers that resulted from multiplying every second digit by two are added together (i.e. in our example above, multiplying the 7 by two resulted in 14, which is 1 + 4 = 5). The result of these additions is added to the value of every digit that was not multiplied (i.e. the first digit, the third, the fifth, etc):
5 + (0) + 0 + (0) + 1 + (6) + 6 + (8) + 2 + (4) + 8 + (4) + 8 + (1 + 4) + 3
= 60
Step Three
When a modulus operation is applied to the result of step two, the remainder must equal 0 in order for the number to pass the Mod 10 algorithm. The modulus operator simply returns the remainder of a division, for example:
10 MOD 5 = 0 (5 goes into 10 two times and has a remainder of 0)
20 MOD 6 = 2 (6 goes into 20 three times and has a remainder of 2)
43 MOD 4 = 3 (4 goes into 43 ten times and has a remainder of 3)
So for our test credit card number 378282246310005, we apply a modulus of 10 to the result from step two, like this:
60 MOD 10 = 0
The modulus operation returns 0, indicating that the credit card number is valid.
Now that we understand the Mod 10 algorithm, it's really quite easy to create our own version to validate credit card numbers with PHP. Let's create our credit card function now.
private bool CheckCCNo(string sInput )
{
///What: This routine will check the validity of a CC no... It will NOT check the account behind it.
///Who: Eric D. Burdo
///When: 6/16/03
///How: bR = CheckCCNo("5412222244447777")
/// this will return True or False, depending on whether the CC passes or fails
///
///The Luhn Mod 10 Algorithm is a means to validate credit card numbers. Note
/// that it validates the *number*, not the *account*. A number can be a valid
/// credit card number but not have an account associated with it. Or the
/// account could be deliquent, cancelled, etc.
///THE ALGORITHM:
/// 1. Starting from the end of the string of digits, double each even (2nd,
/// 4th, etc.) digit. If the result is 10 or more, store it as 2 digits (1
/// and 0, 1 and 8, etc.)
/// 2. Sum the odd digits (starting from the back) and the result digits.
/// 3. The resulting number should be divisible by 10. If so, the original
/// string passes the test.
///EXAMPLE (Credit Card number: 1234 5678 7654 3210):
/// (Back)
/// 0 = 0 => +0
/// 1 * 2 = 2 => +2
/// 2 = 2 => +2
/// 3 * 2 = 6 => +6
/// 4 = 4 => +4
/// 5 * 2 = 10 => +1+0
/// 6 = 6 => +6
/// 7 * 2 = 14 => +1+4
/// 8 = 8 => +8
/// 7 * 2 = 14 => +1+4
/// 6 = 6 => +6
/// 5 * 2 = 10 => +1+0
/// 4 = 4 => +4
/// 3 * 2 = 6 => +6
/// 2 = 2 => +2
/// 1 * 2 = 2 => +2
/// (Front) =====
/// =60 And 60 MOD 10 = 0 so it passes.
///---------------------------------------------------------------------------
int iIndex=0, iCheckSum=0;
bool bOnlyDigits=false, bEven=false;
string sDigits="";
//Validate the input. The string should only contain digits 0-9.
bOnlyDigits = (0 < iindex =" 0;" bonlydigits =" false;" iindex =" sInput.Length">= 0; --iIndex)
{
if (bEven)
{
int iR = Convert.ToInt32(sInput.Substring(iIndex, 1));
sDigits = string.Concat(sDigits, Convert.ToString(iR * 2));
}
else
{
sDigits = string.Concat(sDigits, sInput.Substring(iIndex, 1));
}
bEven = !bEven;
}
//Add up the digits in the string into the checksum.
iCheckSum = 0;
for (iIndex = 0; iIndex < ichecksum =" iCheckSum" ichecksum =" -1;"> 0
}
iIndex = iCheckSum % 10;
return Convert.ToBoolean(iIndex == 0);
}
private string DetermineCardType(string sCCNo )
{
//CardTypes Prefix Width
//American Express 34, 37 15
//Diners Club 300 to 305, 36 14
//Carte Blanche 38 14
//Discover 6011 16
//EnRoute 2014, 2149 15
//JCB 3 16
//JCB 2131, 1800 15
//Master Card 51 to 55 16
//Visa 4 13, 16
try {
switch (Convert.ToInt32(sCCNo.Substring(0, 2)))
{
case 34:
case 37:
return "Card type is: American Express";
//break;
case 36:
return "Card type is: Diners Club";
//break;
case 38:
return "Card type is: Carte Blanche";
//break;
case 51:
case 52:
case 53:
case 54:
case 55:
return "Card type is: Master Card";
//break;
default:
switch (Convert.ToInt32(sCCNo.Substring(0, 4)))
{
case 2014:
case 2149:
return "Card type is: EnRoute";
//break;
case 2131:
case 1800:
return "Card type is: JCB";
//break;
case 6011:
return "Card type is: Discover";
//break;
default:
switch (Convert.ToInt16(sCCNo.Substring(0, 3)))
{
case 300:
case 301:
case 302:
case 303:
case 304:
case 305:
return "Card type is: American Diners Club";
//break;
default:
switch (Convert.ToInt32(sCCNo.Substring(0, 1)))
{
case 3:
return "Card type is: JCB";
//break;
case 4:
return "Card type is: Visa";
//break;
default:
return "Unable to determine credit card type.";
//break;
}
}
}
}
}
catch (Exception e)
{
return "Unable to determine credit card type.";
}
}