Comprendre les numéros BIN : guide pour les développeurs
Qu'est-ce qu'un numéro BIN/IIN ?
Le numéro d'identification bancaire (BIN, Bank Identification Number), officiellement appelé numéro d'identification de l'émetteur (IIN, Issuer Identification Number), correspond aux 6 ou 8 premiers chiffres d'un numéro de carte de paiement. Il identifie le réseau de la carte et l'établissement qui l'a émise. Les systèmes de paiement l'utilisent pour router les transactions, appliquer les règles antifraude et déterminer les règles de validation applicables.
L'IIN comptait historiquement 6 chiffres. Depuis la révision de 2017 de la norme ISO/IEC 7812-1, les nouveaux IIN comptent 8 chiffres, et Visa et Mastercard émettent des BIN à 8 chiffres depuis avril 2022. D'anciens BIN à 6 chiffres sont toujours en circulation : votre code doit donc gérer les deux.
Structure d'un numéro BIN
Décomposition du format standard
| Position | Longueur | Rôle | Exemple |
|---|---|---|---|
| 1 | 1 chiffre | Major Industry Identifier (MII) | 4 (banque et finance) |
| 1–6 ou 1–8 | 6 ou 8 chiffres | Issuer Identification Number (BIN/IIN), MII compris | 453201 ou 45320151 |
| Après le BIN, jusqu'à l'avant-dernier chiffre | Variable | Identifiant du compte individuel | 5112830 |
| Dernière | 1 chiffre | Chiffre de contrôle Luhn | 6 |
Valeurs du Major Industry Identifier (MII)
Voici les catégories définies par la norme ISO/IEC 7812-1 pour le premier chiffre :
| Chiffre MII | Secteur |
|---|---|
| 0 | ISO/TC 68 et autres attributions sectorielles |
| 1 | Compagnies aériennes |
| 2 | Compagnies aériennes, finance et autres attributions sectorielles futures |
| 3 | Voyage et divertissement |
| 4 | Banque et finance |
| 5 | Banque et finance |
| 6 | Commerce et banque/finance |
| 7 | Pétrole et autres attributions sectorielles futures |
| 8 | Santé, télécommunications et autres attributions sectorielles futures |
| 9 | Attribution par les organismes nationaux de normalisation |
Plages de BIN courantes par réseau de carte
Plages de BIN principales
Voici les principales plages publiées. Chaque réseau dispose aussi de plages plus petites : considérez ce tableau comme une aide à la classification, pas comme un registre complet.
bin_ranges = {
'Visa': ['4'],
'Mastercard': ['51-55', '2221-2720'],
'American Express': ['34', '37'],
'Discover': ['6011', '644-649', '65'],
'JCB': ['3528-3589'],
'Diners Club': ['300-305', '3095', '36', '38-39'],
'UnionPay': ['62', '8100-8171'],
}
Aux États-Unis, le réseau Discover accepte aussi les cartes UnionPay (y compris la plage 622126–622925) et Diners Club, mais ces cartes appartiennent toujours à leur propre réseau.
Implémentation d'une recherche de BIN
import re
NETWORK_LENGTHS = {
'Visa': {13, 16, 19},
'Mastercard': {16},
'American Express': {15},
'Discover': {16, 17, 18, 19},
'JCB': {16, 17, 18, 19},
'Diners Club': {14, 15, 16, 17, 18, 19},
'UnionPay': {16, 17, 18, 19},
}
def detect_network(number: str) -> str:
first2, first4 = int(number[:2]), int(number[:4])
if number.startswith(('34', '37')):
return 'American Express'
if number.startswith(('300', '301', '302', '303', '304', '305', '3095', '36', '38', '39')):
return 'Diners Club'
if 3528 <= first4 <= 3589:
return 'JCB'
if number.startswith(('6011', '65')) or 644 <= int(number[:3]) <= 649:
return 'Discover'
if number.startswith('62') or 8100 <= first4 <= 8171:
return 'UnionPay'
if 51 <= first2 <= 55 or 2221 <= first4 <= 2720:
return 'Mastercard'
if number.startswith('4'):
return 'Visa'
return 'Unknown'
def validate_bin(card_number: str) -> dict:
number = re.sub(r'\D', '', card_number)
if len(number) < 6:
return {'valid': False, 'error': 'Enter at least 6 digits'}
network = detect_network(number)
return {
'bin': number[:8] if len(number) >= 16 else number[:6],
'network': network,
'length': len(number),
'valid_length': len(number) in NETWORK_LENGTHS.get(network, set(range(12, 20))),
}
Le fait que le BIN compte 6 ou 8 chiffres dépend de l'émetteur : l'extrait conserve donc les 8 premiers chiffres pour les numéros complets. Les services de recherche acceptent l'un comme l'autre.
Propriétés des données BIN
Champs courants d'une recherche de BIN
Il n'existe pas de schéma standard : voici les champs que renvoient la plupart des services de recherche de BIN, commerciaux ou ouverts, et leurs noms varient selon le fournisseur.
| Champ | Description | Exemple |
|---|---|---|
| scheme | Réseau de la carte | "visa" |
| country | Pays émetteur | "US" |
| type | Type de carte | "credit" |
| category | Niveau ou produit de la carte | "platinum" |
| issuer | Banque émettrice | "CHASE" |
| length | Longueur du numéro de carte | 16 |
Règles de validation basées sur le BIN
Longueur du numéro de carte par réseau
| Réseau | Longueurs valides |
|---|---|
| Visa | 13, 16, 19 |
| Mastercard | 16 |
| American Express | 15 |
| Discover | 16–19 |
| JCB | 16–19 |
| Diners Club | 14–19 (36), 16–19 (autres plages) |
| UnionPay | 16–19 |
Exemple d'intégration
const NETWORK_LENGTHS = {
visa: [13, 16, 19],
mastercard: [16],
amex: [15],
discover: [16, 17, 18, 19],
jcb: [16, 17, 18, 19],
diners: [14, 15, 16, 17, 18, 19],
unionpay: [16, 17, 18, 19],
};
const binValidator = {
checkBIN(cardNumber) {
const digits = cardNumber.replace(/\D/g, '');
if (digits.length < 6) {
return { valid: false, error: 'Enter at least 6 digits' };
}
const network = this.detectNetwork(digits);
const lengths = NETWORK_LENGTHS[network] || [];
return {
valid: lengths.includes(digits.length),
network,
bin: digits.slice(0, digits.length >= 16 ? 8 : 6),
cardLength: digits.length,
};
},
detectNetwork(digits) {
const first4 = Number(digits.slice(0, 4));
if (/^3[47]/.test(digits)) return 'amex';
if (/^(30[0-5]|3095|36|3[89])/.test(digits)) return 'diners';
if (first4 >= 3528 && first4 <= 3589) return 'jcb';
if (/^(6011|64[4-9]|65)/.test(digits)) return 'discover';
if (/^62/.test(digits) || (first4 >= 8100 && first4 <= 8171)) return 'unionpay';
if (/^5[1-5]/.test(digits) || (first4 >= 2221 && first4 <= 2720)) return 'mastercard';
if (/^4/.test(digits)) return 'visa';
return 'unknown';
},
};
Considérations de sécurité
-
Protection des données
- Un BIN seul n'est pas une donnée de titulaire de carte, mais un numéro de carte complet (PAN) l'est. Évitez de stocker des PAN complets ; si vous y êtes obligé, l'exigence 3 de PCI DSS impose de les rendre illisibles (cryptographie robuste, troncature, tokenisation ou hachage à clé).
- Si vous conservez un numéro tronqué, respectez les limites de troncature du PCI SSC : au maximum les 8 premiers chiffres et 4 autres chiffres pour les PAN à 16 chiffres, et les 6 premiers et 4 derniers chiffres pour les numéros Amex à 15 chiffres.
- Chiffrez les numéros de carte complets en transit (TLS) et restreignez les personnes qui peuvent y accéder.
-
Conformité
- Stocker ou traiter des PAN complets fait entrer vos systèmes dans le périmètre PCI DSS ; la tokenisation via votre prestataire de paiement en exclut l'essentiel.
- Définissez des durées de conservation pour tout ce qui est dérivé des données de carte, y compris les logs.
-
Performances
- Mettez en cache les résultats des recherches de BIN ; les données BIN évoluent lentement.
- Respectez les limites de débit de votre fournisseur de recherche et utilisez les points de terminaison en lot lorsqu'ils existent.
Bonnes pratiques pour le traitement des BIN
| Pratique | Objectif | Mise en œuvre |
|---|---|---|
| Mise en cache | Réduire les appels API | Stocker les données BIN en mémoire ou dans une table locale |
| Validation | Éviter les erreurs | Vérifier le format, la longueur et Luhn avant d'appeler une API |
| Surveillance | Détecter les problèmes | Journaliser les échecs de recherche et les BIN inconnus |
| Prise en charge des 8 chiffres | Rester précis | Chercher d'abord sur 8 chiffres, puis se rabattre sur 6 |
Les données BIN sont une aide à la classification, pas une preuve qu'une carte existe ou sera acceptée. Combinez-les avec le contrôle de Luhn, les règles de longueur et, pour les paiements réels, le résultat d'autorisation renvoyé par votre passerelle.