【问题标题】:Determine credit card type by number?通过数字确定信用卡类型?
【发布时间】:2010-11-21 10:43:17
【问题描述】:

是否可以仅根据信用卡号确定信用卡类型?

这是推荐的还是我们应该总是询问客户他们使用的信用卡类型?

我用谷歌搜索了一下,发现了这个算法:http://cuinl.tripod.com/Tips/o-1.htm,这可靠吗?

【问题讨论】:

标签: e-commerce credit-card


【解决方案1】:

是的,您提到的网站是正确的。许多网站,包括。我相信 Google Checkout 依赖于卡类型的自动检测。它很方便,使 UI 不那么混乱(少一个输入框)并节省时间。加油!

【讨论】:

  • +1 为卡片类型提供下拉框的唯一原因可能是作为错误检查的手段。
  • 下拉菜单或图标列表仍然有用 - 因为它允许您在输入之前查看公司接受的卡类型 - 例如,有些可能不接受 amex、diners、maestro 等。跨度>
【解决方案2】:

我很确定,至少对于 MasterCard、Visa、Discover 和 American Express 来说,这是准确的。我从未与其他任何人合作过。

查看此页面的最底部: http://www.merchantplus.com/resources/pages/credit-card-logos-and-test-numbers/

这也可能对你有用” http://www.beachnet.com/~hstiles/cardtype.html

这很有趣: http://en.wikipedia.org/wiki/Bank_card_number

【讨论】:

【解决方案3】:

我听说有一个很好的理由让他们选择(即使你能弄明白)。以便他们知道您接受的信用卡列表。

【讨论】:

  • 此外,能够检查是件好事。
  • 有趣的理由,但我不同意。您可以通过小图标或文字轻松向用户显示您接受哪些卡片,而无需让他们做任何额外的工作。
【解决方案4】:

这是我使用的适用于当前卡片范围的脚本。还对号码进行有效性检查。

/**
* 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;
}

【讨论】:

  • 是我的错...我只记得使用该功能并且由于客户抱怨而不得不更新一些异常(一些有效的 cc# 没有通过)-但这实际上是由于长度检查
  • 大多数卡片的长度为 16#(英国)Maestro 最长可达 19,因此长度检查成为 PITA。
【解决方案5】:

Wikipedia 包含大多数卡前缀的列表。您发布的链接中缺少一些卡片。您提供的链接似乎也是有效的。

询问卡类型的一个原因是为了进行额外验证,将用户提供的内容与号码进行比较。

【讨论】:

    【解决方案6】:

    作为消费者,我讨厌先选卡。我只想开始输入数字。

    Wroblewski 的 Web Form Design 第 153-154 页讨论了这个问题。它在“不必要的输入”一章的“删除问题”部分。给出的示例是 Paypal,它会在您输入号码时突出显示卡的类型。

    【讨论】:

    • 如果他们不接受美国运通会发生什么(经常发生)?你列出你不接受的卡吗?
    • Paypal 具有所有允许的卡类型的图形表示,但显示为幻影。当您键入数字时,匹配的卡片会亮到最大亮度。
    【解决方案7】:

    这个 Python 实现应该适用于 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
    

    【讨论】:

    • 信用卡并没有太糟糕,因为它们遵循一套规则;我们的 Maestro 卡会导致所有问题,因为它们使用与信用卡生产商相同的起始代码并且超过 16 位。
    【解决方案8】:

    如果您接受的所有信用卡都具有相同的属性,那么只需让用户输入卡号和其他属性(到期日期、CVV 等)。但是,某些卡类型需要输入不同的字段(例如,UK Maestro 卡的开始日期或发行编号)。在这些情况下,您要么必须拥有所有字段,从而使用户感到困惑,要么使用一些 Javascript 来隐藏/显示相关字段,再次使用户体验有点奇怪(字段消失/出现,因为他们输入信用卡号) .在这种情况下,我建议先询问卡片类型。

    【讨论】:

      【解决方案9】:

      这是一种自动确定卡片类型并在用户输入时将其显示给用户的快速简便方法。

      这意味着 a) 用户不必选择它并且 b) 他们不会浪费时间寻找不存在的下拉菜单。

      非常简单的 jQuery 版本,适用于 Amex、Visa 和 Mastercard。 如果您需要其他卡类型,您可以采取

       $('[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");
           });
      

      这是伴随这个的jQuery(ASP.NET MVC):

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

      我有一个 .unknown 的 CSS 规则来显示灰色文本。

      【讨论】:

        【解决方案10】:

        这是 codeproject 上的Complete C# or VB code for all kinds of CC related things

        • IsValidNumber
        • GetCardTypeFromNumber
        • GetCardTestNumber
        • 通过LuhnTest

        这篇文章已经发布了几年,没有负面的 cmets。

        【讨论】:

          【解决方案11】:

          这是第一篇文章中提到的相同算法的php版本

          <?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;
           }
           ?>
          

          【讨论】:

            【解决方案12】:

            您链接的代码有一个 不完整的 BIN/范围列表 用于 Discover,省略了 Diner's club(现在无论如何都属于 Discover),列出了不再存在并且应该折叠成其他类型的卡片类型(enRoute,Carte Blanche),并忽略了日益重要的 Maestro International 购物车类型。

            正如@Alex 所证实的,可以从 BIN 号确定卡片类型,许多公司都这样做,但始终如一且正确地这样做并非易事:卡片品牌不断变化,跟踪事情变得更加复杂尝试处理区域借记卡(爱尔兰的 Laser、欧洲的 Maestro 等)——我在任何地方都没有找到免费且维护(正确)的代码或算法。

            正如@MitMaro 指出的那样,Wikipedia contains a high-level list of card identifiersa more-specific list of BIN numbers and ranges,这是一个好的开始,正如 gbjbaanb 评论的那样,Barclays has a publically-published list(但由于某种原因,它似乎不包括 Discover - 大概他们没有' t 在 Discover 网络上处理?)

            虽然看起来微不足道,但正确的卡片识别算法/方法/功能需要维护,因此除非您的检测例程是非关键/信息性的(例如 @Simon_Weaver 的建议),或者您要放入为了使其保持最新状态,我建议您跳过自动检测。

            【讨论】:

              【解决方案13】:

              我个人对先选择卡类型没有问题。但在我看来,信用卡号码输入有两个方面存在问题。

              最糟糕的是无法在数字组之间输入空格。包括打印在物理卡上的空格将使用户更容易扫描数字以验证他们是否正确输入了信息。每次我遇到这种普遍存在的缺陷时,我都觉得自己被推回了一个石器时代,因为无法过滤用户输入以删除不必要的字符。

              第二个是在下电话订单时需要听供应商将卡号重复给您。信用卡接收人真正需要的只是一个 UI,让他们可以访问校验位方案,以验证 cc 号码是否有效。根据该算法,前 15 个(或许多)数字计算最后一个数字 - 几乎不可能“愚弄”。一个胖手指数字“通过”需要在 15 位数字中至少有两个相互抵消的错误。除非该算法存在被我怀疑的转置相邻数字(常见的输入错误)不成比例地愚弄的缺陷,否则我认为它比任何人工仔细检查都更可靠。

              【讨论】:

                【解决方案14】:

                Stripe 为卡片方案检测提供了这个出色的 javascript 库。让我添加一些代码 sn-ps 并向您展示如何使用它。

                首先将其包含到您的网页中

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

                其次使用cardType函数检测卡片方案。

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

                这里是更多示例和演示的参考链接。

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

                【讨论】:

                  【解决方案15】:

                  https://binlist.net/ 提供免费的 API。您只需输入卡号的前 6 位或 8 位数字 - 即发卡行识别号 (IIN),以前称为银行识别号 (BIN)。

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

                  (从更具体的问题交叉发布:How tell the difference between a Debit Card and a Credit Card

                  【讨论】:

                    猜你喜欢
                    • 2011-02-04
                    • 2017-02-23
                    • 1970-01-01
                    • 1970-01-01
                    • 2017-12-15
                    • 2015-02-08
                    • 2017-06-21
                    • 1970-01-01
                    • 2012-01-14
                    相关资源
                    最近更新 更多