it-swarm-vi.tech

Làm thế nào để bạn phát hiện loại thẻ tín dụng dựa trên số?

Tôi đang cố gắng tìm ra cách phát hiện loại thẻ tín dụng hoàn toàn dựa trên số của nó. Có ai biết một cách dứt khoát, đáng tin cậy để tìm thấy điều này?

481
Andrew Edvalson

Số thẻ tín dụng/thẻ ghi nợ được gọi là PAN hoặc Số tài khoản chính. Sáu chữ số đầu tiên của PAN được lấy từ IIN hoặc Số nhận dạng nhà phát hành, thuộc về ngân hàng phát hành (IIN trước đây được gọi là BIN - Số nhận dạng ngân hàng - vì vậy bạn có thể thấy các tài liệu tham khảo về thuật ngữ đó trong một số tài liệu). Sáu chữ số này tuân theo một tiêu chuẩn quốc tế, ISO/IEC 7812 , và có thể được sử dụng để xác định loại thẻ từ số.

Thật không may, cơ sở dữ liệu ISO/IEC 7812 thực tế không có sẵn công khai, tuy nhiên có các danh sách không chính thức, cả thương mại và miễn phí, bao gồm trên Wikipedia .

Dù sao, để phát hiện loại từ số, bạn có thể sử dụng biểu thức chính quy như các biểu thức bên dưới: Tín dụng cho các biểu thức gốc

Visa:^4[0-9]{6,}$ Số thẻ Visa bắt đầu bằng số 4.

MasterCard:^5[1-5][0-9]{5,}|222[1-9][0-9]{3,}|22[3-9][0-9]{4,}|2[3-6][0-9]{5,}|27[01][0-9]{4,}|2720[0-9]{3,}$ Trước năm 2016, số MasterCard bắt đầu bằng các số 51 đến 55, nhưng điều này sẽ chỉ phát hiện thẻ tín dụng MasterCard; có những thẻ khác được phát hành bằng hệ thống MasterCard không thuộc phạm vi IIN này. Trong năm 2016, họ sẽ thêm các số trong phạm vi (222100-272099).

American Express:^3[47][0-9]{5,}$ Số thẻ American Express bắt đầu bằng 34 hoặc 37.

Câu lạc bộ Diners:^3(?:0[0-5]|[68][0-9])[0-9]{4,}$ Số thẻ câu lạc bộ Diners bắt đầu bằng 300 đến 305, 36 hoặc 38. Có những thẻ Diners Club bắt đầu bằng 5 và có 16 chữ số. Đây là một liên doanh giữa Diners Club và MasterCard, và nên được xử lý như MasterCard.

Khám phá:^6(?:011|5[0-9]{2})[0-9]{3,}$ Khám phá số thẻ bắt đầu bằng 6011 hoặc 65.

JCB:^(?:2131|1800|35[0-9]{3})[0-9]{3,}$ Thẻ JCB bắt đầu bằng 2131, 1800 hoặc 35.

Thật không may, có một số loại thẻ được xử lý với hệ thống MasterCard không nằm trong phạm vi IIN của MasterCard (số bắt đầu từ 51 ... 55); trường hợp quan trọng nhất là thẻ Maestro, nhiều thẻ đã được phát hành từ các ngân hàng khác trong phạm vi IIN và do đó được đặt trên khắp không gian số. Do đó, có thể tốt nhất là giả định rằng bất kỳ thẻ nào không thuộc loại nào khác mà bạn chấp nhận phải là MasterCard.

Quan trọng: số thẻ có độ dài khác nhau; chẳng hạn, Visa trước đây đã phát hành thẻ với PAN gồm 13 chữ số và thẻ có PAN 16 chữ số. Tài liệu Visa Visa hiện chỉ ra rằng nó có thể phát hành hoặc có thể đã cấp các số có từ 12 đến 19 chữ số. Do đó, bạn không nên kiểm tra độ dài của số thẻ, ngoài việc xác minh rằng nó có ít nhất 7 chữ số (đối với IIN hoàn chỉnh cộng với một chữ số kiểm tra, phải khớp với giá trị được dự đoán bởi thuật toán Luhn ).

Một gợi ý nữa: trước khi xử lý PAN của chủ thẻ, loại bỏ bất kỳ ký tự khoảng trắng và dấu chấm câu nào khỏi đầu vào. Tại sao? Bởi vì nó thường là nhiều để nhập các chữ số theo nhóm dễ dàng hơn, tương tự như cách họ hiển thị ở mặt trước của thẻ tín dụng thực tế, tức là.

4444 4444 4444 4444

nhập chính xác dễ hơn nhiều

4444444444444444

Có rất nhiều lợi ích trong việc trừng phạt người dùng vì họ đã nhập các ký tự mà bạn không mong đợi ở đây.

Điều này cũng ngụ ý đảm bảo rằng các trường nhập của bạn có chỗ cho ít nhất 24 ký tự, nếu không, người dùng nhập vào khoảng trắng sẽ hết phòng. I hèd khuyên bạn nên làm cho trường đủ rộng để hiển thị 32 ký tự và cho phép tối đa 64 ký tự; cung cấp nhiều khoảng trống để mở rộng.

Đây là một hình ảnh cung cấp một cái nhìn sâu sắc hơn một chút:

CẬP NHẬT (2014): Phương thức tổng kiểm tra không còn là một cách hợp lệ để xác minh tính xác thực của thẻ như đã lưu ý trong các nhận xét về câu trả lời này.

CẬP NHẬT (2016): Mastercard là để triển khai các phạm vi BIN mới bắt đầu Thanh toán Ach .

Credit Card Verification

708
senfo

Trong javascript:

function detectCardType(number) {
    var re = {
        electron: /^(4026|417500|4405|4508|4844|4913|4917)\d+$/,
        maestro: /^(5018|5020|5038|5612|5893|6304|6759|6761|6762|6763|0604|6390)\d+$/,
        dankort: /^(5019)\d+$/,
        interpayment: /^(636)\d+$/,
        unionpay: /^(62|88)\d+$/,
        visa: /^4[0-9]{12}(?:[0-9]{3})?$/,
        mastercard: /^5[1-5][0-9]{14}$/,
        amex: /^3[47][0-9]{13}$/,
        diners: /^3(?:0[0-5]|[68][0-9])[0-9]{11}$/,
        discover: /^6(?:011|5[0-9]{2})[0-9]{12}$/,
        jcb: /^(?:2131|1800|35\d{3})\d{11}$/
    }

    for(var key in re) {
        if(re[key].test(number)) {
            return key
        }
    }
}

Bài kiểm tra đơn vị:

