Determine credit card type by number?

后端 未结 15 1949
旧巷少年郎
旧巷少年郎 2020-11-30 19:44

Can credit card type be determined solely from the credit card number?

Is this recommended or should we always ask client for the type of credit card they\'re using?

相关标签:
15条回答
  • 2020-11-30 19:59

    This is the php version of same algorithm 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;
     }
     ?>
    
    0 讨论(0)
  • 2020-11-30 20:00

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

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

    0 讨论(0)
  • 2020-11-30 20:01

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

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

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

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

    0 讨论(0)
  • 2020-11-30 20:03

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

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

    Very simple jQuery version for Amex, Visa and Mastercard. if you need 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 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 have a css rule for .unknown to display grayed out text.

    0 讨论(0)
  • 2020-11-30 20:04

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

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

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

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

    0 讨论(0)
  • 2020-11-30 20:04

    here is the script that i use that works with current card ranges. also does a validity 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;
    }
    
    0 讨论(0)
提交回复
热议问题