-
-
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}$ |
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 ...
Valeuuu! Mais atualizações vamos mandando ai :)