describe('CreditCard', function() {
    describe('#detectCardType', function() {

        var cards = {
            '8800000000000000': 'UNIONPAY',

            '4026000000000000': 'ELECTRON',
            '4175000000000000': 'ELECTRON',
            '4405000000000000': 'ELECTRON',
            '4508000000000000': 'ELECTRON',
            '4844000000000000': 'ELECTRON',
            '4913000000000000': 'ELECTRON',
            '4917000000000000': 'ELECTRON',

            '5019000000000000': 'DANKORT',

            '5018000000000000': 'MAESTRO',
            '5020000000000000': 'MAESTRO',
            '5038000000000000': 'MAESTRO',
            '5612000000000000': 'MAESTRO',
            '5893000000000000': 'MAESTRO',
            '6304000000000000': 'MAESTRO',
            '6759000000000000': 'MAESTRO',
            '6761000000000000': 'MAESTRO',
            '6762000000000000': 'MAESTRO',
            '6763000000000000': 'MAESTRO',
            '0604000000000000': 'MAESTRO',
            '6390000000000000': 'MAESTRO',

            '3528000000000000': 'JCB',
            '3589000000000000': 'JCB',
            '3529000000000000': 'JCB',

            '6360000000000000': 'INTERPAYMENT',

            '4916338506082832': 'VISA',
            '4556015886206505': 'VISA',
            '4539048040151731': 'VISA',
            '4024007198964305': 'VISA',
            '4716175187624512': 'VISA',

            '5280934283171080': 'MASTERCARD',
            '5456060454627409': 'MASTERCARD',
            '5331113404316994': 'MASTERCARD',
            '5259474113320034': 'MASTERCARD',
            '5442179619690834': 'MASTERCARD',

            '6011894492395579': 'DISCOVER',
            '6011388644154687': 'DISCOVER',
            '6011880085013612': 'DISCOVER',
            '6011652795433988': 'DISCOVER',
            '6011375973328347': 'DISCOVER',

            '345936346788903': 'AMEX',
            '377669501013152': 'AMEX',
            '373083634595479': 'AMEX',
            '370710819865268': 'AMEX',
            '371095063560404': 'AMEX'
        };

        Object.keys(cards).forEach(function(number) {
            it('should detect card ' + number + ' as ' + cards[number], function() {
                Basket.detectCardType(number).should.equal(cards[number]);
            });
        });
    });
});
68
Anatoliy

Cập nhật: ngày 15 tháng 6 năm 2016 (như một giải pháp tối ưu hiện tại)

Xin lưu ý rằng tôi thậm chí bỏ phiếu cho người được bình chọn hàng đầu, nhưng để làm rõ đây là các biểu thức chính thực sự hoạt động tôi đã thử nghiệm nó với hàng ngàn mã BIN thực. Điều quan trọng nhất là sử dụng chuỗi bắt đầu (^) nếu không nó sẽ cho kết quả sai trong thế giới thực!

JCB^(?:2131|1800|35)[0-9]{0,}$ Bắt đầu với: 2131, 1800, 35 (3528-3589)

American Express^3[47][0-9]{0,}$ Bắt đầu bằng: 34, 37

Câu lạc bộ thực khách^3(?:0[0-59]{1}|[689])[0-9]{0,}$ Bắt đầu với: 300-305, 309, 36, 38-39

Visa^4[0-9]{0,}$ Bắt đầu bằng: 4

MasterCard^(5[1-5]|222[1-9]|22[3-9]|2[3-6]|27[01]|2720)[0-9]{0,}$ Bắt đầu với: 2221-2720, 51-55

Maestro^(5[06789]|6)[0-9]{0,}$ Maestro luôn phát triển trong phạm vi: 60-69, bắt đầu bằng/không phải cái gì khác, nhưng bắt đầu 5 phải được mã hóa thành thẻ mastercard. Thẻ Maestro phải được phát hiện ở cuối mã vì một số thẻ khác có trong khoảng 60-69. Hãy nhìn vào mã.

Khám phá^(6011|65|64[4-9]|62212[6-9]|6221[3-9]|622[2-8]|6229[01]|62292[0-5])[0-9]{0,}$ Khám phá mã khá khó, bắt đầu bằng: 6011, 622126-622925, 644-649, 65

Trong javascript Tôi sử dụng chức năng này. Điều này là tốt khi bạn gán nó cho một sự kiện onkeyup và nó cho kết quả càng sớm càng tốt.

function cc_brand_id(cur_val) {
  // the regular expressions check for possible matches as you type, hence the OR operators based on the number of chars
  // regexp string length {0} provided for soonest detection of beginning of the card numbers this way it could be used for BIN CODE detection also

  //JCB
  jcb_regex = new RegExp('^(?:2131|1800|35)[0-9]{0,}$'); //2131, 1800, 35 (3528-3589)
  // American Express
  amex_regex = new RegExp('^3[47][0-9]{0,}$'); //34, 37
  // Diners Club
  diners_regex = new RegExp('^3(?:0[0-59]{1}|[689])[0-9]{0,}$'); //300-305, 309, 36, 38-39
  // Visa
  visa_regex = new RegExp('^4[0-9]{0,}$'); //4
  // MasterCard
  mastercard_regex = new RegExp('^(5[1-5]|222[1-9]|22[3-9]|2[3-6]|27[01]|2720)[0-9]{0,}$'); //2221-2720, 51-55
  maestro_regex = new RegExp('^(5[06789]|6)[0-9]{0,}$'); //always growing in the range: 60-69, started with / not something else, but starting 5 must be encoded as mastercard anyway
  //Discover
  discover_regex = new RegExp('^(6011|65|64[4-9]|62212[6-9]|6221[3-9]|622[2-8]|6229[01]|62292[0-5])[0-9]{0,}$');
  ////6011, 622126-622925, 644-649, 65


  // get rid of anything but numbers
  cur_val = cur_val.replace(/\D/g, '');

  // checks per each, as their could be multiple hits
  //fix: ordering matter in detection, otherwise can give false results in rare cases
  var sel_brand = "unknown";
  if (cur_val.match(jcb_regex)) {
    sel_brand = "jcb";
  } else if (cur_val.match(amex_regex)) {
    sel_brand = "amex";
  } else if (cur_val.match(diners_regex)) {
    sel_brand = "diners_club";
  } else if (cur_val.match(visa_regex)) {
    sel_brand = "visa";
  } else if (cur_val.match(mastercard_regex)) {
    sel_brand = "mastercard";
  } else if (cur_val.match(discover_regex)) {
    sel_brand = "discover";
  } else if (cur_val.match(maestro_regex)) {
    if (cur_val[0] == '5') { //started 5 must be mastercard
      sel_brand = "mastercard";
    } else {
      sel_brand = "maestro"; //maestro is all 60-69 which is not something else, thats why this condition in the end
    }
  }

  return sel_brand;
}

Tại đây bạn có thể chơi với nó:

http://jsfiddle.net/upN3L/69/

