Question

J'essaie de comprendre comment détecter le type de carte de crédit uniquement en fonction de son numéro. Est-ce que quelqu'un connaît un moyen sûr et fiable de le trouver?

Était-ce utile?

La solution

Le numéro de carte de crédit / débit est appelé PAN ou numéro de compte principal . Les six premiers chiffres du PAN proviennent du IIN ou numéro d'identification de l'émetteur , appartenant à la banque émettrice (les numéros IIN étaient auparavant connus sous le nom BIN & # 8212; Identification de la banque. Numbers & # 8212; afin que vous puissiez voir des références à cette terminologie dans certains documents). Ces six chiffres sont soumis à une norme internationale, ISO / IEC 7812 , et peuvent être utilisé pour déterminer le type de carte à partir du numéro.

Malheureusement, la base de données ISO / CEI 7812 n’est pas accessible au public. Cependant, il existe des listes non officielles, commerciales et gratuites, comprenant sur Wikipedia .

Quoi qu'il en soit, pour détecter le type à partir du nombre, vous pouvez utiliser une expression régulière semblable à celles ci-dessous: Crédit pour les expressions originales

Visa: ^ 4 [0-9] {6,} $ Les numéros de carte Visa commencent par un 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,} $ Avant 2016, les numéros MasterCard commencent par les numéros 51 à 55, mais ceci ne détectera que les cartes de crédit MasterCard ; d’autres cartes émises à l’aide du système MasterCard ne se situent pas dans cette plage IIN. En 2016, ils ajouteront des nombres dans la plage (222100-272099).

American Express: ^ 3 [47] [0-9] {5,} $ Les numéros de carte American Express commencent par 34 ou 37.

Diners Club: ^ 3 (?: 0 [0-5] | [68] [0-9]) [0-9] {4,} $ Les numéros de cartes Diners Club commencent par 300 et 305, 36 ou 38. Certaines cartes Diners Club commencent par 5 et comportent 16 chiffres. Celles-ci sont une entreprise commune entre Diners Club et MasterCard et doivent être traitées comme une MasterCard.

Découvrir: ^ 6 (?: 011 | 5 [0-9] {2}) [0-9] {3,} $ Les numéros de carte de découverte commencent avec 6011 ou 65.

JCB: ^ (?: 2131 | 1800 | 35 [0-9] {3}) [0-9] {3,} $ Les cartes JCB commencent avec 2131, 1800 ou 35.

Malheureusement, un certain nombre de types de cartes traitées avec le système MasterCard n'habitent pas dans la plage IIN de MasterCard (numéros commençant par 51 ... 55); le cas le plus important est celui des cartes Maestro, dont beaucoup ont été émises par d'autres banques & # 8217; Les plages IIN et sont donc réparties dans l’espace numérique. Par conséquent, il peut être préférable de supposer que toute carte qui n’est pas d’un autre type que vous acceptez doit être une carte MasterCard .

Important : la longueur des numéros de carte varie; Par exemple, Visa a déjà émis des cartes avec des PAN à 13 chiffres et des cartes avec des PAN à 16 chiffres. La documentation de Visa indique actuellement que le fournisseur peut émettre ou peut avoir émis des numéros comportant entre 12 et 19 chiffres. Par conséquent, vous ne devez pas vérifier la longueur du numéro de carte, sauf pour vérifier qu'il comporte au moins 7 chiffres (pour un IIN complet plus un chiffre de contrôle, qui doit correspondre à la valeur prédite par l'algorithme de Luhn ).

Un conseil supplémentaire: avant de traiter un PAN du titulaire de carte, supprimez les espaces et les caractères de ponctuation de l'entrée . Pourquoi? Parce qu'il est généralement beaucoup beaucoup plus facile de saisir les chiffres par groupes, de la même manière que leur affichage sur le recto d'une carte de crédit, c'est-à-dire.

4444 4444 4444 4444

est beaucoup plus facile à saisir correctement que

4444444444444444

Il n’ya vraiment aucun avantage à réprimander l’utilisateur, car ils ont saisi des caractères inattendus.

