Wednesday, April 30, 2008

Something about Credit Card Validations.....

Credit Card transaction is one of the important parts of all e-commerce websites. There are lots of Credit Card Payment Gateways, which help you to authenticate credit cards. But almost all credit card payment gateways took very long time to respond back. And that might cause performance issue with our developed website.

We can reduce the payment gateway server trips by validating the credit cards in our system itself. As per my experience, most of the time the customer enters wrong credit card number and that cause the waiting time. We can validate those numbers in our system itself using JavaScript or server validators (i.e. Custom Validator in .Net). We can achieve this using Regular Expression. But first let’s start with some facts with Credit Card Numbers… There are total 5 types of widely accepted credit cards, Visa, Master Card, American Express, Diners Club and Discover. The card number pattern is depending on the type of card. The number pattern consists of the length of Card Number and the number prefix.

Card Type Prefix Length Example
Visa 4 16 4563 2214 3215 8542
Master Card 51 to 55 16 5147 2254 6585 4521
American Express




3422 4587 9874 125

3741 5478 9854 654

Diners Club





3000 2544 8874 12

3685 1475 8544 32

3874 8745 6654 85

Discover 6011 16 6011 7415 6587 2265

We can validate these credit cards using regular expression. Find below table of the regular expression for each credit card type.

Card Type Regular Expression
Visa ^4\d{3}-?\d{4}-?\d{4}-?\d{4}$
Master Card ^5[1-5]\d{2}-?\d{4}-?\d{4}-?\d{4}$
American Express ^3[4,7]\d{13}$
Diners Club ^3[0,6,8]\d{12}$
Discover ^6011-?\d{4}-?\d{4}-?\d{4}$

Below is the example of a validation function of Java Script for the Credit Card Validation using Regular Expression and “mod 10” algorithm…

This code validate the credit card using Regular Expression and the "mod 10" algorithm. All the card has different prefix and the length. We are using regular expression to validate the card length and prefix. The "mod 10" validation will be performed after the card number has the right prefix and correct length. Card with even number digits and Odd number of digits validate differently. Every other digit, starting with the second digit (first digit for American Express) is added together. Then a second pass is made, again with every other digit, starting this time with the first digit (second digit for American Express). Each digit is multiplied by 2 in second pass. If the digit multiplied by 2 is greater than or equal to 10, the total minus 9 is added to the original sum from the first pass. If the digit multiplied by 2 is less than 10, then that total is added in to the original sum from the first pass. After the two passes, the total should be evenly divisible by 10.

function isValidCreditCard(cardtype, ccnumber) 
if (cardtype == "Visa")
// Prefix: 4, Lenght: 16
var regEx = /^4\d{3}-?\d{4}-?\d{4}-?\d{4}$/;
else if (cardtype == "MasterCard")
// Prefix: 51-55, Length: 16
var regEx = /^5[1-5]\d{2}-?\d{4}-?\d{4}-?\d{4}$/;
else if (cardtype == "Discover")
// Prefix: 6011, Length: 16
var regEx = /^6011-?\d{4}-?\d{4}-?\d{4}$/;
else if (cardtype == "AmericanExpress")
// Prefix: 34 or 37, Length: 15
var regEx = /^3[4,7]\d{13}$/;
else if (cardtype == "Diners")
// Prefix: 30, 36, or 38, Length: 14
var regEx = /^3[0,6,8]\d{12}$/;

if (!regEx.test(ccnumber)) return false;

// Remove all dashes.
ccnumber = ccnumber.split("-").join("");

// Add even digits in even length strings or odd digits in odd length strings.
var checksum = 0;

for (var cnt=(2-(ccnumber.length % 2)); cnt<=ccnumber.length; cnt+=2)
checksum += parseInt(ccnumber.charAt(cnt-1));

for (var cnt=(ccnumber.length % 2) + 1; cnt {
var digit = parseInt(ccnumber.charAt(cnt-1)) * 2;
if (digit < 10)
checksum += digit;
checksum += (digit-9);

if ((checksum % 10) == 0)
return true;
return false;

The first character in a string is charAt(0), so that is why 1 is subtracted from the value of cnt all the time. In the first pass, if the length is even, then the length mod 2 results 0. So 2 minus 0 is 2, so the value of cnt will walk through the even numbered digits. In the first pass for strings of odd length, the length mod 2 is 1, so 2 minus 1 is 1, and the value of cnt will walk through the odd numbered digits.

This way we can validate credit card numbers client side and save some server trips.

Please feel free to comment on this post. Your feedback and suggestions will be highly appreciated.