Đối với PHP sử dụng chức năng này, điều này cũng phát hiện một số thẻ VISA/MC phụ:

    /**
 * Obtain a brand constant from a PAN 
 *
 * @param type $pan               Credit card number
 * @param type $include_sub_types Include detection of sub visa brands
 * @return string
 */
public static function getCardBrand($pan, $include_sub_types = false)
{
    //maximum length is not fixed now, there are growing number of CCs has more numbers in length, limiting can give false negatives atm

    //these regexps accept not whole cc numbers too
    //visa        
    $visa_regex = "/^4[0-9]{0,}$/";
    $vpreca_regex = "/^428485[0-9]{0,}$/";
    $postepay_regex = "/^(402360|402361|403035|417631|529948){0,}$/";
    $cartasi_regex = "/^(432917|432930|453998)[0-9]{0,}$/";
    $entropay_regex = "/^(406742|410162|431380|459061|533844|522093)[0-9]{0,}$/";
    $o2money_regex = "/^(422793|475743)[0-9]{0,}$/";

    // MasterCard
    $mastercard_regex = "/^(5[1-5]|222[1-9]|22[3-9]|2[3-6]|27[01]|2720)[0-9]{0,}$/";
    $maestro_regex = "/^(5[06789]|6)[0-9]{0,}$/"; 
    $kukuruza_regex = "/^525477[0-9]{0,}$/";
    $yunacard_regex = "/^541275[0-9]{0,}$/";

    // American Express
    $amex_regex = "/^3[47][0-9]{0,}$/";

    // Diners Club
    $diners_regex = "/^3(?:0[0-59]{1}|[689])[0-9]{0,}$/";

    //Discover
    $discover_regex = "/^(6011|65|64[4-9]|62212[6-9]|6221[3-9]|622[2-8]|6229[01]|62292[0-5])[0-9]{0,}$/";

    //JCB
    $jcb_regex = "/^(?:2131|1800|35)[0-9]{0,}$/";

    //ordering matter in detection, otherwise can give false results in rare cases
    if (preg_match($jcb_regex, $pan)) {
        return "jcb";
    }

    if (preg_match($amex_regex, $pan)) {
        return "amex";
    }

    if (preg_match($diners_regex, $pan)) {
        return "diners_club";
    }

    //sub visa/mastercard cards
    if ($include_sub_types) {
        if (preg_match($vpreca_regex, $pan)) {
            return "v-preca";
        }
        if (preg_match($postepay_regex, $pan)) {
            return "postepay";
        }
        if (preg_match($cartasi_regex, $pan)) {
            return "cartasi";
        }
        if (preg_match($entropay_regex, $pan)) {
            return "entropay";
        }
        if (preg_match($o2money_regex, $pan)) {
            return "o2money";
        }
        if (preg_match($kukuruza_regex, $pan)) {
            return "kukuruza";
        }
        if (preg_match($yunacard_regex, $pan)) {
            return "yunacard";
        }
    }

    if (preg_match($visa_regex, $pan)) {
        return "visa";
    }

    if (preg_match($mastercard_regex, $pan)) {
        return "mastercard";
    }

    if (preg_match($discover_regex, $pan)) {
        return "discover";
    }

    if (preg_match($maestro_regex, $pan)) {
        if ($pan[0] == '5') {//started 5 must be mastercard
            return "mastercard";
        }
            return "maestro"; //maestro is all 60-69 which is not something else, thats why this condition in the end

    }

    return "unknown"; //unknown for this system
}
28
Janos Szabo
  public string GetCreditCardType(string CreditCardNumber)
    {
        Regex regVisa = new Regex("^4[0-9]{12}(?:[0-9]{3})?$");
        Regex regMaster = new Regex("^5[1-5][0-9]{14}$");
        Regex regExpress = new Regex("^3[47][0-9]{13}$");
        Regex regDiners = new Regex("^3(?:0[0-5]|[68][0-9])[0-9]{11}$");
        Regex regDiscover = new Regex("^6(?:011|5[0-9]{2})[0-9]{12}$");
        Regex regJCB= new Regex("^(?:2131|1800|35\\d{3})\\d{11}$");


        if(regVisa.IsMatch(CreditCardNumber))
            return "VISA";
       else if (regMaster.IsMatch(CreditCardNumber))
            return "MASTER";
      else  if (regExpress.IsMatch(CreditCardNumber))
            return "AEXPRESS";
       else if (regDiners.IsMatch(CreditCardNumber))
            return "DINERS";
       else if (regDiscover.IsMatch(CreditCardNumber))
            return "DISCOVERS";
       else   if (regJCB.IsMatch(CreditCardNumber))
            return "JCB";
       else
        return "invalid";
    }

Đây là chức năng kiểm tra loại thẻ tín dụng bằng Regex, c #

19
Usman Younas

Kiểm tra này:

http://www.breakingpar.com/bkp/home.nsf/0/87256B280015193F87256CC70060A01B

function isValidCreditCard(type, ccnum) {
/* Visa: length 16, prefix 4, dashes optional.
Mastercard: length 16, prefix 51-55, dashes optional.
Discover: length 16, prefix 6011, dashes optional.
American Express: length 15, prefix 34 or 37.
Diners: length 14, prefix 30, 36, or 38. */

  var re = new Regex({ "visa": "/^4\d{3}-?\d{4}-?\d{4}-?\d",
                       "mc": "/^5[1-5]\d{2}-?\d{4}-?\d{4}-?\d{4}$/",
                       "disc": "/^6011-?\d{4}-?\d{4}-?\d{4}$/",
                       "amex": "/^3[47]\d{13}$/",
                       "diners": "/^3[068]\d{12}$/"}[type.toLowerCase()])

   if (!re.test(ccnum)) return false;
   // Remove all dashes for the checksum checks to eliminate negative numbers
   ccnum = ccnum.split("-").join("");
   // Checksum ("Mod 10")
   // Add even digits in even length strings or odd digits in odd length strings.
   var checksum = 0;
   for (var i=(2-(ccnum.length % 2)); i<=ccnum.length; i+=2) {
      checksum += parseInt(ccnum.charAt(i-1));
   }
   // Analyze odd digits in even length strings or even digits in odd length strings.
   for (var i=(ccnum.length % 2) + 1; i<ccnum.length; i+=2) {
      var digit = parseInt(ccnum.charAt(i-1)) * 2;
      if (digit < 10) { checksum += digit; } else { checksum += (digit-9); }
   }
   if ((checksum % 10) == 0) return true; else return false;
}
18
Rashy

Đây là Mã C # hoặc VB hoàn chỉnh cho tất cả các loại liên quan đến CC trên bảng mã.

  • Số điện thoại
  • GetCardTypeFromNumber
  • GetCardTestNumber
  • PassLuhnTest

Bài viết này đã được một vài năm không có bình luận tiêu cực.

12
Simon_Weaver