Cela implique également de vous assurer que vos champs de saisie ont suffisamment d'espace pour au moins 24 caractères, sinon les utilisateurs qui entrent des espaces manqueront d'espace. I & # 8217; d Il est recommandé d’élargir le champ à 32 caractères et d’autoriser 64 caractères; cela donne beaucoup de marge pour l'expansion.

Voici une image qui donne un peu plus de perspicacité:

UPDATE (2014): la méthode de la somme de contrôle ne semble plus être un moyen valide de vérifier l'authenticité d'une carte , comme indiqué dans les commentaires de cette réponse.

MISE À JOUR (2016): Mastercard doit mettre en œuvre de nouvelles plages BIN à partir du paiement à l'Ach . .

Vérification de carte de crédit

Autres conseils

En 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
        }
    }
}

Test unitaire:

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

Mise à jour: 15 juin 2016 (solution ultime actuellement)

Veuillez noter que j’ai même voté pour celui qui a obtenu le vote le plus élevé, mais pour préciser que ce sont les expressions rationnelles qui fonctionnent, j’ai testé avec des milliers de vrais codes BIN. Le plus important est d'utiliser des chaînes de début (^), sinon cela donnera de faux résultats dans le monde réel!

JCB ^ (?: 2131 | 1800 | 35) [0-9] {0,} $ Commencez par: 2131, 1800, 35 ( 3528-3589)

American Express ^ 3 [47] [0-9] {0,} $ Commencez par: 34, 37

Diners Club ^ 3 (?: 0 [0-59] {1} | [689]) [0-9] {0,} $ Commencez par : 300-305, 309, 36, 38-39

Visa ^ 4 [0-9] {0,} $ Commencez par: 4

MasterCard ^ (5 [1-5] | 222 [1-9] | 22 [3-9] | 2 [3-6] | 27 [01] | 2720 ) [0-9] {0,} $ Commence par: 2221-2720, 51-55

Maestro ^ (5 [06789] | 6) [0-9] {0,} $ Maestro connaît une croissance constante dans la plage suivante: 60-69 , a commencé avec / pas autre chose, mais le 5 doit toujours être encodé en tant que mastercard. Les cartes Maestro doivent être détectées à la fin du code car certaines autres ont entre 60 et 69. Veuillez regarder le code.

Découvrez ^ (6011 | 65 | 64 [4-9] | 62212 [6-9] | 6221 [3-9] | 622 [2-8] | 6229 [ 01] | 62292 [0-5]) [0-9] {0,} $ Découvrir assez difficile à coder, commencez par: 6011, 622126-622925, 644-649, 65

Dans javascript , j'utilise cette fonction. C’est bien lorsque vous l’assignez à un événement onkeyup et qu’il donne le résultat le plus rapidement possible.

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,}

Ici, vous pouvez jouer avec:

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

