Entendendo os números BIN: guia para desenvolvedores
O que é um número BIN/IIN?
O Bank Identification Number (BIN), formalmente chamado de Issuer Identification Number (IIN), corresponde aos primeiros 6 ou 8 dígitos do número de um cartão de pagamento. Ele identifica a bandeira e a instituição que emitiu o cartão. Os sistemas de pagamento o usam para rotear transações, aplicar regras antifraude e decidir quais regras de validação se aplicam.
Historicamente, o IIN tinha 6 dígitos. Desde a revisão de 2017 da ISO/IEC 7812-1, os novos IINs têm 8 dígitos, e a Visa e a Mastercard emitem BINs de 8 dígitos desde abril de 2022. BINs antigos de 6 dígitos continuam em circulação, então o seu código precisa lidar com os dois.
Estrutura do número BIN
Detalhamento do formato padrão
| Posição | Tamanho | Finalidade | Exemplo |
|---|---|---|---|
| 1 | 1 dígito | Identificador Principal da Indústria (MII) | 4 (bancário e financeiro) |
| 1–6 ou 1–8 | 6 ou 8 dígitos | Número de identificação do emissor (BIN/IIN), incluindo o MII | 453201 ou 45320151 |
| Depois do BIN, até o penúltimo dígito | Variável | Identificador da conta individual | 5112830 |
| Último | 1 dígito | Dígito verificador de Luhn | 6 |
Valores do Identificador Principal da Indústria (MII)
Estas são as categorias da ISO/IEC 7812-1 para o primeiro dígito:
| Dígito MII | Setor |
|---|---|
| 0 | ISO/TC 68 e outras atribuições do setor |
| 1 | Companhias aéreas |
| 2 | Companhias aéreas, setor financeiro e outras atribuições futuras do setor |
| 3 | Viagens e entretenimento |
| 4 | Bancário e financeiro |
| 5 | Bancário e financeiro |
| 6 | Comércio e bancário/financeiro |
| 7 | Petróleo e outras atribuições futuras do setor |
| 8 | Saúde, telecomunicações e outras atribuições futuras do setor |
| 9 | Para atribuição pelos órgãos nacionais de normalização |
Faixas de BIN comuns por bandeira
Faixas de BIN principais
Estas são as principais faixas publicadas. Cada bandeira também tem faixas menores, então use esta lista como auxílio de classificação, não como um registro completo.
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'],
}
A rede da Discover também aceita cartões UnionPay (incluindo a faixa 622126–622925) e Diners Club nos EUA, mas esses cartões continuam pertencendo às suas próprias bandeiras.
Implementação de consulta 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))),
}
Se o BIN tem 6 ou 8 dígitos depende do emissor, por isso o trecho guarda os primeiros 8 dígitos nos números de comprimento completo. Os serviços de consulta aceitam qualquer um dos dois.
Propriedades dos dados de BIN
Campos típicos de uma consulta de BIN
Não existe um esquema padrão: estes são os campos que a maioria dos serviços de consulta de BIN, comerciais e abertos, retorna, e os nomes variam de um provedor para outro.
| Campo | Descrição | Exemplo |
|---|---|---|
| scheme | Bandeira do cartão | "visa" |
| country | País emissor | "US" |
| type | Tipo de cartão | "credit" |
| category | Nível ou produto do cartão | "platinum" |
| issuer | Banco emissor | "CHASE" |
| length | Tamanho do número do cartão | 16 |
Regras de validação baseadas em BIN
Tamanho do número do cartão por bandeira
| Bandeira | Tamanhos válidos |
|---|---|
| Visa | 13, 16, 19 |
| Mastercard | 16 |
| American Express | 15 |
| Discover | 16–19 |
| JCB | 16–19 |
| Diners Club | 14–19 (36), 16–19 (demais faixas) |
| UnionPay | 16–19 |
Exemplo de integração
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';
},
};
Considerações de segurança
-
Proteção de dados
- Um BIN sozinho não é dado do portador do cartão, mas o número completo do cartão (PAN) é. Evite armazenar PANs completos; se precisar, o Requisito 3 do PCI DSS exige que eles fiquem ilegíveis (criptografia forte, truncamento, tokenização ou hash com chave).
- Se você guardar um número truncado, respeite os limites de truncamento do PCI SSC: no máximo os 8 primeiros e outros 4 dígitos quaisquer para PANs de 16 dígitos, e os 6 primeiros e os 4 últimos para números Amex de 15 dígitos.
- Criptografe os números completos de cartão em trânsito (TLS) e restrinja quem pode acessá-los.
-
Conformidade
- Armazenar ou processar PANs completos coloca os seus sistemas no escopo do PCI DSS; a tokenização pelo seu provedor de pagamentos mantém a maior parte dele de fora.
- Defina prazos de retenção para tudo o que for derivado de dados de cartão, incluindo logs.
-
Desempenho
- Armazene em cache os resultados das consultas de BIN; os dados de BIN mudam devagar.
- Respeite os limites de requisições do seu provedor de consulta e use endpoints em lote quando disponíveis.
Boas práticas para processar BIN
| Prática | Finalidade | Implementação |
|---|---|---|
| Cache | Reduzir chamadas à API | Guarde os dados de BIN em memória ou em uma tabela local |
| Validação | Evitar erros | Verifique formato, tamanho e Luhn antes de chamar uma API |
| Monitoramento | Detectar problemas | Registre em log falhas de consulta e BINs desconhecidos |
| Suporte a 8 dígitos | Manter a precisão | Compare primeiro com 8 dígitos e depois recorra a 6 |
Os dados de BIN são um auxílio de classificação, não uma prova de que um cartão existe ou será aprovado. Combine-os com a verificação de Luhn, as regras de tamanho e, em pagamentos reais, o resultado da autorização do seu gateway de pagamento.