gần đây tôi cần chức năng như vậy, tôi đã chuyển Trình xác thực thẻ tín dụng Zend Framework sang Ruby . Ruby gem: https://github.com/Fivell/credit_card_validations zend framework: https: // github.com/zendframework/zf2/blob/master/lvern/Zend/Validator/CreditCard.php

Cả hai đều sử dụng phạm vi INN để phát hiện loại. Tại đây bạn có thể đọc về INN

Theo đó, bạn có thể phát hiện thẻ tín dụng thay thế (không có biểu thức chính quy, nhưng khai báo một số quy tắc về tiền tố và độ dài có thể)

Vì vậy, chúng tôi có các quy tắc tiếp theo cho hầu hết các thẻ được sử dụng

########  most used brands #########

    visa: [
        {length: [13, 16], prefixes: ['4']}
    ],
    mastercard: [
        {length: [16], prefixes: ['51', '52', '53', '54', '55']}
    ],

    amex: [
        {length: [15], prefixes: ['34', '37']}
    ],
    ######## other brands ########
    diners: [
        {length: [14], prefixes: ['300', '301', '302', '303', '304', '305', '36', '38']},
    ],

    #There are Diners Club (North America) cards that begin with 5. These are a joint venture between Diners Club and MasterCard, and are processed like a MasterCard
    # will be removed in next major version

    diners_us: [
        {length: [16], prefixes: ['54', '55']}
    ],

    discover: [
        {length: [16], prefixes: ['6011', '644', '645', '646', '647', '648',
                                  '649', '65']}
    ],

    jcb: [
        {length: [16], prefixes: ['3528', '3529', '353', '354', '355', '356', '357', '358', '1800', '2131']}
    ],


    laser: [
        {length: [16, 17, 18, 19], prefixes: ['6304', '6706', '6771']}
    ],

    solo: [
        {length: [16, 18, 19], prefixes: ['6334', '6767']}
    ],

    switch: [
        {length: [16, 18, 19], prefixes: ['633110', '633312', '633304', '633303', '633301', '633300']}

    ],

    maestro: [
        {length: [12, 13, 14, 15, 16, 17, 18, 19], prefixes: ['5010', '5011', '5012', '5013', '5014', '5015', '5016', '5017', '5018',
                                                              '502', '503', '504', '505', '506', '507', '508',
                                                              '6012', '6013', '6014', '6015', '6016', '6017', '6018', '6019',
                                                              '602', '603', '604', '605', '6060',
                                                              '677', '675', '674', '673', '672', '671', '670',
                                                              '6760', '6761', '6762', '6763', '6764', '6765', '6766', '6768', '6769']}
    ],

    # Luhn validation are skipped for union pay cards because they have unknown generation algoritm
    unionpay: [
        {length: [16, 17, 18, 19], prefixes: ['622', '624', '625', '626', '628'], skip_luhn: true}
    ],

    dankrot: [
        {length: [16], prefixes: ['5019']}
    ],

    rupay: [
        {length: [16], prefixes: ['6061', '6062', '6063', '6064', '6065', '6066', '6067', '6068', '6069', '607', '608'], skip_luhn: true}
    ]

}