Cette fonction est également utilisée par PHP pour détecter certaines cartes VISA / MC:

    /**
 * 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
}
); //2131, 1800, 35 (3528-3589) // American Express amex_regex = new RegExp('^3[47][0-9]{0,}

Ici, vous pouvez jouer avec:

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

Cette fonction est également utilisée par PHP pour détecter certaines cartes VISA / MC:

<*>); //34, 37 // Diners Club diners_regex = new RegExp('^3(?:0[0-59]{1}|[689])[0-9]{0,}

Ici, vous pouvez jouer avec:

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

Cette fonction est également utilisée par PHP pour détecter certaines cartes VISA / MC:

<*>); //300-305, 309, 36, 38-39 // Visa visa_regex = new RegExp('^4[0-9]{0,}

Ici, vous pouvez jouer avec:

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

Cette fonction est également utilisée par PHP pour détecter certaines cartes VISA / MC:

<*>); //4 // MasterCard mastercard_regex = new RegExp('^(5[1-5]|222[1-9]|22[3-9]|2[3-6]|27[01]|2720)[0-9]{0,}

Ici, vous pouvez jouer avec:

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

Cette fonction est également utilisée par PHP pour détecter certaines cartes VISA / MC:

<*>); //2221-2720, 51-55 maestro_regex = new RegExp('^(5[06789]|6)[0-9]{0,}

Ici, vous pouvez jouer avec:

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

Cette fonction est également utilisée par PHP pour détecter certaines cartes VISA / MC:

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

Ici, vous pouvez jouer avec:

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

Cette fonction est également utilisée par PHP pour détecter certaines cartes VISA / MC:

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

Ici, vous pouvez jouer avec:

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

Cette fonction est également utilisée par PHP pour détecter certaines cartes VISA / MC:

<*>
  public string GetCreditCardType(string CreditCardNumber)
    {
        Regex regVisa = new Regex("^4[0-9]{12}(?:[0-9]{3})?<*>quot;);
        Regex regMaster = new Regex("^5[1-5][0-9]{14}<*>quot;);
        Regex regExpress = new Regex("^3[47][0-9]{13}<*>quot;);
        Regex regDiners = new Regex("^3(?:0[0-5]|[68][0-9])[0-9]{11}<*>quot;);
        Regex regDiscover = new Regex("^6(?:011|5[0-9]{2})[0-9]{12}<*>quot;);
        Regex regJCB= new Regex("^(?:2131|1800|35\\d{3})\\d{11}<*>quot;);


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

Voici la fonction pour vérifier le type de carte de crédit en utilisant Regex, c #

Découvrez ceci:

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

Voici Code C # ou VB complet pour tous les types des choses liées au CC sur codeproject.

  • IsValidNumber
  • GetCardTypeFromNumber
  • GetCardTestNumber
  • PassesLuhnTest

Cet article est publié depuis quelques années sans commentaires négatifs.

Récemment, j’avais besoin d’une telle fonctionnalité. Je portais le validateur de cartes de crédit Zend Framework sur Ruby. gem rubis: https://github.com/Fivell/credit_card_validations cadre zend: https://github.com/zendframework /zf2/blob/master/library/Zend/Validator/CreditCard.php

Ils utilisent tous les deux des plages INN pour détecter le type. Ici vous pouvez lire à propos de la DCI

Selon cela, vous pouvez détecter les cartes de crédit alternativement (sans regexps, mais en déclarant certaines règles concernant les préfixes et la longueur possible)

Nous avons donc les règles suivantes pour la plupart des cartes utilisées

########  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}
    ]

}

Ensuite, en recherchant le préfixe et en comparant la longueur, vous pouvez détecter la marque de la carte de crédit. N'oubliez pas non plus de luhn algoritm (il est décrit ici http://fr.wikipedia.org/ / Luhn ).

Compacter la version javascript

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

La réponse d'Anatoliy en 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;
    }
 }

Voici une fonction de classe php qui retourne CCtype par CCnumber.
Ce code ne valide pas la carte ou ne fonctionne pas L'algorithme Luhn tente uniquement de trouver le type de carte de crédit basé sur la table cette page . utilise fondamentalement la longueur de numéro CC et le préfixe CCcard pour déterminer le type de carte CC.

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

N'essayez pas de détecter le type de carte de crédit dans le cadre du traitement d'un paiement. Vous risquez de refuser des transactions valides.

Si vous devez fournir des informations à votre processeur de paiement (par exemple, un objet de carte de crédit PayPal nécessite de nommer la type de carte ), puis devinez-le à partir de la moindre information disponible, par exemple

.
$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.');
}

Cette implémentation (en utilisant uniquement les deux premiers chiffres) est suffisante pour identifier tous les systèmes de cartes principaux (et dans le cas de PayPal, tous les systèmes pris en charge). En fait, vous voudrez peut-être ignorer l'exception et choisir par défaut le type de carte le plus populaire. Laissez la passerelle / le processeur de paiement vous avertir en cas d'erreur de validation en réponse à votre demande.

En réalité, votre passerelle de paiement ne se soucie pas de la valeur que vous fournissez .

Les premiers chiffres de la carte de crédit peuvent être utilisés pour se rapprocher du vendeur:

  • Visa: 49,44 ou 47
  • Visa électronique: 42, 45, 48, 49
  • MasterCard: 51
  • Amex: 34
  • Diners: 30, 36, 38
  • JCB: 35

Dans Card Card Recognition (CRR), un inconvénient des algorithmes qui utilisent une série de regex ou d’autres plages codées en dur est que les BIN / IIN changent avec le temps, selon mon expérience. Le co-marquage des cartes est une complication permanente. Différents acquéreurs de cartes / commerçants peuvent avoir besoin que vous traitiez la même carte différemment, en fonction, par exemple, de géolocalisation.

De plus, au cours des dernières années, par exemple avec Les cartes UnionPay étant plus répandues, les modèles existants ne prennent pas en charge de nouvelles gammes qui s’entrelacent parfois avec des gammes plus étendues qu’elles remplacent.
Connaître la géographie que votre système doit couvrir peut être utile, car certaines plages ne peuvent être utilisées que dans certains pays. Par exemple, les gammes 62 incluent des sous-gammes AAA aux États-Unis, mais si votre base de marchand est en dehors des États-Unis, vous pourrez peut-être traiter les 62 comme UnionPay.
Vous pouvez également être invité à traiter une carte différemment en fonction de l'emplacement du commerçant. Par exemple. traiter certaines cartes du Royaume-Uni comme des cartes de débit domestiques, mais des crédits internationaux.

Il existe un ensemble de règles très utile maintenu par une grande banque acquéreuse. Par exemple. https://www.barclaycard.co.uk/business/ files / BIN-Rules-EIRE.pdf et https://www.barclaycard.co.uk/business/files/BIN-Rules-UK.pdf . (Liens valides à compter de juin 2017, grâce à l'utilisateur qui a fourni un lien vers une référence mise à jour.) Sachez toutefois que, même si ces règles CRR peuvent représenter l'univers de Card Issuing tel qu'il s'applique aux marchands acquis par cette entité, cela n'inclut pas par exemple plages identifiées comme CUP / UPI.

Ces commentaires s’appliquent aux scénarios de bande magnétique (MagStripe) ou PKE (Pan Key Entry). La situation est encore différente dans le monde ICC / EMV.

Mise à jour: JCB a toujours 16 longues réponses sur cette page (ainsi que sur la page WikiPedia associée). Cependant, dans mon entreprise, nous avons une équipe d'ingénieurs dédiée qui certifie nos périphériques et logiciels de point de vente dans plusieurs banques et régions géographiques. Le dernier paquet de cartes de certification que cette équipe a reçu de JCB avait un cas de réussite pour un long PAN 19.

Ma solution avec jQuery:

function detectCreditCardType() {
    var type = new Array;
    type[1] = '^4[0-9]{12}(?:[0-9]{3})?

Dans le cas où 0 est renvoyé, le type de carte de crédit n'est pas détecté.

" carte de crédit " La classe doit être ajoutée au champ de saisie de la carte de crédit.

; // visa type[2] = '^5[1-5][0-9]{14}

Dans le cas où 0 est renvoyé, le type de carte de crédit n'est pas détecté.

" carte de crédit " La classe doit être ajoutée au champ de saisie de la carte de crédit.

; // mastercard type[3] = '^6(?:011|5[0-9]{2})[0-9]{12}

Dans le cas où 0 est renvoyé, le type de carte de crédit n'est pas détecté.

" carte de crédit " La classe doit être ajoutée au champ de saisie de la carte de crédit.

; // discover type[4] = '^3[47][0-9]{13}

Dans le cas où 0 est renvoyé, le type de carte de crédit n'est pas détecté.

" carte de crédit " La classe doit être ajoutée au champ de saisie de la carte de crédit.

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

Dans le cas où 0 est renvoyé, le type de carte de crédit n'est pas détecté.

" carte de crédit " La classe doit être ajoutée au champ de saisie de la carte de crédit.

Swift 2.1 Version de la réponse d'Usman Y. Utilisez une instruction print pour vérifier afin d’appeler par une valeur de chaîne

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

func validateCardType(testCard: String) -> String {

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


    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 ""

}

Stripe a fourni cette fantastique bibliothèque javascript pour la détection de schémas de cartes. Permettez-moi d'ajouter quelques extraits de code et de vous montrer comment l'utiliser.

Tout d'abord, incluez-le dans votre page Web en tant que

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

Ensuite, utilisez la fonction cardType pour détecter le schéma de carte.

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

Voici les liens de référence pour plus d'exemples et de démos.

  1. blog Stripe pour jquery.payment.js
  2. référentiel Github

J'ai beaucoup cherché dans le formatage des cartes de crédit et des numéros de téléphone. J'ai trouvé beaucoup de bons conseils, mais rien ne correspond vraiment à mes désirs. J'ai donc créé ce morceau de code . Vous l'utilisez comme ceci:

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

En bref, vous pouvez créer une énumération pour détecter le type de carte de crédit.

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,}<*>quot;

    case .Master:
        regex = "^5[1-5][0-9]{5,}<*>quot;

    case .Amex:
        regex = "^3[47][0-9]{13}<*>quot;

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

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

Appelez la méthode CreditCardType.cardTypeForCreditCardNumber ("# numéro de carte") qui renvoie la valeur enum CreditCardType.

// 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
       },

Juste une petite cuillère:

$("#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");

        }

    });

Voici un exemple de fonctions booléennes écrites en Python qui renvoient True si la carte est détectée conformément au nom de la fonction.

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

Règles d'expression régulière correspondant à vendeurs de cartes respectifs :

  • (4 \ d {12} (?: \ d {3})?) pour VISA.
  • (5 [1-5] \ d {14}) pour MasterCard.
  • (3 [47] \ d {13}) pour AMEX.
  • ((?: 5020 | 5038 | 6304 | 6579 | 6761) \ d {12} (?: \ d \ d)?) pour Maestro.
  • (3 (?: 0 [0-5] | [68] [0-9]) [0-9] {11}) pour Diners Club.
  • (6 (?: 011 | 5 [0-9] {2}) [0-9] {12}) pour Discover.
  • (35 [2-8] [89] \ d \ d \ d {10}) pour JCB.
  

Les six premiers chiffres d’un numéro de carte (y compris le premier MII)   digit) sont appelés numéro d'identification de l'émetteur (IIN). Celles-ci   identifier l'institution émettrice de la carte qui a émis la carte à la carte   titulaire. Le reste du numéro est attribué par l'émetteur de la carte. le   La longueur du numéro de carte est son nombre de chiffres. De nombreux émetteurs de cartes impriment   l'intégralité de l'IIN et du numéro de compte sur leur carte.

Compte tenu de ce qui précède, j'aimerais conserver un extrait de code JAVA pour identifier la marque de la carte.

  

Exemples de types de cartes

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";
  

Préfixes de cartes

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

Vérifiez si le numéro saisi a l'un des préfixes donnés.

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

Enfin, la méthode 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;
}

Référence

J'utilise https://github.com/bendrucker/creditcards-types/ pour détecter le type de carte de crédit à partir du numéro. Un problème que j'ai rencontré est découvrir le numéro de test 6011 1111 1111 1117

à partir de https://www.cybersource.com/developers/other_resources/quick_references / test_cc_numbers / nous pouvons voir que c'est un nombre découvert car il commence par 6011. Mais le résultat que je tire des types de cartes de crédit est "Maestro". J'ai ouvert la question à l'auteur. Il m'a répondu très bientôt et a fourni ce document pdf https://www.discovernetwork.com/downloads/ IPP_VAR_Compliance.pdf La doc nous montre clairement que le 6011 1111 1111 1117 n’entre pas dans la gamme des cartes de crédit découvertes.

Essayez ceci. Pour rapide.

func checkCardValidation(number : String) -> Bool
{
    let reversedInts = number.characters.reversed().map { Int(String(
if (self.checkCardValidation(number: "yourNumber") == true) {
     print("Card Number valid")
}else{
     print("Card Number not valid")
}
)) } 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 }

Utiliser.

<*>
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) {

            }
        });
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top