This code handles the most popular types of credit card: Visa, Master Card, Discover, American Express, and Diner's Club. Each of these cards start out with a different prefix and card number length. This information is used for the regular expression validation. After the card number has the right prefix and is the correct length, a "mod 10" validation is performed on the credit card number. This code is a bit strange and needs some explanation. Cards with an even number of digits go through differently than cards with an odd number of digits (American Express). 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). During this second pass, each digit is multipled by 2. 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, that total is added to the original sum from the first pass. After the two passes, the total should be evenly divisible by 10. This is the check that the JavaScript code goes through to validate the credit card.

The code handles the different cases for cards of even length and cards for odd length (American Express) with the same code. That part is probably the most confusing part of the code when looking at it.

function isValidCreditCard(type, ccnum) {

if (type == "Visa") {

// Visa: length 16, prefix 4, dashes optional.

var re = /^4\d{3}-?\d{4}-?\d{4}-?\d{4}$/;

} else if (type == "MC") {

// Mastercard: length 16, prefix 51-55, dashes optional.

var re = /^5[1-5]\d{2}-?\d{4}-?\d{4}-?\d{4}$/;

} else if (type == "Disc") {

// Discover: length 16, prefix 6011, dashes optional.

var re = /^6011-?\d{4}-?\d{4}-?\d{4}$/;

} else if (type == "AmEx") {

// American Express: length 15, prefix 34 or 37.

var re = /^3[4,7]\d{13}$/;

} else if (type == "Diners") {

// Diners: length 14, prefix 30, 36, or 38.

var re = /^3[0,6,8]\d{12}$/;

}

if (!re.test(ccnum)) return false;

// Remove all dashes for the checksum checks to eliminate negative numbers

ccnum = ccnum.split("-").join("");

// Checksum ("Mod 10")

// Add even digits in even length strings or odd digits in odd length strings.

var checksum = 0;

for (var i=(2-(ccnum.length % 2)); i<=ccnum.length; i+=2) {

checksum += parseInt(ccnum.charAt(i-1));

}

// Analyze odd digits in even length strings or even digits in odd length strings.

for (var i=(ccnum.length % 2) + 1; i<ccnum.length; i+=2) {

var digit = parseInt(ccnum.charAt(i-1)) * 2;

if (digit < 10) { checksum += digit; } else { checksum += (digit-9); }

}

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

}

Note that the first character in a string is charAt(0), so that is why 1 is subtracted from the value of i all the time. For the first pass, if the length is even, then the length mod 2 ("mod" is a mathematical term that says to return the remainder of the first number divided by the second number, so 5 mod 2 is 1 and 6 mod 2 is 0. % is the mod operator in JavaScript) results in 0. So 2 minus 0 is 2, so the value of i 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 i will walk through the odd numbered digits.