26

i have an array of card types that looks something like this

var cards = new Array();

cards [0] = {name: "VISA", length: "13,16", prefixes: "4", checkdigit: true};
cards [1] = {name: "VISA_DELTA/ELECTRON", length: "16", prefixes: "417500,4917,4913",     checkdigit: true};

however id like to be able to find the card type depending on the card number entered. e.g if they select their card type from a drop down list i.e visa, then the credit card number should start with 4 otherwise when they submit the form a message of some sort should be display saying this is (whatever card it is, please change card type). Any help would be appreciated.

the id for the card number text field is CardNumber. Im not sure what other info may be needed, i have a function called Validate which validates the rest of the form and a function call Calculate which does the luhn check.

Ghatzi
  • 567
  • 2
  • 12
  • 24

4 Answers4

72

I believe you are probably looking for something like this:

<script type="text/javascript">
function GetCardType(number)
{
    // visa
    var re = new RegExp("^4");
    if (number.match(re) != null)
        return "Visa";

    // Mastercard 
    // Updated for Mastercard 2017 BINs expansion
     if (/^(5[1-5][0-9]{14}|2(22[1-9][0-9]{12}|2[3-9][0-9]{13}|[3-6][0-9]{14}|7[0-1][0-9]{13}|720[0-9]{12}))$/.test(number)) 
        return "Mastercard";

    // AMEX
    re = new RegExp("^3[47]");
    if (number.match(re) != null)
        return "AMEX";

    // Discover
    re = new RegExp("^(6011|622(12[6-9]|1[3-9][0-9]|[2-8][0-9]{2}|9[0-1][0-9]|92[0-5]|64[4-9])|65)");
    if (number.match(re) != null)
        return "Discover";

    // Diners
    re = new RegExp("^36");
    if (number.match(re) != null)
        return "Diners";

    // Diners - Carte Blanche
    re = new RegExp("^30[0-5]");
    if (number.match(re) != null)
        return "Diners - Carte Blanche";

    // JCB
    re = new RegExp("^35(2[89]|[3-8][0-9])");
    if (number.match(re) != null)
        return "JCB";

    // Visa Electron
    re = new RegExp("^(4026|417500|4508|4844|491(3|7))");
    if (number.match(re) != null)
        return "Visa Electron";

    return "";
}
</script>

Originally posted here @ http://mel-green.com/2008/11/determine-credit-card-type-with-javascript/

AmyG
  • 321
  • 3
  • 5
Russ Clarke
  • 17,511
  • 4
  • 41
  • 45
  • 2
    While this may answer the question, link-only answers are discouraged. If the link goes dead (link rot), this answer would contain no information at all. Consider editing this answer to include relevant details from the link. – Chris Baker Sep 30 '14 at 16:01
  • 3
    Thanks - I did answer this over 3 years ago though. Thanks for the downvote. – Russ Clarke Oct 03 '14 at 10:32
  • I don't see how the age of the post is germane to my suggestion, but I would certainly retract the DV if the answer were improved. – Chris Baker Oct 03 '14 at 15:22
  • 3
    I don't want to get into a debate about this, as it's not helpful to the site nor a friendly environment for new members to experience, but the culture on S/O has changed a lot in the last couple of years; there was a time when it was generally considered Ok to post links, especially as it would feel like I was stealing if I simple just posted the content of someone else's article. I agree with the new way of doing things, but I find that retroactively downvoting something from years ago isn't helping. That's my opinion anyway. – Russ Clarke Oct 06 '14 at 11:57
  • I understand the culture change and agree that it would be unproductive to seek out every old answer and downvote it. I was being lazy and looking for a JS card type sniffing script instead of porting my PHP one, this came up after a Google search. That's why the age doesn't matter, even old questions get traffic. So I came here, hoping for a solution, and found that [My answer is in another castle](http://meta.stackexchange.com/questions/225370/your-answer-is-in-another-castle-when-is-an-answer-not-an-answer), so I left the initial comment. – Chris Baker Oct 06 '14 at 13:57
  • 8
    fwiw, you would have to put Visa electron first before visa, otherwise it would catch visa and exit. Same for Amex/Diners – Shanimal Apr 30 '15 at 22:46
  • 2
    Note for any others stumbling across this; Mastercard has since added a new BIN series (222100-272099), so the regex would have to be modified to take this into account. The answer this question duplicates explains that. – k3davis Dec 15 '16 at 17:20
  • Not working for JCB – Lakin Mohapatra Nov 22 '19 at 13:02
  • The link is broken now. – Sam Jun 12 '20 at 19:48
  • Here's a regular expression for unionpay: (^62)([^\s]{14,17}) – Wasabi Thumbs May 02 '21 at 15:27
3

Here's a jQuery plugin designed for exactly this:

http://jquerycreditcardvalidator.com/

See also this StackOverflow answer for an excellent discussion of how credit card numbers are related to card types:

https://stackoverflow.com/a/72801/12484

Community
  • 1
  • 1
Jon Schneider
  • 25,758
  • 23
  • 142
  • 170
2

The card companies have a fairly well-defined list of prefixes which are specific to the card type.

These prefixes range from a single digit (everything begining with '5' is Mastercard) to some strings up to six or seven digits long, for more obscure card types, and also for mainstream cards, but being able to identify not only the card type but also the issuing bank.

Here's one resource I found: http://www.beachnet.com/~hstiles/cardtype.html

You may also want to see Wikipedia: http://en.wikipedia.org/wiki/Credit_card_numbers

The down side is that while the prefixes that are in circulation now are pretty much fixed, there's always the likelyhood that they'll need to come up with more, so you would need to ensure that you keep any prefix list up-to-date, especially if you're using it to check the longer prefix ranges.

Spudley
  • 166,037
  • 39
  • 233
  • 307
  • 1
    +1 Every now and then they also drop ranges, or mark them as being ATM only/no ecomm/no CNP etc – Alex K. May 06 '11 at 12:32
1

The card prefix scheme is detailed in BIN (bank id number) lists and change regularly, I would advise against validating against the full 1st 6 digits of the PAN unless you plan regular updates and only perform a cursory check on the first couple of digits (your missing 48* for for visa/electon for example and visa length can span 16-19).

If your in the UK; http://www.barclaycard.co.uk/business/documents/pdfs/bin_rules.pdf

Alex K.
  • 171,639
  • 30
  • 264
  • 288