-
Star
(103)
You must be signed in to star a gist -
Fork
(18)
You must be signed in to fork a gist
-
-
Save gusribeiro/263a165db774f5d78251 to your computer and use it in GitHub Desktop.
Amex: ^3[47][0-9]{13}$ | |
Aura: /^((?!504175))^((?!5067))(^50[0-9])/ | |
Banese Card: '^636117' | |
Cabal: '(60420[1-9]|6042[1-9][0-9]|6043[0-9]{2}|604400)' | |
Diners: '(36[0-8][0-9]{3}|369[0-8][0-9]{2}|3699[0-8][0-9]|36999[0-9]) | |
Discover: /^6(?:011|5[0-9]{2})[0-9]{12}/ | |
Elo: /^4011(78|79)|^43(1274|8935)|^45(1416|7393|763(1|2))|^50(4175|6699|67[0-6][0-9]|677[0-8]|9[0-8][0-9]{2}|99[0-8][0-9]|999[0-9])|^627780|^63(6297|6368|6369)|^65(0(0(3([1-3]|[5-9])|4([0-9])|5[0-1])|4(0[5-9]|[1-3][0-9]|8[5-9]|9[0-9])|5([0-2][0-9]|3[0-8]|4[1-9]|[5-8][0-9]|9[0-8])|7(0[0-9]|1[0-8]|2[0-7])|9(0[1-9]|[1-6][0-9]|7[0-8]))|16(5[2-9]|[6-7][0-9])|50(0[0-9]|1[0-9]|2[1-9]|[3-4][0-9]|5[0-8]))/ | |
Fort Brasil: '^628167' | |
GrandCard: '^605032' | |
Hipercard: ^606282|^3841(?:[0|4|6]{1})0 | |
JCB: /^(?:2131|1800|35\d{3})\d{11}/ | |
Mastercard: ^((5(([1-2]|[4-5])[0-9]{8}|0((1|6)([0-9]{7}))|3(0(4((0|[2-9])[0-9]{5})|([0-3]|[5-9])[0-9]{6})|[1-9][0-9]{7})))|((508116)\\d{4,10})|((502121)\\d{4,10})|((589916)\\d{4,10})|(2[0-9]{15})|(67[0-9]{14})|(506387)\\d{4,10}) | |
Personal Card: '^636085' | |
Sorocred: '^627892|^636414' | |
Valecard: '^606444|^606458|^606482' | |
Visa: ^4[0-9]{15}$ |
Obrigado @sousaweb e @WestBonner pela contribuição! Já estou atualizando o gist ;)
Alguém tem dos cartões BrasilCard, Mais e PlenoCard? Alguém tem informações sobre os cartões se por exemplo são apenas para alimentação?
As Regex que tenho usado:
ELO: /^(4011|431274|438935|451416|457393|4576|457631|457632|504175|627780|636297|636368|636369|(6503[1-3])|(6500(3[5-9]|4[0-9]|5[0-1]))|(6504(0[5-9]|1[0-9]|2[0-9]|3[0-9]))|(650(48[5-9]|49[0-9]|50[0-9]|51[1-9]|52[0-9]|53[0-7]))|(6505(4[0-9]|5[0-9]|6[0-9]|7[0-9]|8[0-9]|9[0-8]))|(6507(0[0-9]|1[0-8]))|(6507(2[0-7]))|(650(90[1-9]|91[0-9]|920))|(6516(5[2-9]|6[0-9]|7[0-9]))|(6550(0[0-9]|1[1-9]))|(6550(2[1-9]|3[0-9]|4[0-9]|5[0-8]))|(506(699|77[0-8]|7[1-6][0-9))|(509([0-9][0-9][0-9])))/,
DN: /^3(?:0[0-5]|[68][0-9])[0-9]/,//Diners
AE: /^3[47][0-9]{5,}$/, //AMEX
MC: /^(5[1-5]|222[1-9]|22[3-9]|2[3-6]|27[01]|2720)[0-9]/,//MasterCard
AU: /^((?!504175))^((?!5067))(^50[0-9])/,//Aura
VI: /^4\d{5}/, //Visa
VC: /^606444|^606458|^606482/, //ValeCard
SC: /^627892|^636414/, //SoroCred
PC: /^636085/, //PersonalCard
GC: /^605032/, //GrandCard
FB: /^628167/, //FortBrasil
@sousaweb, utilizei a tua Regex em alguns testes meus utilizando os números de cartões da mastercard gerados apartir deste site porém obtive o resultado false em alguns testes.
Procurei no stackoverflow, e encontrei essa Regex:
^(5[1-5][0-9]{14}|2(22[1-9][0-9]{12}|2[3-9][0-9]{13}|[3-6][0-9]{14}|7[0-1][0-9]{13}|720[0-9]{12}))$
Com essa Regex, não tive problema com a validação dos cartões mastercard começados com 222100 a 272099.
Pergunta do stackoverflow onde eu consegui a Regex acima:
https://stackoverflow.com/questions/9315647/regex-credit-card-number-tests
@sousaweb, utilizei a tua Regex em alguns testes meus utilizando os números de cartões da mastercard gerados apartir deste site porém obtive o resultado false em alguns testes.
Procurei no stackoverflow, e encontrei essa Regex:
^(5[1-5][0-9]{14}|2(22[1-9][0-9]{12}|2[3-9][0-9]{13}|[3-6][0-9]{14}|7[0-1][0-9]{13}|720[0-9]{12}))$
Com essa Regex, não tive problema com a validação dos cartões mastercard começados com 222100 a 272099.Pergunta do stackoverflow onde eu consegui a Regex acima:
https://stackoverflow.com/questions/9315647/regex-credit-card-number-tests
obrigado @sousaweb, irei atualizar o gist. assim teremos uma fonte cada dia mais atualizada ;)
A Regex pra cartões Aura do @JeffersonTeixeira se saiu mais acertiva nos testes que fiz pra essa bandeira.
Quanto a cartões Elo, tomei a liberdade de diminuir/limpar um pouco a Regex atual, mantendo as mesmas regras. Ficou assim:
/^4011(78|79)|^43(1274|8935)|^45(1416|7393|763(1|2))|^50(4175|6699|67[0-6][0-9]|677[0-8]|9[0-8][0-9]{2}|99[0-8][0-9]|999[0-9])|^627780|^63(6297|6368|6369)|^65(0(0(3([1-3]|[5-9])|4([0-9])|5[0-1])|4(0[5-9]|[1-3][0-9]|8[5-9]|9[0-9])|5([0-2][0-9]|3[0-8]|4[1-9]|[5-8][0-9]|9[0-8])|7(0[0-9]|1[0-8]|2[0-7])|9(0[1-9]|[1-6][0-9]|7[0-8]))|16(5[2-9]|[6-7][0-9])|50(0[0-9]|1[0-9]|2[1-9]|[3-4][0-9]|5[0-8]))/
Se alguém tiver alguma lista de cartões Elo e puder compartilhar e testar, ficarei grato :)
Se alguém tiver alguma lista de cartões Elo e puder compartilhar e testar, ficarei grato :)
@diafrit Testa esse site: https://www.vccgenerator.com/
ELO: ^(50(67(0[78]|1[5789]|2[012456789]|3[01234569]|4[0-7]|53|7[4-8])|9(0(0[0-9]|1[34]|2[0-7]|3[0359]|4[01235678]|5[01235789]|6[0-9]|7[01346789]|8[01234789]|9[123479])|1(0[34568]|4[6-9]|5[1-8]|8[356789])|2(2[0-2]|5[78]|6[1-9]|7[0-9]|8[01235678]|90)|357|4(0[7-9]|1[0-9]|2[0-2]|31|5[7-9]|6[0-6]|84)|55[01]|636|7(2[2-9]|6[5-9])))|4(0117[89]|3(1274|8935)|5(1416|7(393|63[12])))|6(27780|36368|5(0(0(3[12356789]|4[0-7]|7[78])|4(0[6-9]|1[0234]|2[2-9]|3[045789]|8[5-9]|9[0-9])|5(0[012346789]|1[0-9]|2[0-9]|3[0178]|5[2-9]|6[0-6]|7[7-9]|8[0-8]|9[1-8])|72[0-7]|9(0[1-9]|1[0-9]|2[0128]|3[89]|4[6-9]|5[0145]|6[235678]|71))|16(5[2-9]|6[0-9]|7[01456789])|50(0[0-9]|1[02345678]|36|5[1267]))))\\d{0,13}$
HIPERCARD: ^606282|^3841(?:[0|4|6]{1})0
MASTERCARD: ^((5(([1-2]|[4-5])[0-9]{8}|0((1|6)([0-9]{7}))|3(0(4((0|[2-9])[0-9]{5})|([0-3]|[5-9])[0-9]{6})|[1-9][0-9]{7})))|((508116)\\d{4,10})|((502121)\\d{4,10})|((589916)\\d{4,10})|(2[0-9]{15})|(67[0-9]{14})|(506387)\\d{4,10})
AMEX: ^3[47][0-9]{13}$
VISA: ^4[0-9]{15}$
Atualização 2021
A Regex pra cartões Aura do @JeffersonTeixeira se saiu mais acertiva nos testes que fiz pra essa bandeira.
Quanto a cartões Elo, tomei a liberdade de diminuir/limpar um pouco a Regex atual, mantendo as mesmas regras. Ficou assim:
/^4011(78|79)|^43(1274|8935)|^45(1416|7393|763(1|2))|^50(4175|6699|67[0-6][0-9]|677[0-8]|9[0-8][0-9]{2}|99[0-8][0-9]|999[0-9])|^627780|^63(6297|6368|6369)|^65(0(0(3([1-3]|[5-9])|4([0-9])|5[0-1])|4(0[5-9]|[1-3][0-9]|8[5-9]|9[0-9])|5([0-2][0-9]|3[0-8]|4[1-9]|[5-8][0-9]|9[0-8])|7(0[0-9]|1[0-8]|2[0-7])|9(0[1-9]|[1-6][0-9]|7[0-8]))|16(5[2-9]|[6-7][0-9])|50(0[0-9]|1[0-9]|2[1-9]|[3-4][0-9]|5[0-8]))/
Se alguém tiver alguma lista de cartões Elo e puder compartilhar e testar, ficarei grato :)
De todos os testes que eu fiz com os regex dessa discussão, esse do diafrit foi o único que passou em todos testes que eu fiz para cartão ELO
regexr.com/5s4ov
Edit: aproveitei e deixei uma grande lista de cartões para teste
^(4011(78|79)|43(1274|8935)|45(1416|7393|763(1|2))|50(4175|6699|67[0-7][0-9]|9000)|50(9[0-9][0-9][0-9])|627780|63(6297|6368)|650(03([^4])|04([0-9])|05(0|1)|05([7-9])|06([0-9])|07([0-9])|08([0-9])|4([0-3][0-9]|8[5-9]|9[0-9])|5([0-9][0-9]|3[0-8])|9([0-6][0-9]|7[0-8])|7([0-2][0-9])|541|700|720|727|901)|65165([2-9])|6516([6-7][0-9])|65500([0-9])|6550([0-5][0-9])|655021|65505([6-7])|6516([8-9][0-9])|65170([0-4]))
Esse regex da Jumori funcionou igualmente bem ao do comentário anterior, passou em todos os testes.
Esse é de um aviso direto da Elo, me parece mais confiável.
Oi pessoal, o Regex da VISA e Elo citados acabam coincidindo pra esse número de cartão gerado: 4576329166124130, o que está me causando uma dor de cabeça pra pensar numa solução.
Gerei nesse site: https://www.vccgenerator.com/
Alguém tem o regex para Credz?
Alguém tem o regex para Credz?
Tecnicamente falando, é possível criar o regex para uma grande diversidade de cartões tendo por base o Número de Identificação do Emissor (IIN), também chamado de Número de Identificação Bancária (BIN). Isso significa que o reconhecimento da bandeira do cartão geralmente ocorre após inseridos os 4 ou 6 primeiros números desse cartão.
Eu não conheço o emissor do cartão em questão, mas creio que o BIN seja 6367 60XX XXXX XXXX. Se eu estiver correto, ou seja, se todos os cartões da Credz se iniciarem com os seis números citados acima, gerar um regex é tarefa bem simples, basta ver os exemplos acima.
Oi pessoal, o Regex da VISA e Elo citados acabam coincidindo pra esse número de cartão gerado: 4576329166124130, o que está me causando uma dor de cabeça pra pensar numa solução.
Gerei nesse site: https://www.vccgenerator.com/
Oi pessoal, o Regex da VISA e Elo citados acabam coincidindo pra esse número de cartão gerado: 4576329166124130, o que está me causando uma dor de cabeça pra pensar numa solução.
Gerei nesse site: https://www.vccgenerator.com/
Coincidências não deveriam ocorrer. Os emissores de cartões definem números de forma a não haver Coincidências. Provavelmente há algum conflito na formação de alguma das regex acima. Estou a muito tempo longe desse tipo de programação, não acho que eu teria expertise - ou paciência - para encontrar o conflito. Talvez alguém se disponibilize a fazê-lo. No entanto, se ninguém o fizer ou se o conflito persistir, você poderá tentar soluções alternativas. Uma delas é, em caso de um conflito, solicitar ao cliente que informe ele mesmo a bandeira do cartão. Pode não ser a solução ideal, mas nem tudo no mundo é...
Esse Regex já está levando em consideração a quantidade de dígitos?
(Pode ser que seja uma pergunta meio besta, mas não me aventuro muito em Regex, então as vezes me perco rsrs)
Efetuei Alguns testes e o padrão do Visa tbm valida o do Elo, esse é o padrão que utilizei para evitar isso, com um negativo lookahead do Elo.
^(?!504175|506699|5067|509|6500|6501|4011(78|79)|43(1274|8935)|45(1416|7393|763(1|2))|50(4175|6699|67[0-6][0-9]|677[0-8]|9[0-8][0-9]{2}|99[0-8][0-9]|999[0-9])|627780|63(6297|6368|6369)|65(0(0(3([1-3]|[5-9])|4([0-9])|5[0-1])|4(0[5-9]|[1-3][0-9]|8[5-9]|9[0-9])|5([0-2][0-9]|3[0-8]|4[1-9]|[5-8][0-9]|9[0-8])|7(0[0-9]|1[0-8]|2[0-7])|9(0[1-9]|[1-6][0-9]|7[0-8]))|16(5[2-9]|[6-7][0-9])|50(0[0-9]|1[0-9]|2[1-9]|[3-4][0-9]|5[0-8])))4[0-9]{12}(?:[0-9]{3})?$
realmente é grande, mas não acontece mais essa exceção.
Boa tarde, pessoal!
Estou precisando de uma ajuda pq tmb não tenho experiência em REGEX, esse que foi informado é para qual bandeira? E em suma, quais seriam para cada bandeira?
Efetuei Alguns testes e o padrão do Visa tbm valida o do Elo, esse é o padrão que utilizei para evitar isso, com um negativo lookahead do Elo.
^(?!504175|506699|5067|509|6500|6501|4011(78|79)|43(1274|8935)|45(1416|7393|763(1|2))|50(4175|6699|67[0-6][0-9]|677[0-8]|9[0-8][0-9]{2}|99[0-8][0-9]|999[0-9])|627780|63(6297|6368|6369)|65(0(0(3([1-3]|[5-9])|4([0-9])|5[0-1])|4(0[5-9]|[1-3][0-9]|8[5-9]|9[0-9])|5([0-2][0-9]|3[0-8]|4[1-9]|[5-8][0-9]|9[0-8])|7(0[0-9]|1[0-8]|2[0-7])|9(0[1-9]|[1-6][0-9]|7[0-8]))|16(5[2-9]|[6-7][0-9])|50(0[0-9]|1[0-9]|2[1-9]|[3-4][0-9]|5[0-8])))4[0-9]{12}(?:[0-9]{3})?$
realmente é grande, mas não acontece mais essa exceção.
@GianAlbino não, não está limitando a quantidade de caracteres.
@Fer-code talvez esteja um pouco desatualizado pois não tive mais tempo de vir aqui atualizar a postagem inicial, mas no início da thread eu separei os regex para cada bandeira.
Essa último post, foi relacionado ao Visa e Elo apenas, pelo que eu pude entender.
Ola pessoal, fiz as correcoes que vcs falaram. Porem percebi que HIPERCARD esta desatualizado. Por isso fiz um novo validando todos que estao nesse site: "https://bincheck.io/pt/br/itau-unibanco,-s.a./hipercard".
HIPERCARD ATUALIZADO: /^(606282\d{10}(\d{3})?)|(3841\d{12})|(637\d{13})$/
AO TODO:
'AMERICAN_EXPRESS': /^3[47]\d{13}$/,
'DINERS_CLUB': /^3(?:0[0-5]|[68]\d)\d{11}$/,
'ELO': /(4011|431274|438935|451416|457393|4576|457631|457632|504175|627780|636297|636368|636369|(6503[1-3])|(6500(3[5-9]|4[0-9]|5[0-1]))|(6504(0[5-9]|1[0-9]|2[0-9]|3[0-9]))|(650(48[5-9]|49[0-9]|50[0-9]|51[1-9]|52[0-9]|53[0-7]))|(6505(4[0-9]|5[0-9]|6[0-9]|7[0-9]|8[0-9]|9[0-8]))|(6507(0[0-9]|1[0-8]))|(6507(2[0-7]))|(650(90[1-9]|91[0-9]|920))|(6516(5[2-9]|6[0-9]|7[0-9]))|(6550(0[0-9]|1[1-9]))|(6550(2[1-9]|3[0-9]|4[0-9]|5[0-8]))|(506(699|77[0-8]|7[1-6][0-9))|(509([0-9][0-9][0-9])))/,
'HIPERCARD': /^(606282\d{10}(\d{3})?)|(3841\d{12})|(637\d{13})$/,
'MASTERCARD': /^5[1-5]\d{14}$|^2(?:2(?:2[1-9]|[3-9]\d)|[3-6]\d\d|7(?:[01]\d|20))\d{12}$/,
'VISA': /^(?!504175|506699|5067|509|6500|6501|4011(78|79)|43(1274|8935)|45(1416|7393|763(1|2))|50(4175|6699|67[0-6][0-9]|677[0-8]|9[0-8][0-9]{2}|99[0-8][0-9]|999[0-9])|627780|63(6297|6368|6369)|65(0(0(3([1-3]|[5-9])|4([0-9])|5[0-1])|4(0[5-9]|[1-3][0-9]|8[5-9]|9[0-9])|5([0-2][0-9]|3[0-8]|4[1-9]|[5-8][0-9]|9[0-8])|7(0[0-9]|1[0-8]|2[0-7])|9(0[1-9]|[1-6][0-9]|7[0-8]))|16(5[2-9]|[6-7][0-9])|50(0[0-9]|1[0-9]|2[1-9]|[3-4][0-9]|5[0-8])))4[0-9]{12}(?:[0-9]{3})?$/
@Fer-code , show de bola, ficou top viu, vou até utilizar kkk
@Fer-code , show de bola, ficou top viu, vou até utilizar kkk
Valeuuu! Mais atualizações vamos mandando ai :)
Boa tarde pessoal,
Minha pequena contribuição, segue uma lista com alguns cartões que estou colecionando de alguns provedores para teste.
const cards = {
// PagSeguro
// https://dev.pagbank.uol.com.br/reference/cartoes-de-teste
'4539620659922097': EnumCardBrand.VISA,
'4929291898380766': EnumCardBrand.VISA,
'5240082975622454': EnumCardBrand.MASTERCARD,
'5530062640663264': EnumCardBrand.MASTERCARD,
'345817690311361': EnumCardBrand.AMEX,
'372938001199778': EnumCardBrand.AMEX,
'4514161122113757': EnumCardBrand.ELO,
'4389350446134811': EnumCardBrand.ELO,
'6062828598919021': EnumCardBrand.HIPERCARD,
'6062822916014409': EnumCardBrand.HIPERCARD,
// https://dev.pagbank.uol.com.br/reference/criar-pagar-pedido-com-3ds-validacao-pagbank
'4000000000002701': EnumCardBrand.VISA,
'5200000000001005': EnumCardBrand.MASTERCARD,
'6505050000001000': EnumCardBrand.ELO,
'4000000000002503': EnumCardBrand.VISA,
'5200000000001096': EnumCardBrand.MASTERCARD,
'6505050000001091': EnumCardBrand.ELO,
'4000000000002925': EnumCardBrand.VISA,
'5200000000001013': EnumCardBrand.MASTERCARD,
'6505050000001018': EnumCardBrand.ELO,
'4000000000002370': EnumCardBrand.VISA,
'5200000000001104': EnumCardBrand.MASTERCARD,
'6505050000001109': EnumCardBrand.ELO,
// Mercado pago
// https://www.mercadopago.com.br/developers/pt/docs/checkout-api/additional-content/your-integrations/test/cards
'5067766783888311': EnumCardBrand.ELO,
'5031433215406351': EnumCardBrand.MASTERCARD,
'4235647728025682': EnumCardBrand.VISA,
'375365153556885': EnumCardBrand.AMEX,
// Gerados
// https://www.vccgenerator.org/
'5098176533461570': EnumCardBrand.ELO,
'5067349319312260': EnumCardBrand.ELO,
'5098193894226609': EnumCardBrand.ELO,
'5091084515027541': EnumCardBrand.ELO,
'5098177024386094': EnumCardBrand.ELO,
'4391395999142147': EnumCardBrand.VISA,
'4103922157715577': EnumCardBrand.VISA,
'4380208328771358': EnumCardBrand.VISA,
'4297672575052840': EnumCardBrand.VISA,
'4380277454970936': EnumCardBrand.VISA,
'5551555128049017': EnumCardBrand.MASTERCARD,
'5268003770982262': EnumCardBrand.MASTERCARD,
'5448382804657501': EnumCardBrand.MASTERCARD,
'5582852950163914': EnumCardBrand.MASTERCARD,
'5448384161742298': EnumCardBrand.MASTERCARD,
'340205640990176': EnumCardBrand.AMEX,
'340205958483061': EnumCardBrand.AMEX,
'340205254489929': EnumCardBrand.AMEX,
'340205493225258': EnumCardBrand.AMEX,
'340205571301401': EnumCardBrand.AMEX,
};
Implementei essa função em typescript e testei os cartões que o @MMortari mandou, alguns falharam:
export function getCardBrandName (cardNumber: string): string | null {
const numbers = cardNumber.replace(/[^0-9]+/g, '')
const cards = {
amex: /^3[47][0-9]{13}$/,
aura: /^((?!504175))^((?!5067))(^50[0-9])/,
banese_card: /^636117/,
cabal: /(60420[1-9]|6042[1-9][0-9]|6043[0-9]{2}|604400)/,
diners: /(36[0-8][0-9]{3}|369[0-8][0-9]{2}|3699[0-8][0-9]|36999[0-9])/,
discover: /^6(?:011|5[0-9]{2})[0-9]{12}/,
elo: /^4011(78|79)|^43(1274|8935)|^45(1416|7393|763(1|2))|^50(4175|6699|67[0-6][0-9]|677[0-8]|9[0-8][0-9]{2}|99[0-8][0-9]|999[0-9])|^627780|^63(6297|6368|6369)|^65(0(0(3([1-3]|[5-9])|4([0-9])|5[0-1])|4(0[5-9]|[1-3][0-9]|8[5-9]|9[0-9])|5([0-2][0-9]|3[0-8]|4[1-9]|[5-8][0-9]|9[0-8])|7(0[0-9]|1[0-8]|2[0-7])|9(0[1-9]|[1-6][0-9]|7[0-8]))|16(5[2-9]|[6-7][0-9])|50(0[0-9]|1[0-9]|2[1-9]|[3-4][0-9]|5[0-8]))/,
fort_brasil: /^628167/,
grand_card: /^605032/,
hipercard: /^606282|^3841(?:[0|4|6]{1})0/,
jbc: /^(?:2131|1800|35\d{3})\d{11}/,
mastercard: /^((5(([1-2]|[4-5])[0-9]{8}|0((1|6)([0-9]{7}))|3(0(4((0|[2-9])[0-9]{5})|([0-3]|[5-9])[0-9]{6})|[1-9][0-9]{7})))|((508116)\\d{4,10})|((502121)\\d{4,10})|((589916)\\d{4,10})|(2[0-9]{15})|(67[0-9]{14})|(506387)\\d{4,10})/,
personal_card: /^636085/,
sorocred: /^627892|^636414/,
valecard: /^606444|^606458|^606482/,
visa: /^4[0-9]{15}$/
}
const match = Object.entries(cards).find(([_, value]) => {
if (value.test(numbers)) {
return true
}
return false
})
if (match) {
return match[0]
}
return null
}
6505050000001000: Esperado: Elo. Resultado: Discover
6505050000001091: Esperado: Elo. Resultado: Discover
6505050000001018: Esperado: Elo. Resultado: Discover
6505050000001109: Esperado: Elo. Resultado: Discover
5031433215406351: Esperado: Mastercard. Resultado: Aura
5098176533461570: Esperado: Elo. Resultado: Aura
5098193894226609: Esperado: Elo. Resultado: Aura
5091084515027541: Esperado: Elo. Resultado: Aura
5098177024386094: Esperado: Elo. Resultado: Aura
Comlementando, os cartões que deram errado passam na REGEX da bandeira esperada, mas também passam na da Discover/Aura. Eu comentei essas duas bandeiras e a maioria passou, só o 5031433215406351 que não está passando na REGEX do mastercard
Implementei essa função em typescript e testei os cartões que o @MMortari mandou, alguns falharam:
export function getCardBrandName (cardNumber: string): string | null { const numbers = cardNumber.replace(/[^0-9]+/g, '') const cards = { amex: /^3[47][0-9]{13}$/, aura: /^((?!504175))^((?!5067))(^50[0-9])/, banese_card: /^636117/, cabal: /(60420[1-9]|6042[1-9][0-9]|6043[0-9]{2}|604400)/, diners: /(36[0-8][0-9]{3}|369[0-8][0-9]{2}|3699[0-8][0-9]|36999[0-9])/, discover: /^6(?:011|5[0-9]{2})[0-9]{12}/, elo: /^4011(78|79)|^43(1274|8935)|^45(1416|7393|763(1|2))|^50(4175|6699|67[0-6][0-9]|677[0-8]|9[0-8][0-9]{2}|99[0-8][0-9]|999[0-9])|^627780|^63(6297|6368|6369)|^65(0(0(3([1-3]|[5-9])|4([0-9])|5[0-1])|4(0[5-9]|[1-3][0-9]|8[5-9]|9[0-9])|5([0-2][0-9]|3[0-8]|4[1-9]|[5-8][0-9]|9[0-8])|7(0[0-9]|1[0-8]|2[0-7])|9(0[1-9]|[1-6][0-9]|7[0-8]))|16(5[2-9]|[6-7][0-9])|50(0[0-9]|1[0-9]|2[1-9]|[3-4][0-9]|5[0-8]))/, fort_brasil: /^628167/, grand_card: /^605032/, hipercard: /^606282|^3841(?:[0|4|6]{1})0/, jbc: /^(?:2131|1800|35\d{3})\d{11}/, mastercard: /^((5(([1-2]|[4-5])[0-9]{8}|0((1|6)([0-9]{7}))|3(0(4((0|[2-9])[0-9]{5})|([0-3]|[5-9])[0-9]{6})|[1-9][0-9]{7})))|((508116)\\d{4,10})|((502121)\\d{4,10})|((589916)\\d{4,10})|(2[0-9]{15})|(67[0-9]{14})|(506387)\\d{4,10})/, personal_card: /^636085/, sorocred: /^627892|^636414/, valecard: /^606444|^606458|^606482/, visa: /^4[0-9]{15}$/ } const match = Object.entries(cards).find(([_, value]) => { if (value.test(numbers)) { return true } return false }) if (match) { return match[0] } return null }6505050000001000: Esperado: Elo. Resultado: Discover 6505050000001091: Esperado: Elo. Resultado: Discover 6505050000001018: Esperado: Elo. Resultado: Discover 6505050000001109: Esperado: Elo. Resultado: Discover 5031433215406351: Esperado: Mastercard. Resultado: Aura 5098176533461570: Esperado: Elo. Resultado: Aura 5098193894226609: Esperado: Elo. Resultado: Aura 5091084515027541: Esperado: Elo. Resultado: Aura 5098177024386094: Esperado: Elo. Resultado: Aura
Interessante esse comportamento, vou fazer alguns testes aqui e quem sabe com um negative lookahead ele funcione corretamente, posteriormente comentarei com um retorno ...
Comlementando, os cartões que deram errado passam na REGEX da bandeira esperada, mas também passam na da Discover/Aura. Eu comentei essas duas bandeiras e a maioria passou, só o 5031433215406351 que não está passando na REGEX do mastercard
Isso acontece porque o padrão desses cartões ELO realmente batem com o padrão da discover, porém por algum motivo a caixa registrou o BIN antes (não sei como funciona esses registros de BIN). Essas exceções já estão no regex da elo, podemos ver na parte "|6505[0-2][0-9]". Se jogarmos no bincheck.io inicialmente ele também da discover, mas se fizer o POST pra verificar ele irá retornar elo.
pra resolver podemos criar um switch e dar break antes para não continuar a verificação, e sempre verificar o ELO primeiro. Um exemplo em PHP
$bandeira = match (1) {
preg_match(
'/^4011(78|79)|^43(1274|8935)|^45(1416|7393|763(1|2))|^504175|^627780|^63(6297|6368|6369)|(65003[5-9]|65004[0-9]|65005[01])|(65040[5-9]|6504[1-3][0-9])|(65048[5-9]|65049[0-9]|6505[0-2][0-9]|65053[0-8])|(65054[1-9]|6505[5-8][0-9]|65059[0-8])|(65070[0-9]|65071[0-8])|(65072[0-7])|(65090[1-9]|6509[1-6][0-9]|65097[0-8])|(65165[2-9]|6516[67][0-9])|(65500[0-9]|65501[0-9])|(65502[1-9]|6550[34][0-9]|65505[0-8])|^(506699|5067[0-6][0-9]|50677[0-8])|^(509[0-8][0-9]{2}|5099[0-8][0-9]|50999[0-9])|^65003[1-3]|^(65003[5-9]|65004\d|65005[0-1])|^(65040[5-9]|6504[1-3]\d)|^(65048[5-9]|65049\d|6505[0-2]\d|65053[0-8])|^(65054[1-9]|6505[5-8]\d|65059[0-8])|^(65070\d|65071[0-8])|^65072[0-7]|^(65090[1-9]|65091\d|650920)|^(65165[2-9]|6516[6-7]\d)|^(65500\d|65501\d)|^(65502[1-9]|6550[3-4]\d|65505[0-8])/',
$cartaoNumero
) => 'elo',
preg_match('/^4[0-9]{12}(?:[0-9]{3})?/', $cartaoNumero) => 'visa',
preg_match('/^((5(([1-2]|[4-5])[0-9]{8}|0((1|6)([0-9]{7}))|3(0(4((0|[2-9])[0-9]{5})|([0-3]|[5-9])[0-9]{6})|[1-9][0-9]{7})))|((508116)\\d{4,10})|((502121)\\d{4,10})|((589916)\\d{4,10})|(2[0-9]{15})|(67[0-9]{14})|(506387)\\d{4,10})/', $cartaoNumero) => 'mastercard',
preg_match('/^3[47][0-9]{13}/', $cartaoNumero) => 'amexs',
preg_match('/^65[4-9][0-9]{13}|64[4-9][0-9]{13}|6011[0-9]{12}|(622(?:12[6-9]|1[3-9][0-9]|[2-8][0-9][0-9]|9[01][0-9]|92[0-5])[0-9]{10})/', $cartaoNumero) => 'discover',
preg_match('/^3(?:0[0-5]|[68][0-9])[0-9]{11}/', $cartaoNumero) => 'diners',
preg_match('/^(?:2131|1800|35\d{3})\d{11}/', $cartaoNumero) => 'jcb',
preg_match('/^(606282\d{10}(\d{3})?)|(3841\d{12})|(637\d{13})/', $cartaoNumero) => 'hipercard',
default => ''
};
Agora todos os números vão bater corretamente!
Esta bandeira 5031433215406351 no bincheck.io deu que não existe, então pode ser retirada.
Eu pequei os cartões dessa resposta do @MMortari :
Boa tarde pessoal,
Minha pequena contribuição, segue uma lista com alguns cartões que estou colecionando de alguns provedores para teste.
const cards = { // PagSeguro // https://dev.pagbank.uol.com.br/reference/cartoes-de-teste '4539620659922097': EnumCardBrand.VISA, '4929291898380766': EnumCardBrand.VISA, '5240082975622454': EnumCardBrand.MASTERCARD, '5530062640663264': EnumCardBrand.MASTERCARD, '345817690311361': EnumCardBrand.AMEX, '372938001199778': EnumCardBrand.AMEX, '4514161122113757': EnumCardBrand.ELO, '4389350446134811': EnumCardBrand.ELO, '6062828598919021': EnumCardBrand.HIPERCARD, '6062822916014409': EnumCardBrand.HIPERCARD, // https://dev.pagbank.uol.com.br/reference/criar-pagar-pedido-com-3ds-validacao-pagbank '4000000000002701': EnumCardBrand.VISA, '5200000000001005': EnumCardBrand.MASTERCARD, '6505050000001000': EnumCardBrand.ELO, '4000000000002503': EnumCardBrand.VISA, '5200000000001096': EnumCardBrand.MASTERCARD, '6505050000001091': EnumCardBrand.ELO, '4000000000002925': EnumCardBrand.VISA, '5200000000001013': EnumCardBrand.MASTERCARD, '6505050000001018': EnumCardBrand.ELO, '4000000000002370': EnumCardBrand.VISA, '5200000000001104': EnumCardBrand.MASTERCARD, '6505050000001109': EnumCardBrand.ELO, // Mercado pago // https://www.mercadopago.com.br/developers/pt/docs/checkout-api/additional-content/your-integrations/test/cards '5067766783888311': EnumCardBrand.ELO, '5031433215406351': EnumCardBrand.MASTERCARD, '4235647728025682': EnumCardBrand.VISA, '375365153556885': EnumCardBrand.AMEX, // Gerados // https://www.vccgenerator.org/ '5098176533461570': EnumCardBrand.ELO, '5067349319312260': EnumCardBrand.ELO, '5098193894226609': EnumCardBrand.ELO, '5091084515027541': EnumCardBrand.ELO, '5098177024386094': EnumCardBrand.ELO, '4391395999142147': EnumCardBrand.VISA, '4103922157715577': EnumCardBrand.VISA, '4380208328771358': EnumCardBrand.VISA, '4297672575052840': EnumCardBrand.VISA, '4380277454970936': EnumCardBrand.VISA, '5551555128049017': EnumCardBrand.MASTERCARD, '5268003770982262': EnumCardBrand.MASTERCARD, '5448382804657501': EnumCardBrand.MASTERCARD, '5582852950163914': EnumCardBrand.MASTERCARD, '5448384161742298': EnumCardBrand.MASTERCARD, '340205640990176': EnumCardBrand.AMEX, '340205958483061': EnumCardBrand.AMEX, '340205254489929': EnumCardBrand.AMEX, '340205493225258': EnumCardBrand.AMEX, '340205571301401': EnumCardBrand.AMEX, };
E usei os regex da última resposta, conforme o @gfucci colocou em sua resposta:
Comlementando, os cartões que deram errado passam na REGEX da bandeira esperada, mas também passam na da Discover/Aura. Eu comentei essas duas bandeiras e a maioria passou, só o 5031433215406351 que não está passando na REGEX do mastercard
Isso acontece porque o padrão desses cartões ELO realmente batem com o padrão da discover, porém por algum motivo a caixa registrou o BIN antes (não sei como funciona esses registros de BIN). Essas exceções já estão no regex da elo, podemos ver na parte "|6505[0-2][0-9]". Se jogarmos no bincheck.io inicialmente ele também da discover, mas se fizer o POST pra verificar ele irá retornar elo.
pra resolver podemos criar um switch e dar break antes para não continuar a verificação, e sempre verificar o ELO primeiro. Um exemplo em PHP
$bandeira = match (1) { preg_match( '/^4011(78|79)|^43(1274|8935)|^45(1416|7393|763(1|2))|^504175|^627780|^63(6297|6368|6369)|(65003[5-9]|65004[0-9]|65005[01])|(65040[5-9]|6504[1-3][0-9])|(65048[5-9]|65049[0-9]|6505[0-2][0-9]|65053[0-8])|(65054[1-9]|6505[5-8][0-9]|65059[0-8])|(65070[0-9]|65071[0-8])|(65072[0-7])|(65090[1-9]|6509[1-6][0-9]|65097[0-8])|(65165[2-9]|6516[67][0-9])|(65500[0-9]|65501[0-9])|(65502[1-9]|6550[34][0-9]|65505[0-8])|^(506699|5067[0-6][0-9]|50677[0-8])|^(509[0-8][0-9]{2}|5099[0-8][0-9]|50999[0-9])|^65003[1-3]|^(65003[5-9]|65004\d|65005[0-1])|^(65040[5-9]|6504[1-3]\d)|^(65048[5-9]|65049\d|6505[0-2]\d|65053[0-8])|^(65054[1-9]|6505[5-8]\d|65059[0-8])|^(65070\d|65071[0-8])|^65072[0-7]|^(65090[1-9]|65091\d|650920)|^(65165[2-9]|6516[6-7]\d)|^(65500\d|65501\d)|^(65502[1-9]|6550[3-4]\d|65505[0-8])/', $cartaoNumero ) => 'elo', preg_match('/^4[0-9]{12}(?:[0-9]{3})?/', $cartaoNumero) => 'visa', preg_match('/^((5(([1-2]|[4-5])[0-9]{8}|0((1|6)([0-9]{7}))|3(0(4((0|[2-9])[0-9]{5})|([0-3]|[5-9])[0-9]{6})|[1-9][0-9]{7})))|((508116)\\d{4,10})|((502121)\\d{4,10})|((589916)\\d{4,10})|(2[0-9]{15})|(67[0-9]{14})|(506387)\\d{4,10})/', $cartaoNumero) => 'mastercard', preg_match('/^3[47][0-9]{13}/', $cartaoNumero) => 'amexs', preg_match('/^65[4-9][0-9]{13}|64[4-9][0-9]{13}|6011[0-9]{12}|(622(?:12[6-9]|1[3-9][0-9]|[2-8][0-9][0-9]|9[01][0-9]|92[0-5])[0-9]{10})/', $cartaoNumero) => 'discover', preg_match('/^3(?:0[0-5]|[68][0-9])[0-9]{11}/', $cartaoNumero) => 'diners', preg_match('/^(?:2131|1800|35\d{3})\d{11}/', $cartaoNumero) => 'jcb', preg_match('/^(606282\d{10}(\d{3})?)|(3841\d{12})|(637\d{13})/', $cartaoNumero) => 'hipercard', default => '' };
Agora todos os números vão bater corretamente!
Esta bandeira 5031433215406351 no bincheck.io deu que não existe, então pode ser retirada.
Aparentemente está falhando para alguns ainda... Olha o resultado que eu tive:
Comlementando, os cartões que deram errado passam na REGEX da bandeira esperada, mas também passam na da Discover/Aura. Eu comentei essas duas bandeiras e a maioria passou, só o 5031433215406351 que não está passando na REGEX do mastercard
Isso acontece porque o padrão desses cartões ELO realmente batem com o padrão da discover, porém por algum motivo a caixa registrou o BIN antes (não sei como funciona esses registros de BIN). Essas exceções já estão no regex da elo, podemos ver na parte "|6505[0-2][0-9]". Se jogarmos no bincheck.io inicialmente ele também da discover, mas se fizer o POST pra verificar ele irá retornar elo.
pra resolver podemos criar um switch e dar break antes para não continuar a verificação, e sempre verificar o ELO primeiro. Um exemplo em PHP
$bandeira = match (1) { preg_match( '/^4011(78|79)|^43(1274|8935)|^45(1416|7393|763(1|2))|^504175|^627780|^63(6297|6368|6369)|(65003[5-9]|65004[0-9]|65005[01])|(65040[5-9]|6504[1-3][0-9])|(65048[5-9]|65049[0-9]|6505[0-2][0-9]|65053[0-8])|(65054[1-9]|6505[5-8][0-9]|65059[0-8])|(65070[0-9]|65071[0-8])|(65072[0-7])|(65090[1-9]|6509[1-6][0-9]|65097[0-8])|(65165[2-9]|6516[67][0-9])|(65500[0-9]|65501[0-9])|(65502[1-9]|6550[34][0-9]|65505[0-8])|^(506699|5067[0-6][0-9]|50677[0-8])|^(509[0-8][0-9]{2}|5099[0-8][0-9]|50999[0-9])|^65003[1-3]|^(65003[5-9]|65004\d|65005[0-1])|^(65040[5-9]|6504[1-3]\d)|^(65048[5-9]|65049\d|6505[0-2]\d|65053[0-8])|^(65054[1-9]|6505[5-8]\d|65059[0-8])|^(65070\d|65071[0-8])|^65072[0-7]|^(65090[1-9]|65091\d|650920)|^(65165[2-9]|6516[6-7]\d)|^(65500\d|65501\d)|^(65502[1-9]|6550[3-4]\d|65505[0-8])/', $cartaoNumero ) => 'elo', preg_match('/^4[0-9]{12}(?:[0-9]{3})?/', $cartaoNumero) => 'visa', preg_match('/^((5(([1-2]|[4-5])[0-9]{8}|0((1|6)([0-9]{7}))|3(0(4((0|[2-9])[0-9]{5})|([0-3]|[5-9])[0-9]{6})|[1-9][0-9]{7})))|((508116)\\d{4,10})|((502121)\\d{4,10})|((589916)\\d{4,10})|(2[0-9]{15})|(67[0-9]{14})|(506387)\\d{4,10})/', $cartaoNumero) => 'mastercard', preg_match('/^3[47][0-9]{13}/', $cartaoNumero) => 'amexs', preg_match('/^65[4-9][0-9]{13}|64[4-9][0-9]{13}|6011[0-9]{12}|(622(?:12[6-9]|1[3-9][0-9]|[2-8][0-9][0-9]|9[01][0-9]|92[0-5])[0-9]{10})/', $cartaoNumero) => 'discover', preg_match('/^3(?:0[0-5]|[68][0-9])[0-9]{11}/', $cartaoNumero) => 'diners', preg_match('/^(?:2131|1800|35\d{3})\d{11}/', $cartaoNumero) => 'jcb', preg_match('/^(606282\d{10}(\d{3})?)|(3841\d{12})|(637\d{13})/', $cartaoNumero) => 'hipercard', default => '' };
Agora todos os números vão bater corretamente!
Esta bandeira 5031433215406351 no bincheck.io deu que não existe, então pode ser retirada.
Opa, consegui fazer funcionar. Só joguei a linha do elo para ser a primeira regex para checar e funcionou em todos (após remover o 5031433215406351)
Segue o código completo:
export function getCardBrandName (cardNumber: string): string | null {
const numbers = cardNumber.replace(/[^0-9]+/g, '')
const brands = {
elo: /^4011(78|79)|^43(1274|8935)|^45(1416|7393|763(1|2))|^50(4175|6699|67[0-6][0-9]|677[0-8]|9[0-8][0-9]{2}|99[0-8][0-9]|999[0-9])|^627780|^63(6297|6368|6369)|^65(0(0(3([1-3]|[5-9])|4([0-9])|5[0-1])|4(0[5-9]|[1-3][0-9]|8[5-9]|9[0-9])|5([0-2][0-9]|3[0-8]|4[1-9]|[5-8][0-9]|9[0-8])|7(0[0-9]|1[0-8]|2[0-7])|9(0[1-9]|[1-6][0-9]|7[0-8]))|16(5[2-9]|[6-7][0-9])|50(0[0-9]|1[0-9]|2[1-9]|[3-4][0-9]|5[0-8]))/,
amex: /^3[47][0-9]{13}$/,
aura: /^((?!504175))^((?!5067))(^50[0-9])/,
banese_card: /^636117/,
cabal: /(60420[1-9]|6042[1-9][0-9]|6043[0-9]{2}|604400)/,
diners: /(36[0-8][0-9]{3}|369[0-8][0-9]{2}|3699[0-8][0-9]|36999[0-9])/,
discover: /^6(?:011|5[0-9]{2})[0-9]{12}/,
fort_brasil: /^628167/,
grand_card: /^605032/,
hipercard: /^606282|^3841(?:[0|4|6]{1})0/,
jbc: /^(?:2131|1800|35\d{3})\d{11}/,
mastercard: /^((5(([1-2]|[4-5])[0-9]{8}|0((1|6)([0-9]{7}))|3(0(4((0|[2-9])[0-9]{5})|([0-3]|[5-9])[0-9]{6})|[1-9][0-9]{7})))|((508116)\\d{4,10})|((502121)\\d{4,10})|((589916)\\d{4,10})|(2[0-9]{15})|(67[0-9]{14})|(506387)\\d{4,10})/,
personal_card: /^636085/,
sorocred: /^627892|^636414/,
valecard: /^606444|^606458|^606482/,
visa: /^4[0-9]{15}$/
}
const match = Object.entries(brands).find(([_, value]) => {
if (value.test(numbers)) {
return true
}
return false
})
if (match) {
return match[0]
}
return null
}
const cards = {
// PagSeguro
// https://dev.pagbank.uol.com.br/reference/cartoes-de-teste
'4539620659922097': 'visa',
'4929291898380766': 'visa',
'5240082975622454': 'mastercard',
'5530062640663264': 'mastercard',
'345817690311361': 'amex',
'372938001199778': 'amex',
'4514161122113757': 'elo',
'4389350446134811': 'elo',
'6062828598919021': 'hipercard',
'6062822916014409': 'hipercard',
// https://dev.pagbank.uol.com.br/reference/criar-pagar-pedido-com-3ds-validacao-pagbank
'4000000000002701': 'visa',
'5200000000001005': 'mastercard',
'6505050000001000': 'elo',
'4000000000002503': 'visa',
'5200000000001096': 'mastercard',
'6505050000001091': 'elo',
'4000000000002925': 'visa',
'5200000000001013': 'mastercard',
'6505050000001018': 'elo',
'4000000000002370': 'visa',
'5200000000001104': 'mastercard',
'6505050000001109': 'elo',
// Mercado pago
// https://www.mercadopago.com.br/developers/pt/docs/checkout-api/additional-content/your-integrations/test/cards
'5067766783888311': 'elo',
'4235647728025682': 'visa',
'375365153556885': 'amex',
// Gerados
// https://www.vccgenerator.org/
'5098176533461570': 'elo',
'5067349319312260': 'elo',
'5098193894226609': 'elo',
'5091084515027541': 'elo',
'5098177024386094': 'elo',
'4391395999142147': 'visa',
'4103922157715577': 'visa',
'4380208328771358': 'visa',
'4297672575052840': 'visa',
'4380277454970936': 'visa',
'5551555128049017': 'mastercard',
'5268003770982262': 'mastercard',
'5448382804657501': 'mastercard',
'5582852950163914': 'mastercard',
'5448384161742298': 'mastercard',
'340205640990176': 'amex',
'340205958483061': 'amex',
'340205254489929': 'amex',
'340205493225258': 'amex',
'340205571301401': 'amex',
};
for (const card in cards) {
const expectedBrand = cards[card]
const calculatedBrand = getCardBrandName(card)
if (expectedBrand == calculatedBrand) {
console.log(`${card} OK`)
} else {
console.log(`${card} ERROR. Expected ${expectedBrand}, got ${calculatedBrand}`)
}
}
Eu pequei os cartões dessa resposta do @MMortari :
Boa tarde pessoal,
Minha pequena contribuição, segue uma lista com alguns cartões que estou colecionando de alguns provedores para teste.const cards = { // PagSeguro // https://dev.pagbank.uol.com.br/reference/cartoes-de-teste '4539620659922097': EnumCardBrand.VISA, '4929291898380766': EnumCardBrand.VISA, '5240082975622454': EnumCardBrand.MASTERCARD, '5530062640663264': EnumCardBrand.MASTERCARD, '345817690311361': EnumCardBrand.AMEX, '372938001199778': EnumCardBrand.AMEX, '4514161122113757': EnumCardBrand.ELO, '4389350446134811': EnumCardBrand.ELO, '6062828598919021': EnumCardBrand.HIPERCARD, '6062822916014409': EnumCardBrand.HIPERCARD, // https://dev.pagbank.uol.com.br/reference/criar-pagar-pedido-com-3ds-validacao-pagbank '4000000000002701': EnumCardBrand.VISA, '5200000000001005': EnumCardBrand.MASTERCARD, '6505050000001000': EnumCardBrand.ELO, '4000000000002503': EnumCardBrand.VISA, '5200000000001096': EnumCardBrand.MASTERCARD, '6505050000001091': EnumCardBrand.ELO, '4000000000002925': EnumCardBrand.VISA, '5200000000001013': EnumCardBrand.MASTERCARD, '6505050000001018': EnumCardBrand.ELO, '4000000000002370': EnumCardBrand.VISA, '5200000000001104': EnumCardBrand.MASTERCARD, '6505050000001109': EnumCardBrand.ELO, // Mercado pago // https://www.mercadopago.com.br/developers/pt/docs/checkout-api/additional-content/your-integrations/test/cards '5067766783888311': EnumCardBrand.ELO, '5031433215406351': EnumCardBrand.MASTERCARD, '4235647728025682': EnumCardBrand.VISA, '375365153556885': EnumCardBrand.AMEX, // Gerados // https://www.vccgenerator.org/ '5098176533461570': EnumCardBrand.ELO, '5067349319312260': EnumCardBrand.ELO, '5098193894226609': EnumCardBrand.ELO, '5091084515027541': EnumCardBrand.ELO, '5098177024386094': EnumCardBrand.ELO, '4391395999142147': EnumCardBrand.VISA, '4103922157715577': EnumCardBrand.VISA, '4380208328771358': EnumCardBrand.VISA, '4297672575052840': EnumCardBrand.VISA, '4380277454970936': EnumCardBrand.VISA, '5551555128049017': EnumCardBrand.MASTERCARD, '5268003770982262': EnumCardBrand.MASTERCARD, '5448382804657501': EnumCardBrand.MASTERCARD, '5582852950163914': EnumCardBrand.MASTERCARD, '5448384161742298': EnumCardBrand.MASTERCARD, '340205640990176': EnumCardBrand.AMEX, '340205958483061': EnumCardBrand.AMEX, '340205254489929': EnumCardBrand.AMEX, '340205493225258': EnumCardBrand.AMEX, '340205571301401': EnumCardBrand.AMEX, };E usei os regex da última resposta, conforme o @gfucci colocou em sua resposta:
Comlementando, os cartões que deram errado passam na REGEX da bandeira esperada, mas também passam na da Discover/Aura. Eu comentei essas duas bandeiras e a maioria passou, só o 5031433215406351 que não está passando na REGEX do mastercard
Isso acontece porque o padrão desses cartões ELO realmente batem com o padrão da discover, porém por algum motivo a caixa registrou o BIN antes (não sei como funciona esses registros de BIN). Essas exceções já estão no regex da elo, podemos ver na parte "|6505[0-2][0-9]". Se jogarmos no bincheck.io inicialmente ele também da discover, mas se fizer o POST pra verificar ele irá retornar elo.
pra resolver podemos criar um switch e dar break antes para não continuar a verificação, e sempre verificar o ELO primeiro. Um exemplo em PHP$bandeira = match (1) { preg_match( '/^4011(78|79)|^43(1274|8935)|^45(1416|7393|763(1|2))|^504175|^627780|^63(6297|6368|6369)|(65003[5-9]|65004[0-9]|65005[01])|(65040[5-9]|6504[1-3][0-9])|(65048[5-9]|65049[0-9]|6505[0-2][0-9]|65053[0-8])|(65054[1-9]|6505[5-8][0-9]|65059[0-8])|(65070[0-9]|65071[0-8])|(65072[0-7])|(65090[1-9]|6509[1-6][0-9]|65097[0-8])|(65165[2-9]|6516[67][0-9])|(65500[0-9]|65501[0-9])|(65502[1-9]|6550[34][0-9]|65505[0-8])|^(506699|5067[0-6][0-9]|50677[0-8])|^(509[0-8][0-9]{2}|5099[0-8][0-9]|50999[0-9])|^65003[1-3]|^(65003[5-9]|65004\d|65005[0-1])|^(65040[5-9]|6504[1-3]\d)|^(65048[5-9]|65049\d|6505[0-2]\d|65053[0-8])|^(65054[1-9]|6505[5-8]\d|65059[0-8])|^(65070\d|65071[0-8])|^65072[0-7]|^(65090[1-9]|65091\d|650920)|^(65165[2-9]|6516[6-7]\d)|^(65500\d|65501\d)|^(65502[1-9]|6550[3-4]\d|65505[0-8])/', $cartaoNumero ) => 'elo', preg_match('/^4[0-9]{12}(?:[0-9]{3})?/', $cartaoNumero) => 'visa', preg_match('/^((5(([1-2]|[4-5])[0-9]{8}|0((1|6)([0-9]{7}))|3(0(4((0|[2-9])[0-9]{5})|([0-3]|[5-9])[0-9]{6})|[1-9][0-9]{7})))|((508116)\\d{4,10})|((502121)\\d{4,10})|((589916)\\d{4,10})|(2[0-9]{15})|(67[0-9]{14})|(506387)\\d{4,10})/', $cartaoNumero) => 'mastercard', preg_match('/^3[47][0-9]{13}/', $cartaoNumero) => 'amexs', preg_match('/^65[4-9][0-9]{13}|64[4-9][0-9]{13}|6011[0-9]{12}|(622(?:12[6-9]|1[3-9][0-9]|[2-8][0-9][0-9]|9[01][0-9]|92[0-5])[0-9]{10})/', $cartaoNumero) => 'discover', preg_match('/^3(?:0[0-5]|[68][0-9])[0-9]{11}/', $cartaoNumero) => 'diners', preg_match('/^(?:2131|1800|35\d{3})\d{11}/', $cartaoNumero) => 'jcb', preg_match('/^(606282\d{10}(\d{3})?)|(3841\d{12})|(637\d{13})/', $cartaoNumero) => 'hipercard', default => '' };
Agora todos os números vão bater corretamente!
Esta bandeira 5031433215406351 no bincheck.io deu que não existe, então pode ser retirada.Aparentemente está falhando para alguns ainda... Olha o resultado que eu tive:
Qual código você tá usando?
No meu exemplo em TypeScript funcionou todos os cartões
Vou deixar minha contribuição de expressões regulares, se alguém quiser se disponibilizar a deixá-la mais completa, fico grato:
Todas as bandeiras acima são atualmente utilizadas pelo gateway da PagSeguro. Sim, sim, o Regex da ELO é gigantesco, talvez haja alguma forma de reduzi-lo, entretanto, em todos os testes que eu fiz ele passou.