Question Comment détectez-vous le type de carte de crédit en fonction du nombre?


J'essaie de comprendre comment détecter le type de carte de crédit en se basant uniquement sur son numéro. Est-ce que quelqu'un connaît un moyen définitif et fiable de trouver cela?


467
2017-09-16 14:16


origine


Réponses:


Le numéro de carte de crédit / débit est appelé LA POÊLE, ou Numéro de compte principal. Les six premiers chiffres du PAN sont tirés du IIN, ou Numéro d'identification de l'émetteur, appartenant à la banque émettrice (les IIN étaient auparavant connus sous le nom de BIN - Bank Identification Numbers - vous pouvez donc voir des références à cette terminologie dans certains documents). Ces six chiffres sont soumis à une norme internationale, ISO / IEC 7812, et peut être utilisé pour déterminer le type de carte à partir du numéro.

Malheureusement, la base de données ISO / IEC 7812 n'est pas accessible au public, mais il existe des listes non officielles, commerciales et gratuites, y compris sur Wikipedia.

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

Visa:  ^4[0-9]{6,}$ Les numéros de carte Visa commencent par 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 cela ne détectera que les cartes de crédit MasterCard; d'autres cartes émises par le système MasterCard ne font pas partie de cette gamme. En 2016, ils vont ajouter des chiffres dans la fourchette (222100-272099).

American Express:  ^3[47][0-9]{5,}$ Les numéros de cartes 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 à 305, 36 ou 38. Il y a des cartes Diners Club qui commencent par 5 et ont 16 chiffres. Il s'agit d'une joint-venture entre Diners Club et MasterCard, et devrait être traitée comme une carte MasterCard.

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

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

Malheureusement, il y a un certain nombre de types de cartes traitées avec le système MasterCard qui ne sont pas dans la gamme 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 dans les gammes IIN d'autres banques et se trouvent donc partout 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: les numéros de cartes varient en longueur; 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 qu'elle peut émettre ou avoir émis des numéros de 12 à 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évue par l'algorithme de Luhn).

Un autre indice: avant de traiter un PAN de titulaire de carte, supprimez les espaces et les caractères de ponctuation de l'entrée. Pourquoi? Parce que c'est typiquement beaucoup il est plus facile d'entrer les chiffres dans les groupes, de la même manière qu'ils sont affichés sur le devant d'une carte de crédit réelle, c'est-à-dire

4444 4444 4444 4444

est beaucoup plus facile d'entrer correctement que

4444444444444444

Il n'y a vraiment aucun avantage à châtier l'utilisateur car il a saisi des caractères inattendus ici.

Cela implique également de s'assurer que vos champs d'entrée ont de la place pour au moins 24 caractères, sinon les utilisateurs qui entrent dans les espaces manqueront de place.  Je vous recommande de rendre le champ assez large pour afficher 32 caractères et en autoriser jusqu'à 64; cela donne beaucoup de marge pour l'expansion.

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

MISE À JOUR (2014): La méthode de somme de contrôle ne semble plus être un moyen valable de vérifier l'authenticité d'une carte comme indiqué dans les commentaires sur cette réponse.

MISE À JOUR (2016): Mastercard doit implémenter de nouvelles gammes BIN à partir de Ach Paiement.

Credit Card Verification


689
2017-09-16 14:18



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 de l'unité:

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

66
2017-10-02 14:04



Mis à jour: 15 juin 2016 (comme solution ultime actuellement)

S'il vous plaît noter que je donne même voter pour l'un est le mieux voté, mais pour préciser que ce sont les regexps fonctionne réellement je l'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,}$ Commencer avec: 2131, 1800, 35 (3528-3589)

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

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

Visa  ^4[0-9]{0,}$ Commencer avec: 4

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

Maestro  ^(5[06789]|6)[0-9]{0,}$ Maestro croît toujours dans la gamme: 60-69, a commencé avec / pas autre chose, mais le démarrage 5 doit être encodé en tant que mastercard de toute façon. 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écouvrir  ^(6011|65|64[4-9]|62212[6-9]|6221[3-9]|622[2-8]|6229[01]|62292[0-5])[0-9]{0,}$ Découvrez assez difficile à coder, commencez par: 6011, 622126-622925, 644-649, 65

Dans javascript J'utilise cette fonction. C'est bien quand vous l'assignez à un événement onkeyup et que cela 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,}$'); //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;
}

Ici vous pouvez jouer avec:

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

Pour PHP utiliser cette fonction, cela détecte aussi 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
}

26
2018-02-07 01:21



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

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


19
2017-12-12 14:55



Regarde ça:

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

17
2018-03-09 11:21



récemment j'avais besoin d'une telle fonctionnalité, je portais Zend Framework Credit Card Validator à ruby. ruby gem: https://github.com/Fivell/credit_card_validations  cadre zend: https://github.com/zendframework/zf2/blob/master/library/Zend/Validator/CreditCard.php

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

Selon ce que vous pouvez détecter la carte de crédit alternativement (sans regexps, mais en déclarant quelques règles sur 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 carte de crédit. N'oublie pas non plus luhn algoritm (il est décrit ici http://en.wikipedia.org/wiki/Luhn).


12
2018-03-19 12:15



Voici Compléter le code C # ou VB pour toutes sortes de choses liées au CC sur codeproject.

  • IsValidNumber
  • GetCardTypeFromNumber
  • GetCardTestNumber
  • PassesLuhnTest

Cet article a été mis en place pour quelques années sans commentaires négatifs.


11
2017-11-22 23:20



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

7
2018-03-25 10:33



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

7
2018-06-20 17:58



Voici une fonction de classe PHP renvoie CCtype par CCnumber.
Ce code ne valide pas la carte ou ne fonctionne pas Luhn algorithme seulement essayer de trouver le type de carte de crédit basé sur la table dans cette page. utilise fondamentalement la longueur CCnumber et le préfixe CCcard pour déterminer le type de carte 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
2017-08-13 18:29



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 doit type de carte), puis devinez-le à partir de la moindre information disponible, par ex.

$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 majeurs (et dans le cas de PayPal). En fait, vous pouvez ignorer l'exception et choisir le type de carte le plus populaire. Laissez la passerelle / le processeur de paiement vous indiquer s'il y a une erreur de validation en réponse à votre demande.

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


5
2018-02-26 07:05