Определить тип кредитной карты по номеру?

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

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

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

Ответ 1

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

Ответ 2

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

Ответ 3

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

Этот вопрос обсуждается в Wroblewski Веб-дизайн форм на стр. 153-154. Это в разделе "Удаление вопросов" главы "Ненужные входы". Приведенный пример - Paypal, в котором указывается тип карты, когда вы ввели свой номер.

Ответ 4

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

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

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

Ответ 7

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

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

Ответ 8

Это версия 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;
 }
 ?>

Ответ 9

Укомплектованный вами код имеет неполный список BIN/range для Discover, omits Diner club (который теперь принадлежит Discover), перечисляет типы карт, которые больше не существуют, и их нужно складывать в другие типы (enRoute, Carte Blanche), и игнорирует все более важный тип корзины Maestro International.

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

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

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

Ответ 10

Вот быстрый грязный способ автоматически определить тип карты и показать ее пользователю во время ввода.

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

Очень простая версия 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>

У меня есть правило css для .unknown для отображения текста с серым цветом.

Ответ 11

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

Вот ссылки для ссылок на примеры и демонстрации.

Ответ 12

Эта реализация в 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

Ответ 13

Если все принятые вами кредитные карты имеют одни и те же свойства, тогда просто введите пользователю номер карты и другие свойства (дата истечения срока действия, CVV и т.д.). Однако для некоторых типов карточек требуются разные поля для ввода (например, дата начала или номер выпуска для карт Великобритании Maestro). В этих случаях вы должны иметь все поля, тем самым запутывая пользователя или некоторый Javascript, чтобы скрыть/показать соответствующие поля, снова создавая у пользователя немного странные (поля исчезают/появляются, когда они вводят номер кредитной карты), В таких случаях я рекомендую сначала просить тип карты.

Ответ 14

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

Хуже всего неспособность вводить пробелы между группами чисел. В том числе пробелы, напечатанные на физических карточках, сделают цифры намного проще для сканирования пользователем, чтобы убедиться, что они правильно ввели информацию. Каждый раз, когда я сталкиваюсь с этим вездесущим недостатком, я чувствую, что меня продвигают назад в каменный век, когда пользовательский ввод не может быть отфильтрован для удаления ненужных символов.

Вторая необходимость при размещении телефонного заказа для прослушивания продавца повторить номер карты обратно к вам. Всем получателем кредитной карты действительно нужен интерфейс, который дает им доступ к схеме контрольных цифр, которая проверяет, что номер cc действителен. Согласно этому алгоритму первые 15 (или сколько угодно) цифр вычисляют последнюю цифру - и практически невозможно "обмануть". Для номера с полным пальцем для "прохода" требуется, по меньшей мере, две взаимно аннулирующие ошибки среди 15 цифр. Если алгоритм не страдает от недостатка в том, что он несправедливо обманут путем переноса соседних чисел (общая ошибка входа), которые я сомневаюсь, я исключаю, что он более надежен, чем любая двойная проверка человека.

Ответ 15

https://binlist.net/ предлагает бесплатный API. Вам нужно только ввести первые 6 или 8 цифр номера карты - то есть идентификационные номера эмитента (IIN), ранее известные как идентификационный номер банка (BIN).

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

(перекрестный ответ на более конкретный вопрос: как определить разницу между дебетовой и кредитной картой)