Return to Snippet

Revision: 68131
at December 1, 2014 09:53 by geneticcode


Initial Code
// CreditCard object definition
function CreditCard(ccn){
    // Card properties
    this.valid = true;
    this.error = "None";
    this.digits = "";
    this.industry = "N/A";
    this.MII = "N/A";
    this.IIN = "N/A";
    this.issuer = "N/A";
    this.validation = "None";
    this.accountNumber = "N/A";
    this.checksum = "N/A";
    
    // Methods
    // +++++
    // Luhn Algorithm check
    this.luhnCheck = function(){
        var i = this.digits.length;
        var even = true; //zero is even
        var sum = 0;
        while(i--){
            even = !even;
            digit = parseInt(this.digits[i]);
            if(even){
                digit = digit * 2;
                if(digit > 9){
                    d = String(digit);
                    digit = parseInt(d[0]) + parseInt(d[1]);
                }
            }
            sum += digit;
        }
        return (sum % 10) === 0;
    };
    // Determine the issuer based on the IIN
    // Data source: http://en.wikipedia.org/wiki/Bank_card_number#Issuer_identification_number_.28IIN.29
    this.getIssuer = function(){
        var iin = this.IIN;
        var i = this.digits.length;
        var validLength = false;
        if(iin.substring(0,2) === "34" || iin.substring(0,2) === "37"){
            this.issuer = "American Express";
            this.validation = "Luhn";
            validLength = i === 15;
        }else if(iin.substring(0,2) === "56"){
            this.issuer = "Bankcard";
            this.validation = "Luhn";
            validLength = i === 16;
        }else if(iin.substring(0,2) === "62"){
            this.issuer = "China UnionPay (Discover)";
            this.validation = "Length";
            validLength = i > 15 && i < 20;
        }else if(iin.substring(0,2) === "30" || iin.substring(0,2) === "36" || iin.substring(0,2) === "38" || iin.substring(0,2) === "39"){
            this.issuer = "Diners Club International";
            this.validation = "Luhn";
            validLength = i === 14;
        }else if(iin.substring(0,2) === "20" || iin.substring(0,2) === "21"){
            this.issuer = "Diners Club enRoute";
            this.validation = "Length";
            validLength = i === 15;
        }else if(iin.substring(0,2) === "54" || iin.substring(0,2) === "55"){
            this.issuer = "Diners Club";
            this.validation = "Luhn";
            validLength = i === 16;
        }else if(iin.substring(0,2) === "60" || iin.substring(0,2) === "62" || iin.substring(0,2) === "64" || iin.substring(0,2) === "65"){
            this.issuer = "Discover Card";
            this.validation = "Luhn";
            validLength = i === 16;
        }else if(iin.substring(0,3) === "636"){
            this.issuer = "InterPayment";
            this.validation = "Luhn";
            validLength = i > 15 && i < 20;
        }else if(iin.substring(0,3) === "637" || iin.substring(0,3) === "638" || iin.substring(0,3) === "639"){
            this.issuer = "InstaPayment";
            this.validation = "Luhn";
            validLength = i === 16;
        }else if(iin.substring(0,2) === "35"){
            this.issuer = "JCB";
            this.validation = "Luhn";
            validLength = i === 16;
        }else if(iin.substring(0,4) === "6304" || iin.substring(0,4) === "6706" || iin.substring(0,4) === "6771" || iin.substring(0,4) === "6709"){
            this.issuer = "Laser";
            this.validation = "Luhn";
            validLength = i > 15 && i < 20;
        }else if(iin.substring(0,4) === "5019"){
            this.issuer = "Dankort";
            this.validation = "Luhn";
            validLength = i === 16;
        }else if(iin.substring(0,2) === "50" || (parseInt(iin.substring(0,2)) > 55 && parseInt(iin.substring(0,2)) < 70)){
            this.issuer = "Maestro";
            this.validation = "Luhn";
            validLength = i > 11 && i < 20;
        }else if((parseInt(iin.substring(0,2)) > 21 && parseInt(iin.substring(0,2)) < 28) || (parseInt(iin.substring(0,2)) > 50 && parseInt(iin.substring(0,2)) < 56)){
            this.issuer = "MasterCard";
            this.validation = "Luhn";
            validLength = i === 16;
        }else if(iin.substring(0,4) === "6334" || iin.substring(0,4) === "6767"){
            this.issuer = "Solo";
            this.validation = "Luhn";
            validLength = i === 16 || i === 18 || i === 19;
        }else if(iin.substring(0,4) === "4903" || iin.substring(0,4) === "4905" || iin.substring(0,4) === "4905" || iin.substring(0,4) === "4911" || iin.substring(0,4) === "4936" || iin === "564182" || iin === "633110" || iin.substring(0,4) === "6333" || iin.substring(0,4) === "6759"){
            this.issuer = "Switch";
            this.validation = "Luhn";
            validLength = i === 16 || i === 18 || i === 19;
        }else if(iin.substring(0,4) === "4026" || iin === "417500" || iin.substring(0,4) === "4405" || iin.substring(0,4) === "4508" || iin.substring(0,4) === "4844" || iin.substring(0,4) === "4913" || iin.substring(0,4) === "4917"){
            this.issuer = "Visa Electron";
            this.validation = "Luhn";
            validLength = i === 16;
        }else if(iin.substring(0,1) === "4"){
            this.issuer = "Visa";
            this.validation = "Luhn";
            validLength = i === 16 || i === 13;
        }else if(iin.substring(0,1) === "1"){
            this.issuer = "UATP";
            this.validation = "Luhn";
            validLength = i === 15;
        }else{
            this.issuer = "Not Known";
            this.validation = "Length";
            validLength = true;
        }
        if(!validLength){
            this.valid = false;
            this.error = "Invalid card length for "+this.issuer;
        }
    };
    // Constructor method, called at the bottom
    this.construct = function(cardNumber){
        // Iterate through the card number 
        cardNumber = String(cardNumber);
        var i = cardNumber.length;
        var realNumber = ""; //string containing card digits only
        var c = 0; //the real card number index
        for( y = 0; i > y; y++){
            char = cardNumber[y];
            if(!isNaN(char)){
                realNumber += char;
                // Get Industry
                if(c === 0){
                    this.MII = char;
                    switch(char){
                        case '0':
                            this.industry = "ISO/TC 68";
                            break;
                        case '1':
                        case '2':
                            this.industry = "Airline";
                            break;
                        case '3':
                            this.industry = "Travel/Entertainment";
                            break;
                        case '4':
                        case '5':
                            this.industry = "Banking/Financial";
                            break;
                        case '6':
                            this.industry = "Merch/Banking";
                            break;
                        case '7':
                            this.industry = "Petroleum";
                            break;
                        case '8':
                            this.industry = "Telecomm";
                            break;
                        case '9':
                            this.industry = "National Assignment";
                            break;
                    }
                }
                c++;
            }else{
                // check for invalid characters
                if(char !== " " && char !== "-"){
                    this.valid = false;
                    this.industry = "N/A";
                    this.error = "Invalid characters (Accepts numbers, spaces, and hyphens only.)";
                }

            }
        }
        // Validate length
        if (realNumber.length > 19 || realNumber.length<12){
            this.valid = false;
            this.industry = "N/A";
            this.error = "Invalid card length";
        }
        this.digits = realNumber;
        this.IIN = realNumber.substring(0, 6);
        this.accountNumber = realNumber.substring(6, (realNumber.length - 1));
        this.checksum = realNumber.substring((realNumber.length - 1), realNumber.length);
        this.getIssuer();
        if(this.validation === "Luhn"){
            if(this.luhnCheck() === false){
                this.valid = false;
                this.error = "Failed Luhn Algorithm Check";
            }
        }
    };
    
    
    // Initialize the class
    this.construct(ccn);
}

Initial URL
http://geneticcoder.blogspot.com/2014/11/advanced-client-side-credit-card.html

Initial Description
With publicly available information and a little math it is possible to not only validate a given card number, but to determine the financial institution that issued the card, the type of industry the issuer belongs to, the actual account number and more.

Fiddle: http://jsfiddle.net/qLq29frn/1/

Initial Title
Credit Card Parser & Validator

Initial Tags
javascript, js, validation

Initial Language
JavaScript