Определить тип кредитной карты по номеру? - PullRequest
67 голосов
/ 20 августа 2009

Можно ли определить тип кредитной карты исключительно по номеру кредитной карты?

Это рекомендуется, или мы всегда должны спрашивать клиента о типе кредитной карты, которую они используют?

Я прогуглил об этом и нашел этот алгоритм: http://cuinl.tripod.com/Tips/o-1.htm, это надежно?

Ответы [ 15 ]

32 голосов
/ 20 августа 2009

Да, указанный вами сайт правильный. Много сайтов, в т.ч. Я считаю, что Google Checkout полагается на автоматическое определение типа карты. Это удобно, делает пользовательский интерфейс менее загроможденным (на одно поле ввода меньше) и экономит время. Вперед!

21 голосов
/ 20 августа 2009

Я слышал одну хорошую причину, чтобы заставить их выбирать (даже если вы можете понять это). Чтобы они знали список кредитных карт, которые вы принимаете.

11 голосов
/ 20 августа 2009

Как потребитель, я ненавижу сначала выбирать карту. Я хочу просто начать набирать номер.

Эта проблема обсуждается в Wroblewski Web Form Design на страницах 153-154. Это в разделе «Удаление вопросов» главы «Ненужные входы». В качестве примера приводится Paypal, в котором указывается тип карты, когда вы вводите свой номер.

7 голосов
/ 20 августа 2009

Я вполне уверен, что по крайней мере для 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

5 голосов
/ 23 ноября 2009

Вот Полный код C # или VB для всех видов связанных с CC вещей в проекте кода.

  • IsValidNumber
  • GetCardTypeFromNumber
  • GetCardTestNumber
  • PassesLuhnTest

Эта статья была опубликована в течение нескольких лет без негативных комментариев.

5 голосов
/ 20 августа 2009

вот скрипт, который я использую, который работает с текущими диапазонами карт. также делает проверку достоверности номера.

/**
* 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;
}
4 голосов
/ 20 августа 2009

Википедия содержит список большинства префиксов карт. Некоторые карты отсутствуют по указанной вами ссылке. Также представляется, что указанная вами ссылка действительна.

Одной из причин, по которой следует запросить тип карты, является дополнительная проверка, сравните данные, предоставленные пользователем, с номером.

3 голосов
/ 09 июля 2012

Код, который вы связали, имеет неполный список БИН / диапазон для Обнаружения, опускает клуб Diner's (который теперь все равно принадлежит Обнаружению), перечисляет типы карт, которые больше не существуют и должны быть объединены в другие типы enRoute, Carte Blanche) и игнорирует все более важный тип тележки Maestro International.

Как подтвердил @Alex, можно определить тип карты по номеру BIN, и многие компании делают это, но делать это последовательно и правильно не тривиально: бренды карт постоянно меняются, и отслеживать вещи становится все сложнее по мере того, как вы попробуйте обрабатывать региональные дебетовые карты (Laser в Ирландии, Maestro в Европе и т. д.) - я не нашел ни одного бесплатного и поддерживаемого (правильного) фрагмента кода или алгоритма для этого.

Как указала @MitMaro, Википедия содержит высокоуровневый список идентификаторов карт , а также более конкретный список номеров БИН и диапазонов , что является хорошим началом и, как прокомментировал gbjbaanb, Barclays имеет публично опубликованный список (но, похоже, по какой-то причине он не включает Discover - предположительно, они не обрабатываются в сети Discover?)

Как ни банально, правильный алгоритм / метод / функция идентификации карты требует работы для поддержания, поэтому, если ваша процедура обнаружения не является критической / информационной (например, предложение @ Simon_Weaver), ИЛИ вы собираетесь вставить чтобы поддерживать его в актуальном состоянии, я бы порекомендовал вам пропустить автоматическое обнаружение.

3 голосов
/ 14 октября 2011

Это php-версия того же алгоритма, упомянутого в 1-м посте

<?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;
 }
 ?>
2 голосов
/ 17 апреля 2015

Stripe предоставил эту фантастическую библиотеку javascript для определения схемы карты. Позвольте мне добавить несколько фрагментов кода и показать, как его использовать.

Сначала включите его на свою веб-страницу как

<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. Блог в полоску для jquery.payment.js
  2. Github хранилище
...