Skip to content

Instantly share code, notes, and snippets.

@gusribeiro
Last active April 26, 2024 21:10
Show Gist options
  • Star 99 You must be signed in to star a gist
  • Fork 17 You must be signed in to fork a gist
  • Save gusribeiro/263a165db774f5d78251 to your computer and use it in GitHub Desktop.
Save gusribeiro/263a165db774f5d78251 to your computer and use it in GitHub Desktop.
Regex para identificar bandeiras do cartão de crédito
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}$
@IkaroFox
Copy link

IkaroFox commented Nov 15, 2023

@Fer-code , show de bola, ficou top viu, vou até utilizar kkk

image

@Fer-code
Copy link

@Fer-code , show de bola, ficou top viu, vou até utilizar kkk

image

Valeuuu! Mais atualizações vamos mandando ai :)

@MMortari
Copy link

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

@GabrielLasso
Copy link

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

@GabrielLasso
Copy link

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

@IkaroFox
Copy link

IkaroFox commented Apr 5, 2024

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 ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment