[ACCEPTED]-Determine credit card type by number?-credit-card

Accepted answer
Score: 32

Yes, the site you mentioned is correct. Many 5 sites, incl. Google Checkout I believe, rely 4 on automatic detection of the card type. It's 3 convenient, makes the UI less cluttered 2 (one less input box) and saves time. Go 1 ahead!

Score: 21

I have heard one good reason to make them 3 pick (even though you can figure it out). So 2 that they know the list of credit cards 1 you accept.

Score: 11

As a consumer, I hate choosing a card first. I 7 want to just start typing the number.

This 6 issue is discussed in Wroblewski's Web Form Design on pages 5 153-154. It's in the section "Removing 4 Questions" of the chapter "Unnecessary 3 Inputs." The example given is Paypal, which 2 highlights the type of card when you've 1 typed in your number.

Score: 7

I am pretty certain that at least for MasterCard, Visa, Discover, and 5 American Express that that is accurate. I 4 have never worked with any of the others.

See 3 the very bottom of this page: http://www.merchantplus.com/resources/pages/credit-card-logos-and-test-numbers/

Also this 2 might be useful to you" http://www.beachnet.com/~hstiles/cardtype.html

This is pretty 1 interesting to: http://en.wikipedia.org/wiki/Bank_card_number

Score: 5

here is the script that i use that works 2 with current card ranges. also does a validity 1 check on the number.

/**
* checks a given string for a valid credit card
* @returns:
*   -1  invalid
*       1   mastercard
*       2   visa
*       3   amex
*       4   diners club
*       5   discover
*       6   enRoute
*       7   jcb
*/
function checkCC(val) {
    String.prototype.startsWith = function (str) {
        return (this.match("^" + str) == str)
    }

    Array.prototype.has=function(v,i){
        for (var j=0;j<this.length;j++){
            if (this[j]==v) return (!i ? true : j);
        }
        return false;
    }

    // get rid of all non-numbers (space etc)
    val = val.replace(/[^0-9]/g, "");

    // now get digits
    var d = new Array();
    var a = 0;
    var len = 0;
    var cval = val;
    while (cval != 0) {
        d[a] = cval%10;
        cval -= d[a];
        cval /= 10;
        a++;
        len++;
    }

    if (len < 13)
        return -1;

    var cType = -1;

    // mastercard
    if (val.startsWith("5")) {
        if (len != 16)
            return -1;
        cType = 1;
    } else
    // visa
    if (val.startsWith("4")) {
        if (len != 16 && len != 13)
            return -1;
        cType = 2;
    } else
    // amex
    if (val.startsWith("34") || val.startsWith("37")) {
        if (len != 15)
            return -1;
        cType = 3;
    } else
    // diners
    if (val.startsWith("36") || val.startsWith("38") || val.startsWith("300") || val.startsWith("301") || val.startsWith("302") || val.startsWith("303") || val.startsWith("304") || val.startsWith("305")) {
        if (len != 14)
        return -1;
        cType = 4;
    } else
    // discover
    if (val.startsWith("6011")) {
        if (len != 15 && len != 16)
            return -1;
        cType = 5;
    } else
    // enRoute
    if (val.startsWith("2014") || val.startsWith("2149")) {
        if (len != 15 && len != 16)
            return -1;
        // any digit check
        return 6;
    } else
    // jcb
    if (val.startsWith("3")) {
        if (len != 16)
        return -1;
        cType = 7;
    } else
    // jcb
    if (val.startsWith("2131") || val.startsWith("1800")) {                                         

        if (len != 15)
        return -1;
        cType = 7;
    } else
    return - 1;
    // invalid cc company

    // lets do some calculation
    var sum = 0;
    var i;
    for (i = 1; i < len; i += 2) {
        var s = d[i] * 2;
        sum += s % 10;
        sum += (s - s%10) /10;
    }

    for (i = 0; i < len; i += 2)
        sum += d[i];

    // musst be %10
    if (sum%10 != 0)
        return - 1;

    return cType;
}
Score: 5

Here's Complete C# or VB code for all kinds of CC related things on codeproject.

  • IsValidNumber
  • GetCardTypeFromNumber
  • GetCardTestNumber
  • PassesLuhnTest

This article has 2 been up for a couple years with no negative 1 comments.

Score: 4

Wikipedia contains a list of most card prefixes. Some 5 cards are missing from the link you posted. It 4 also appears that the link you provided 3 is valid.

One reason to ask for the card 2 type is for extra validation, compare what 1 the user provided against the number.

Score: 4

This is the php version of same algorithm 1 mentioned in 1st post

<?php
function CreditCardType($CardNo)
{
/*
'*CARD TYPES            *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
*/    
//Just in case nothing is found
$CreditCardType = "Unknown";

//Remove all spaces and dashes from the passed string
$CardNo = str_replace("-", "",str_replace(" ", "",$CardNo));

//Check that the minimum length of the string isn't less
//than fourteen characters and -is- numeric
If(strlen($CardNo) < 14 || !is_numeric($CardNo))
    return false;

//Check the first two digits first
switch(substr($CardNo,0, 2))
{
    Case 34: Case 37:
        $CreditCardType = "American Express";
        break;
    Case 36:
        $CreditCardType = "Diners Club";
        break;
    Case 38:
        $CreditCardType = "Carte Blanche";
        break;
    Case 51: Case 52: Case 53: Case 54: Case 55:
        $CreditCardType = "Master Card";
        break;
}

//None of the above - so check the
if($CreditCardType == "Unknown")
{
    //first four digits collectively
    switch(substr($CardNo,0, 4))
    {
        Case 2014:Case 2149:
            $CreditCardType = "EnRoute";
            break;
        Case 2131:Case  1800:
            $CreditCardType = "JCB";
            break;
        Case 6011:
            $CreditCardType = "Discover";
            break;
    }
}

//None of the above - so check the
if($CreditCardType == "Unknown")
{
    //first three digits collectively
    if(substr($CardNo,0, 3) >= 300 && substr($CardNo,0, 3) <= 305)
    {
        $CreditCardType = "American Diners Club";
    }
}

//None of the above -
if($CreditCardType == "Unknown")
{
    //So simply check the first digit
    switch(substr($CardNo,0, 1))
    {
        Case 3:
            $CreditCardType = "JCB";
            break;
        Case 4:
            $CreditCardType = "Visa";
            break;
    }
}

return $CreditCardType;
 }
 ?>
Score: 3

The code you linked has an incomplete BIN/range list for Discover, omits 27 Diner's club (which now belongs to Discover 26 anyway), lists card types that no longer 25 exist and should be folded into other types 24 (enRoute, Carte Blanche), and ignores the 23 increasingly-important Maestro International 22 cart type.

As @Alex confirmed, it's possible 21 to determine the card type from the BIN 20 number, and numerous companies do it but 19 doing so consistently and correctly is not 18 trivial: card brands constantly change, and 17 keeping track of things becomes more complicated 16 as you try to handle regional debit cards 15 (Laser in Ireland, Maestro in Europe, etc) - I 14 have not found a free and maintained (correct) piece 13 of code or algorithm for this anywhere.

As 12 @MitMaro poined out, Wikipedia contains a high-level list of card identifiers, and also a more-specific list of BIN numbers and ranges, which 11 is a good start, and as gbjbaanb commented, Barclays has a publically-published list (but 10 it does not seem to include Discover for 9 some reason - presumably they don't process 8 on the Discover network?)

Trivial as it may 7 seem, a correct card-identification algorithm/method/function 6 takes work to maintain, so unless your detection 5 routine is non-critical/informational (eg 4 @Simon_Weaver's suggestion), OR you're going 3 to put in the work to keep it current, I 2 would recommend that you skip the automatic 1 detection.

Score: 3

Stripe has provided this fantastic javascript library 6 for card scheme detection. Let me add few 5 code snippets and show you how to use it.

Firstly 4 Include it to your web page as

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery.payment/1.2.3/jquery.payment.js " ></script>

Secondly use 3 the function cardType for detecting the 2 card scheme.

$(document).ready(function() {              
            var type = $.payment.cardType("4242 4242 4242 4242"); //test card number
            console.log(type);                                   
}); 

Here are the reference links 1 for more examples and demos.

  1. Stripe blog for jquery.payment.js
  2. Github repository
Score: 2

Here's a quick a dirty way to determine 10 the card type automatically and show it 9 to the user while they're typing.

That means 8 a) the user doesnt have to pick it and 7 b) they wont waste time looking for a dropdown 6 that doesnt exist.

Very simple jQuery version 5 for Amex, Visa and Mastercard. if you need 4 other card types you can take the

 $('[id$=CreditCardNumber]').assertOne().keyup(function(){

        // rules taken from http://en.wikipedia.org/wiki/Credit_card_number#cite_note-GenCardFeatures-0
        var value = $(this).val();

        $('#ccCardType').removeClass("unknown");
        if ((/^4/).test(value)) {
            $('#ccCardType').html("Visa");
            return;
        }
        if ((/^5[1-5]/).test(value)) {
           $('#ccCardType').html("Mastercard");
           return;
        }
        if ((/^3[47]/).test(value)) {
           $('#ccCardType').html("Mastercard");
           return;
        }
        $('#ccCardType').html("Enter card number above");
        $('#ccCardType').addClass("unknown");
     });

This is 3 the jQuery to accompany this (ASP.NET MVC):

  Card number: <%= Html.TextBox("PaymentDetails.CreditCardDetails.CreditCardNumber")%>
  Card Type: <span id="ccCardType" class="unknown">Enter card number above</span>

I 2 have a css rule for .unknown to display grayed out 1 text.

Score: 1

This implementation in Python should work 1 for AmEx, Discover, Master Card, Visa:

def cardType(number):
    number = str(number)
    cardtype = "Invalid"
    if len(number) == 15:
        if number[:2] == "34" or number[:2] == "37":
            cardtype = "American Express"
    if len(number) == 13:
        if number[:1] == "4":
            cardtype = "Visa"
    if len(number) == 16:
        if number[:4] == "6011":
            cardtype = "Discover"
        if int(number[:2]) >= 51 and int(number[:2]) <= 55:
            cardtype = "Master Card"
        if number[:1] == "4":
            cardtype = "Visa"
    return cardtype
Score: 1

If all the credit cards that you accept 13 have the same properties then just let the 12 user enter the card number and other properties 11 (expiry date, CVV, etc). However, some card 10 types require different fields to be entered 9 (e.g. start date or issue number for UK 8 Maestro cards). In those cases, you either 7 have to have all fields, thereby confusing 6 the user, or some Javascript to hide/show 5 the relevant fields, again making the user 4 experience a bit weird (fields disappearing/appearing, as 3 they enter the credit card number). In those 2 cases, I recommend asking for the card type 1 first.

Score: 1

Personally I have no problem with picking 29 the card type first. But there are two aspects 28 of credit card number entry that are problematic 27 in my view.

The worst is the inability to 26 enter spaces between groups of numbers. Including 25 the spaces printed on the physical cards 24 would make the digits vastly easier for 23 the user to scan to verify they've entered 22 the information correctly. Every time I 21 encounter this ubiquitous deficiency I feel 20 like I'm being propelled backwards into 19 a stone age when user input couldn't be 18 filtered to remove unnecessary characters.

The 17 second is the need when placing a phone 16 order to listen to the vendor repeat the 15 card number back to you. All the credit 14 card recipient actually needs is a UI that 13 gives them access to the check digit scheme 12 which verifies that a cc number is valid. According 11 to that algorithm the first 15 (or however 10 many) digits calculate the last digit - and 9 is virtually impossible to "fool." For a 8 fat fingered number to "pass" requires at 7 least two mutually canceling errors among 6 the 15 digits. Unless the algorithm suffers 5 from the defect of being dis-proportionally 4 fooled by transposing adjacent numbers (a 3 common entry error) which I doubt, I except 2 it is more reliable than any human double 1 check.

Score: 0

https://binlist.net/ offers a free API. You only need to enter 5 the first 6 or 8 digits of the card number 4 - i.e. the Issuer Identification Numbers 3 (IIN), previously known as Bank Identification 2 Number (BIN).

curl -H "Accept-Version: 3" "https://lookup.binlist.net/45717360"

(cross-posted from a more 1 specific question: How tell the difference between a Debit Card and a Credit Card )

More Related questions