Sau đó, bằng cách tìm kiếm tiền tố và so sánh độ dài, bạn có thể phát hiện thương hiệu thẻ tín dụng. Cũng đừng quên luhn algoritm (nó được giải thích ở đây http://en.wikipedia.org/wiki/Luhn ).

12
Fivell

Câu trả lời của Anatoliy trong PHP:

 public static function detectCardType($num)
 {
    $re = array(
        "visa"       => "/^4[0-9]{12}(?:[0-9]{3})?$/",
        "mastercard" => "/^5[1-5][0-9]{14}$/",
        "amex"       => "/^3[47][0-9]{13}$/",
        "discover"   => "/^6(?:011|5[0-9]{2})[0-9]{12}$/",
    );

    if (preg_match($re['visa'],$num))
    {
        return 'visa';
    }
    else if (preg_match($re['mastercard'],$num))
    {
        return 'mastercard';
    }
    else if (preg_match($re['amex'],$num))
    {
        return 'amex';
    }
    else if (preg_match($re['discover'],$num))
    {
        return 'discover';
    }
    else
    {
        return false;
    }
 }
7
angelcool.net

Phiên bản javascript nhỏ gọn

    var getCardType = function (number) {
        var cards = {
            visa: /^4[0-9]{12}(?:[0-9]{3})?$/,
            mastercard: /^5[1-5][0-9]{14}$/,
            amex: /^3[47][0-9]{13}$/,
            diners: /^3(?:0[0-5]|[68][0-9])[0-9]{11}$/,
            discover: /^6(?:011|5[0-9]{2})[0-9]{12}$/,
            jcb: /^(?:2131|1800|35\d{3})\d{11}$/
        };
        for (var card in cards) {
            if (cards[card].test(number)) {
                return card;
            }
        }
    };
7
Nick

Đây là một hàm lớp php trả về CCtype bởi CCnumber.
Mã này không xác thực thẻ hoặc không chạy thuật toán Luhn chỉ thử tìm loại thẻ tín dụng dựa trên bảng trong trang này . về cơ bản sử dụng chiều dài CCnumber và tiền tố CCcard để xác định loại CCcard.

    <?php class CreditcardType
    {
   public static $creditcardTypes = array(
            array('Name'=>'American Express','cardLength'=>array(15),'cardPrefix'=>array('34', '37'))
            ,array('Name'=>'Maestro','cardLength'=>array(12, 13, 14, 15, 16, 17, 18, 19),'cardPrefix'=>array('5018', '5020', '5038', '6304', '6759', '6761', '6763'))
            ,array('Name'=>'Mastercard','cardLength'=>array(16),'cardPrefix'=>array('51', '52', '53', '54', '55'))
            ,array('Name'=>'Visa','cardLength'=>array(13,16),'cardPrefix'=>array('4'))
            ,array('Name'=>'JCB','cardLength'=>array(16),'cardPrefix'=>array('3528', '3529', '353', '354', '355', '356', '357', '358'))
            ,array('Name'=>'Discover','cardLength'=>array(16),'cardPrefix'=>array('6011', '622126', '622127', '622128', '622129', '62213',
                                        '62214', '62215', '62216', '62217', '62218', '62219',
                                        '6222', '6223', '6224', '6225', '6226', '6227', '6228',
                                        '62290', '62291', '622920', '622921', '622922', '622923',
                                        '622924', '622925', '644', '645', '646', '647', '648',
                                        '649', '65'))
            ,array('Name'=>'Solo','cardLength'=>array(16, 18, 19),'cardPrefix'=>array('6334', '6767'))
            ,array('Name'=>'Unionpay','cardLength'=>array(16, 17, 18, 19),'cardPrefix'=>array('622126', '622127', '622128', '622129', '62213', '62214',
                                        '62215', '62216', '62217', '62218', '62219', '6222', '6223',
                                        '6224', '6225', '6226', '6227', '6228', '62290', '62291',
                                        '622920', '622921', '622922', '622923', '622924', '622925'))
            ,array('Name'=>'Diners Club','cardLength'=>array(14),'cardPrefix'=>array('300', '301', '302', '303', '304', '305', '36'))
            ,array('Name'=>'Diners Club US','cardLength'=>array(16),'cardPrefix'=>array('54', '55'))
            ,array('Name'=>'Diners Club Carte Blanche','cardLength'=>array(14),'cardPrefix'=>array('300','305'))
            ,array('Name'=>'Laser','cardLength'=>array(16, 17, 18, 19),'cardPrefix'=>array('6304', '6706', '6771', '6709'))
    );     
        private function __construct() {}    
        public static function getType($CCNumber)
        {
            $CCNumber= trim($CCNumber);
            $type='Unknown';
            foreach (CreditcardType::$creditcardTypes as $card){
                if (! in_array(strlen($CCNumber),$card['cardLength'])) {
                    continue;
                }
                $prefixes = '/^('.implode('|',$card['cardPrefix']).')/';            
                if(preg_match($prefixes,$CCNumber) == 1 ){
                    $type= $card['Name'];
                    break;
                }
            }
            return $type;
        }
    } ?>
6
ismail

Các số đầu tiên của thẻ tín dụng có thể được sử dụng để ước tính nhà cung cấp:

  • Visa: 49,44 hoặc 47
  • Visa điện tử: 42, 45, 48, 49
  • Thẻ tín dụng: 51
  • Amex: 34
  • Thực khách: 30, 36, 38
  • JCB: 35
5
Shoban

Trong Nhận dạng phạm vi thẻ (CRR), một nhược điểm với các thuật toán sử dụng một loạt biểu thức chính quy hoặc các phạm vi được mã hóa cứng khác, đó là các BIN/IIN thay đổi theo thời gian theo kinh nghiệm của tôi. Việc hợp tác xây dựng thương hiệu thẻ là một sự phức tạp đang diễn ra. Người mua/người bán thẻ khác nhau có thể cần bạn đối xử với cùng một loại thẻ khác nhau, tùy thuộc vào ví dụ: định vị địa lý. 

Ngoài ra, trong vài năm qua với ví dụ: Thẻ UnionPay trong lưu thông rộng hơn, các mô hình hiện tại không đối phó với các phạm vi mới đôi khi xen kẽ với các phạm vi rộng hơn mà chúng thay thế.
Biết địa lý mà hệ thống của bạn cần bảo vệ có thể giúp ích, vì một số phạm vi bị hạn chế sử dụng ở các quốc gia cụ thể. Ví dụ: phạm vi 62 bao gồm một số phạm vi phụ AAA ở Hoa Kỳ, nhưng nếu cơ sở thương mại của bạn ở bên ngoài Hoa Kỳ, bạn có thể coi tất cả 62 là UnionPay.
Bạn cũng có thể được yêu cầu đối xử với một thẻ khác nhau dựa trên vị trí thương gia. Ví dụ. để coi một số thẻ của Vương quốc Anh là ghi nợ trong nước, nhưng là tín dụng quốc tế. 

Có những bộ quy tắc rất hữu ích được duy trì bởi một Ngân hàng Mua lại lớn. Ví dụ. https://www.barclaycard.co.uk/business/files/BIN-Rules-EIRE.pdfhttps://www.barclaycard.co.uk/business/files/BIN-Rules- Anh.pdf . (Liên kết hợp lệ kể từ tháng 6 năm 2017, nhờ người dùng đã cung cấp liên kết đến tài liệu tham khảo được cập nhật.) Nhưng hãy lưu ý rằng, trong khi các quy tắc CRR này có thể đại diện cho vũ trụ Phát hành Thẻ khi áp dụng cho các thương nhân có được bởi thực thể đó, nó không bao gồm ví dụ phạm vi được xác định là CUP/UPI.

Những nhận xét này áp dụng cho các tình huống sọc từ (MagStripe) hoặc PKE (Pan Key Entry). Tình hình lại khác trong thế giới ICC/EMV.

Cập nhật: Các câu trả lời khác trên trang này (và cả trang WikiPedia được liên kết) có JCB luôn luôn dài 16. Tuy nhiên, trong công ty của tôi, chúng tôi có một nhóm kỹ sư chuyên dụng chứng nhận các thiết bị và phần mềm POS của chúng tôi trên nhiều ngân hàng và khu vực địa lý. Gói Chứng nhận gần đây nhất của nhóm này có từ JCB, đã có một trường hợp vượt qua cho một PAN dài 19.

5
MikeRoger

Đừng cố gắng phát hiện loại thẻ tín dụng như là một phần của việc xử lý thanh toán. Bạn đang có nguy cơ từ chối các giao dịch hợp lệ.

Nếu bạn cần cung cấp thông tin cho bộ xử lý thanh toán của mình (ví dụ: đối tượng thẻ tín dụng Paypal yêu cầu đặt tên loại loại thẻ ), sau đó đoán từ thông tin ít nhất có sẵn, ví dụ:.

$credit_card['pan'] = preg_replace('/[^0-9]/', '', $credit_card['pan']);
$inn = (int) mb_substr($credit_card['pan'], 0, 2);

// @see http://en.wikipedia.org/wiki/List_of_Bank_Identification_Numbers#Overview
if ($inn >= 40 && $inn <= 49) {
    $type = 'visa';
} else if ($inn >= 51 && $inn <= 55) {
    $type = 'mastercard';
} else if ($inn >= 60 && $inn <= 65) {
    $type = 'discover';
} else if ($inn >= 34 && $inn <= 37) {
    $type = 'amex';
} else {
    throw new \UnexpectedValueException('Unsupported card type.');
}

Việc triển khai này (chỉ sử dụng hai chữ số đầu tiên) là đủ để xác định tất cả các chương trình thẻ chính (và trong trường hợp của Paypal là tất cả các chương trình thẻ được hỗ trợ). Trong thực tế, bạn có thể muốn bỏ qua ngoại lệ hoàn toàn và mặc định cho loại thẻ phổ biến nhất. Hãy để cổng thanh toán/bộ xử lý cho bạn biết nếu có lỗi xác thực đáp ứng yêu cầu của bạn.

Thực tế là cổng thanh toán của bạn không quan tâm đến giá trị bạn cung cấp .

5
Gajus

Swift 2.1 Phiên bản câu trả lời của Usman Y . Sử dụng câu lệnh in để xác minh để gọi theo một số giá trị chuỗi

print(self.validateCardType(self.creditCardField.text!))

func validateCardType(testCard: String) -> String {

    let regVisa = "^4[0-9]{12}(?:[0-9]{3})?$"
    let regMaster = "^5[1-5][0-9]{14}$"
    let regExpress = "^3[47][0-9]{13}$"
    let regDiners = "^3(?:0[0-5]|[68][0-9])[0-9]{11}$"
    let regDiscover = "^6(?:011|5[0-9]{2})[0-9]{12}$"
    let regJCB = "^(?:2131|1800|35\\d{3})\\d{11}$"


    let regVisaTest = NSPredicate(format: "SELF MATCHES %@", regVisa)
    let regMasterTest = NSPredicate(format: "SELF MATCHES %@", regMaster)
    let regExpressTest = NSPredicate(format: "SELF MATCHES %@", regExpress)
    let regDinersTest = NSPredicate(format: "SELF MATCHES %@", regDiners)
    let regDiscoverTest = NSPredicate(format: "SELF MATCHES %@", regDiscover)
    let regJCBTest = NSPredicate(format: "SELF MATCHES %@", regJCB)


    if regVisaTest.evaluateWithObject(testCard){
        return "Visa"
    }
    else if regMasterTest.evaluateWithObject(testCard){
        return "MasterCard"
    }

    else if regExpressTest.evaluateWithObject(testCard){
        return "American Express"
    }

    else if regDinersTest.evaluateWithObject(testCard){
        return "Diners Club"
    }

    else if regDiscoverTest.evaluateWithObject(testCard){
        return "Discover"
    }

    else if regJCBTest.evaluateWithObject(testCard){
        return "JCB"
    }

    return ""

}
3
Daisy R.

Giải pháp của tôi với jQuery:

function detectCreditCardType() {
    var type = new Array;
    type[1] = '^4[0-9]{12}(?:[0-9]{3})?$';      // visa
    type[2] = '^5[1-5][0-9]{14}$';              // mastercard
    type[3] = '^6(?:011|5[0-9]{2})[0-9]{12}$';  // discover
    type[4] = '^3[47][0-9]{13}$';               // amex

    var ccnum = $('.creditcard').val().replace(/[^\d.]/g, '');
    var returntype = 0;

    $.each(type, function(idx, re) {
        var regex = new RegExp(re);
        if(regex.test(ccnum) && idx>0) {
            returntype = idx;
        }
    });

    return returntype;
}

Trong trường hợp 0 ​​được trả về, loại thẻ tín dụng không bị phát hiện.

Lớp "thẻ tín dụng" nên được thêm vào trường nhập thẻ tín dụng.

3
ZurabWeb

Stripe đã cung cấp thư viện javascript tuyệt vời này để phát hiện lược đồ thẻ. Hãy để tôi thêm một vài đoạn mã và chỉ cho bạn cách sử dụng nó. 

Trước hết, hãy đưa nó vào trang web của bạn dưới dạng

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

Thứ hai sử dụng chức năng cardType để phát hiện sơ đồ thẻ.

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

Dưới đây là các liên kết tham khảo cho nhiều ví dụ và bản demo.

  1. Blog sọc cho jquery.payment.js
  2. Kho lưu trữ Github
2
Naina

Trong Swift, bạn có thể tạo một enum để phát hiện loại thẻ tín dụng.

enum CreditCardType: Int { // Enum which encapsulates different card types and method to find the type of card.

case Visa
case Master
case Amex
case Discover

func validationRegex() -> String {
    var regex = ""
    switch self {
    case .Visa:
        regex = "^4[0-9]{6,}$"

    case .Master:
        regex = "^5[1-5][0-9]{5,}$"

    case .Amex:
        regex = "^3[47][0-9]{13}$"

    case .Discover:
        regex = "^6(?:011|5[0-9]{2})[0-9]{12}$"
    }

    return regex
}

func validate(cardNumber: String) -> Bool {
    let predicate = NSPredicate(format: "SELF MATCHES %@", validationRegex())
    return predicate.evaluateWithObject(cardNumber)
}

// Method returns the credit card type for given card number
static func cardTypeForCreditCardNumber(cardNumber: String) -> CreditCardType?  {
    var creditCardType: CreditCardType?

    var index = 0
    while let cardType = CreditCardType(rawValue: index) {
        if cardType.validate(cardNumber) {
            creditCardType = cardType
            break
        } else {
            index++
        }
    }
    return creditCardType
  }
}

Gọi phương thức CreditCardType.cardTypeForCreditCardNumber ("# số thẻ") trả về giá trị enum của CreditCardType.

2
Vidyalaxmi

Tôi đã tìm kiếm xung quanh khá nhiều để định dạng thẻ tín dụng và định dạng số điện thoại. Tìm thấy rất nhiều lời khuyên hay nhưng không có gì thực sự phù hợp với mong muốn chính xác của tôi nên tôi đã tạo đoạn mã này . Bạn sử dụng nó như thế này:

var sf = smartForm.formatCC(myInputString);
var cardType = sf.cardType;
2
ShadeTreeDeveloper

Chỉ cần một thìa nhỏ cho ăn:

$("#CreditCardNumber").focusout(function () {


        var regVisa = /^4[0-9]{12}(?:[0-9]{3})?$/;
        var regMasterCard = /^5[1-5][0-9]{14}$/;
        var regAmex = /^3[47][0-9]{13}$/;
        var regDiscover = /^6(?:011|5[0-9]{2})[0-9]{12}$/;

        if (regVisa.test($(this).val())) {
            $("#CCImage").html("<img height='40px' src='@Url.Content("~/images/visa.png")'>");          

        }

        else if (regMasterCard.test($(this).val())) {
        $("#CCImage").html("<img height='40px' src='@Url.Content("~/images/mastercard.png")'>");

        }

        else if (regAmex.test($(this).val())) {

           $("#CCImage").html("<img height='40px' src='@Url.Content("~/images/amex.png")'>");

        }
         else if (regDiscover.test($(this).val())) {

           $("#CCImage").html("<img height='40px' src='@Url.Content("~/images/discover.png")'>");

        }
        else {
        $("#CCImage").html("NA");

        }

    });
1
Pinch

Dưới đây là ví dụ về một số hàm boolean được viết bằng Python trả về True nếu thẻ được phát hiện theo tên hàm. 

def is_american_express(cc_number):
    """Checks if the card is an american express. If us billing address country code, & is_amex, use vpos
    https://en.wikipedia.org/wiki/Bank_card_number#cite_note-GenCardFeatures-3
    :param cc_number: unicode card number
    """
    return bool(re.match(r'^3[47][0-9]{13}$', cc_number))


def is_visa(cc_number):
    """Checks if the card is a visa, begins with 4 and 12 or 15 additional digits.
    :param cc_number: unicode card number
    """

    # Standard Visa is 13 or 16, debit can be 19
    if bool(re.match(r'^4', cc_number)) and len(cc_number) in [13, 16, 19]:
        return True

    return False


def is_mastercard(cc_number):
    """Checks if the card is a mastercard. Begins with 51-55 or 2221-2720 and 16 in length.
    :param cc_number: unicode card number
    """
    if len(cc_number) == 16 and cc_number.isdigit():  # Check digit, before cast to int
        return bool(re.match(r'^5[1-5]', cc_number)) or int(cc_number[:4]) in range(2221, 2721)
    return False


def is_discover(cc_number):
    """Checks if the card is discover, re would be too hard to maintain. Not a supported card.
    :param cc_number: unicode card number
    """
    if len(cc_number) == 16:
        try:
            # return bool(cc_number[:4] == '6011' or cc_number[:2] == '65' or cc_number[:6] in range(622126, 622926))
            return bool(cc_number[:4] == '6011' or cc_number[:2] == '65' or 622126 <= int(cc_number[:6]) <= 622925)
        except ValueError:
            return False
    return False


def is_jcb(cc_number):
    """Checks if the card is a jcb. Not a supported card.
    :param cc_number: unicode card number
    """
    # return bool(re.match(r'^(?:2131|1800|35\d{3})\d{11}$', cc_number))  # wikipedia
    return bool(re.match(r'^35(2[89]|[3-8][0-9])[0-9]{12}$', cc_number))  # PawelDecowski


def is_diners_club(cc_number):
    """Checks if the card is a diners club. Not a supported card.
    :param cc_number: unicode card number
    """
    return bool(re.match(r'^3(?:0[0-6]|[68][0-9])[0-9]{11}$', cc_number))  # 0-5 = carte blance, 6 = international


def is_laser(cc_number):
    """Checks if the card is laser. Not a supported card.
    :param cc_number: unicode card number
    """
    return bool(re.match(r'^(6304|670[69]|6771)', cc_number))


def is_maestro(cc_number):
    """Checks if the card is maestro. Not a supported card.
    :param cc_number: unicode card number
    """
    possible_lengths = [12, 13, 14, 15, 16, 17, 18, 19]
    return bool(re.match(r'^(50|5[6-9]|6[0-9])', cc_number)) and len(cc_number) in possible_lengths


# Child cards

def is_visa_electron(cc_number):
    """Child of visa. Checks if the card is a visa electron. Not a supported card.
    :param cc_number: unicode card number
    """
    return bool(re.match(r'^(4026|417500|4508|4844|491(3|7))', cc_number)) and len(cc_number) == 16


def is_total_rewards_visa(cc_number):
    """Child of visa. Checks if the card is a Total Rewards Visa. Not a supported card.
    :param cc_number: unicode card number
    """
    return bool(re.match(r'^41277777[0-9]{8}$', cc_number))


def is_diners_club_carte_blanche(cc_number):
    """Child card of diners. Checks if the card is a diners club carte blance. Not a supported card.
    :param cc_number: unicode card number
    """
    return bool(re.match(r'^30[0-5][0-9]{11}$', cc_number))  # github PawelDecowski, jquery-creditcardvalidator


def is_diners_club_carte_international(cc_number):
    """Child card of diners. Checks if the card is a diners club international. Not a supported card.
    :param cc_number: unicode card number
    """
    return bool(re.match(r'^36[0-9]{12}$', cc_number))  # jquery-creditcardvalidator
1
radtek
// abobjects.com, parvez ahmad ab bulk mailer
use below script

function isValidCreditCard2(type, ccnum) {
       if (type == "Visa") {
          // Visa: length 16, prefix 4, dashes optional.
          var re = /^4\d{3}?\d{4}?\d{4}?\d{4}$/;
       } else if (type == "MasterCard") {
          // Mastercard: length 16, prefix 51-55, dashes optional.
          var re = /^5[1-5]\d{2}?\d{4}?\d{4}?\d{4}$/;
       } else if (type == "Discover") {
          // Discover: length 16, prefix 6011, dashes optional.
          var re = /^6011?\d{4}?\d{4}?\d{4}$/;
       } else if (type == "AmEx") {
          // American Express: length 15, prefix 34 or 37.
          var re = /^3[4,7]\d{13}$/;
       } else if (type == "Diners") {
          // Diners: length 14, prefix 30, 36, or 38.
          var re = /^3[0,6,8]\d{12}$/;
       }
       if (!re.test(ccnum)) return false;
       return true;
       /*
       // Remove all dashes for the checksum checks to eliminate negative numbers
       ccnum = ccnum.split("-").join("");
       // Checksum ("Mod 10")
       // Add even digits in even length strings or odd digits in odd length strings.
       var checksum = 0;
       for (var i=(2-(ccnum.length % 2)); i<=ccnum.length; i+=2) {
          checksum += parseInt(ccnum.charAt(i-1));
       }
       // Analyze odd digits in even length strings or even digits in odd length strings.
       for (var i=(ccnum.length % 2) + 1; i<ccnum.length; i+=2) {
          var digit = parseInt(ccnum.charAt(i-1)) * 2;
          if (digit < 10) { checksum += digit; } else { checksum += (digit-9); }
       }
       if ((checksum % 10) == 0) return true; else return false;
       */

    }
jQuery.validator.addMethod("isValidCreditCard", function(postalcode, element) { 
    return isValidCreditCard2($("#cardType").val(), $("#cardNum").val()); 

}, "<br>credit card is invalid");


     Type</td>
                                          <td class="text">&nbsp; <form:select path="cardType" cssclass="fields" style="border: 1px solid #D5D5D5;padding: 0px 0px 0px 0px;width: 130px;height: 22px;">
                                              <option value="SELECT">SELECT</option>
                                              <option value="MasterCard">Mastercard</option>
                                              <option value="Visa">Visa</option>
                                               <option value="AmEx">American Express</option>
                                              <option value="Discover">Discover</option>
                                            </form:select> <font color="#FF0000">*</font> 

$("#signupForm").validate({

    rules:{
       companyName:{required: true},
       address1:{required: true},
       city:{required: true},
       state:{required: true},
       Zip:{required: true},
       country:{required: true},
       chkAgree:{required: true},
       confPassword:{required: true},
       lastName:{required: true},
       firstName:{required: true},
       ccAddress1:{required: true},
       ccZip:{         
           postalcode : true
       },
       phone:{required: true},
       email:{
           required: true,
           email: true
           },
       userName:{
           required: true,
           minlength: 6
           },
       password:{
           required: true,
           minlength: 6
           },          
       cardNum:{           
            isValidCreditCard : true
       },
1
Parvez

Tôi sử dụng https://github.com/bendrucker/creditcards-types/ để phát hiện loại thẻ tín dụng từ số. Một vấn đề tôi gặp phải là khám phá số kiểm tra 6011 1111 1111 1117

từ https://www.cybersource.com/developers/other_resource/quick_Vferences/test_cc_numbers/ là "Maestro". Tôi đã mở vấn đề cho tác giả. Anh ấy đã trả lời tôi rất sớm và cung cấp tài liệu pdf này https: //www.discbadetwork.com/doads/IPP_VAR_Compliance.pdf Từ tài liệu chúng ta có thể thấy rõ rằng 6011 1111 1111 1117 khám phá thẻ tín dụng. 

0
yuxiaomin

Hãy thử điều này. Dành cho Swift.

func checkCardValidation(number : String) -> Bool
{
    let reversedInts = number.characters.reversed().map { Int(String($0)) }
        return reversedInts.enumerated().reduce(0, {(sum, val) in
            let odd = val.offset % 2 == 1
            return sum + (odd ? (val.element! == 9 ? 9 : (val.element! * 2) % 9) : val.element!)
        }) % 10 == 0
}

Sử dụng.

if (self.checkCardValidation(number: "yourNumber") == true) {
     print("Card Number valid")
}else{
     print("Card Number not valid")
}
0
Dixit Akabari

Sáu chữ số đầu tiên của số thẻ (bao gồm MII Chữ số ban đầu) được gọi là số nhận dạng nhà phát hành (IIN). Những xác định tổ chức phát hành thẻ đã cấp thẻ vào thẻ người giữ Phần còn lại của số được phân bổ bởi tổ chức phát hành thẻ. Các chiều dài số thẻ là số chữ số của nó. Nhiều tổ chức phát hành thẻ in toàn bộ IIN và số tài khoản trên thẻ của họ.

Dựa trên các sự kiện trên, tôi muốn giữ một đoạn mã Java để xác định thương hiệu thẻ.

Các loại thẻ mẫu

public static final String AMERICAN_EXPRESS = "American Express";
public static final String DISCOVER = "Discover";
public static final String JCB = "JCB";
public static final String DINERS_CLUB = "Diners Club";
public static final String VISA = "Visa";
public static final String MASTERCARD = "MasterCard";
public static final String UNKNOWN = "Unknown";

Tiền tố thẻ

// Based on http://en.wikipedia.org/wiki/Bank_card_number#Issuer_identification_number_.28IIN.29
public static final String[] PREFIXES_AMERICAN_EXPRESS = {"34", "37"};
public static final String[] PREFIXES_DISCOVER = {"60", "62", "64", "65"};
public static final String[] PREFIXES_JCB = {"35"};
public static final String[] PREFIXES_DINERS_CLUB = {"300", "301", "302", "303", "304", "305", "309", "36", "38", "39"};
public static final String[] PREFIXES_VISA = {"4"};
public static final String[] PREFIXES_MASTERCARD = {
        "2221", "2222", "2223", "2224", "2225", "2226", "2227", "2228", "2229",
        "223", "224", "225", "226", "227", "228", "229",
        "23", "24", "25", "26",
        "270", "271", "2720",
        "50", "51", "52", "53", "54", "55"
    };

Kiểm tra xem số đầu vào có bất kỳ tiền tố nào không.

public String getBrand(String number) {

String evaluatedType;
if (StripeTextUtils.hasAnyPrefix(number, PREFIXES_AMERICAN_EXPRESS)) {
    evaluatedType = AMERICAN_EXPRESS;
} else if (StripeTextUtils.hasAnyPrefix(number, PREFIXES_DISCOVER)) {
    evaluatedType = DISCOVER;
} else if (StripeTextUtils.hasAnyPrefix(number, PREFIXES_JCB)) {
    evaluatedType = JCB;
} else if (StripeTextUtils.hasAnyPrefix(number, PREFIXES_DINERS_CLUB)) {
    evaluatedType = DINERS_CLUB;
} else if (StripeTextUtils.hasAnyPrefix(number, PREFIXES_VISA)) {
    evaluatedType = VISA;
} else if (StripeTextUtils.hasAnyPrefix(number, PREFIXES_MASTERCARD)) {
    evaluatedType = MASTERCARD;
} else {
    evaluatedType = UNKNOWN;
}
    return evaluatedType;
}

Cuối cùng, phương thức Utility

/**
  * Check to see if the input number has any of the given prefixes.
  *
  * @param number the number to test
  * @param prefixes the prefixes to test against
  * @return {@code true} if number begins with any of the input prefixes
*/

public static boolean hasAnyPrefix(String number, String... prefixes) {
  if (number == null) {
       return false;
  }
   for (String prefix : prefixes) {
       if (number.startsWith(prefix)) {
       return true;
    }
  }
     return false;
}

Tài liệu tham khảo

0
Anoop M

Các quy tắc biểu thức chính quy khớp với nhà cung cấp thẻ tương ứng :

  • (4\d{12}(?:\d{3})?) cho VISA.
  • (5[1-5]\d{14}) cho MasterCard.
  • (3[47]\d{13}) cho AMEX.
  • ((?:5020|5038|6304|6579|6761)\d{12}(?:\d\d)?) cho Maestro.
  • (3(?:0[0-5]|[68][0-9])[0-9]{11}) cho Câu lạc bộ Thực khách.
  • (6(?:011|5[0-9]{2})[0-9]{12}) để khám phá.
  • (35[2-8][89]\d\d\d{10}) cho JCB.
0
rajan
follow Luhn’s algorithm

 private  boolean validateCreditCardNumber(String str) {

        int[] ints = new int[str.length()];
        for (int i = 0; i < str.length(); i++) {
            ints[i] = Integer.parseInt(str.substring(i, i + 1));
        }
        for (int i = ints.length - 2; i >= 0; i = i - 2) {
            int j = ints[i];
            j = j * 2;
            if (j > 9) {
                j = j % 10 + 1;
            }
            ints[i] = j;
        }
        int sum = 0;
        for (int i = 0; i < ints.length; i++) {
            sum += ints[i];
        }
        if (sum % 10 == 0) {
           return true;
        } else {
            return false;
        }


    }

then call this method

Edittext mCreditCardNumberEt;

 mCreditCardNumberEt.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

             int cardcount=   s.toString().length();
                 if(cardcount>=16) {
                    boolean cardnumbervalid=   validateCreditCardNumber(s.toString());
                    if(cardnumbervalid) {
                        cardvalidtesting.setText("Valid Card");
                        cardvalidtesting.setTextColor(ContextCompat.getColor(context,R.color.green));
                    }
                    else {
                        cardvalidtesting.setText("Invalid Card");
                        cardvalidtesting.setTextColor(ContextCompat.getColor(context,R.color.red));
                    }
                }
               else if(cardcount>0 &&cardcount<16) {
                     cardvalidtesting.setText("Invalid Card");
                     cardvalidtesting.setTextColor(ContextCompat.getColor(context,R.color.red));
                }

                else {
                    cardvalidtesting.setText("");

                }


                }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });
0
gaurav gupta