Tokenização de Cartão via JS

Nosso checkout.js é uma biblioteca JS que criptografa os dados do cartão do comprador para transacioná-los sempre de forma segura.

O uso da nossa biblioteca consiste em enviar os dados do cartão diretamente pelo navegador do cliente (Client-side) sem passar, assim, nenhum dado sensível em texto plano pelo seu servidor.

Ao final do processo, é devolvido um hash temporário de identificação único, que será utilizada posteriormente nos endpoints que aceitam dados de cartão.

❗️

Atenção: O hash do cartão é temporário. Cada cartão tokenizado tem um tempo de expiração de 5 minutos. Caso o cartão não seja utilizado nesse intervalo, deverá ser gerada um novo hash.

Para obter o seu cartão tokenizado, você deve seguir o seguintes passos:

Inclusão no projeto

  1. Incluir a biblioteca na página através do script: https://js.cel.cash/checkout-v2.min.js
<script type="text/javascript" src="https://js.cel.cash/checkout-v2.min.js"></script>

  1. Instanciar BaasCard definindo o ambiente (sandbox ou produção).
  2. Carregar a chave pública RSA do ambiente com _setPublicKey().
  3. Criar um Card com os dados brutos do cartão.
  4. Validar os campos (validate e validadores específicos).
  5. Criptografar o cartão com a chave pública (encrypt) e enviar o token resultante ao backend.

Classe BaasCard

Cria uma instância configurada para o ambiente desejado.

const baasCard = new BaasCard(false); // sandbox
const baasCard = new BaasCard(true);  // produção

await baasCard._setPublicKey()

Busca a chave pública RSA no endpoint do ambiente e a armazena em baasCard._publicKey como string base64 (PEM).

await baasCard._setPublicKey();
console.log(baasCard._publicKey); // string base64 da chave pública

Boas práticas: chame _setPublicKey() o mais cedo possível no lifecycle da página (ex.: DOMContentLoaded) para já ter a chave carregada quando o usuário submeter o formulário.

Cria uma instância de Card a partir dos dados informados.

baasCard.newCard(data)

Cria uma instância de Card a partir dos dados informados.

const card = baasCard.newCard({
  number: '4111111111111111',
  holder: 'JOAO DA SILVA',
  expiresAt: '2027-08',
  cvv: '123'
});

card.validate()

Valida todos os campos do cartão. Lança Error se algum campo for inválido.

try {
  card.validate();
} catch (e) {
  console.error(e.message);
}

card.checkNumber(number)

Valida o número do cartão pelo algoritmo de Luhn. Retorna true ou lança Error.

card.checkNumber('4111111111111111'); // true ou Error

card.checkExpiresDate(expiresAt)

card.checkExpiresDate('2027-08'); // true ou Error

card.checkCvv(cvv)

Valida o CVV (3 ou 4 dígitos). Retorna true ou lança Error.

card.checkCvv('123'); // true ou Error

card.encrypt(publicKey)

Criptografa os dados do cartão com a chave pública RSA usando node-forge.

const encrypted = card.encrypt(publicKeyPem);
console.log(encrypted);

Sobre o token: o valor retornado por encrypt é um blob base64 que representa os campos sensíveis criptografados. Este token deve ser enviado ao backend, que fará a descriptografia/validação junto ao provedor Baas.

Exemplo completo

(async () => {
  // 1. Instanciar BaasCard
  const baasCard = new BaasCard(false); // false = sandbox

  // 2. Buscar a chave pública
  await baasCard._setPublicKey();

  // 3. Criar o cartão
  const card = baasCard.newCard({
    number: '4111111111111111',
    holder: 'JOAO DA SILVA',
    expiresAt: '2027-08',
    cvv: '123'
  });

  // 4. Validar
  try {
    card.validate();
  } catch (e) {
    console.error('Cartão inválido:', e.message);
    return;
  }

  // 5. Criptografar
  const encrypted = card.encrypt(baasCard._publicKey);
  console.log('Token:', encrypted);
})();

Observações:

  • A geração do token utiliza única e exclusivamente o publicToken já fornecido pela biblioteca, não sendo necessário qualquer outra informação para composição do mesmo.
  • Antes de criar um cartão pelos endpoints de criação de cartão, cobrança ou afins, é necessário gerar o token e adicioná-lo no atributo cryptData.

Exemplo de criação de Cartão com token

É esperado que o hash seja gerado antes de enviar a requisição.

curl --request POST \
     --url  https://sandbox.openfinance.celcoin.dev/baas/v1/cash/cards/1/galaxPayId?account=123456 \
     --header 'accept: application/json' \
     --header 'authorization: Bearer TOKEN' \
     --header 'content-type: application/json' \
     --data '
{
  "cryptData": "MIICXAIBAAKBgQCBzYu64lVZGFpXhSUqev+60XTkcXloqOmB9hRnwTd4V7g+sNNZkQa8upGS/0D7VYfhVExmfaSGLrT/erTZoednye1Tx1OKMSomXQZY9G1vVMrTmVby+2ey3V15YQL0EAfk6tuXC/kuRkHNzIvTcvZZ/xHq+KahFFGi+1bizd9VuQIDAQABAoGANZxrpdhtX8sLJTK80vrSPJreKKwldPCu4Rp9+wx2mKHCW0I1SLz5h2GXVptOf4AoCw0CMSKbnUAVSZ+oqmqQZFSTqbNuX9T/L/6FHAvyUceeskz+hfNaCGoHoefEwpU40gW4rt7P4reb4PS+0LKIHepdCg14mJhAoJWJPnAt5gECQQD0QMlqvXhezdBJR2P69ljpSi+jVLvlvykz28CAeGi42Ok0mbFg3aRzYuN8AEwIfgF6Jmg3tnUQuuWcipRFfeKpAkEAiAupu1ntBLj5YDqjjYy/itwPGazXZKYeaWIiWsjd8abWgBieSWccC0Bv9uN4uZD4JB8IO/nppqpKTo0q667UkQJBAJhGk8viF9szAPnOcjyRvNikkZKITyRqyyszg44Ug2VKhglvEDDNvaraKeyy2rQoqo8Wxr6FF/K4MlIn60xvsRECQHgwJZEYjuZ/LACxjVA+KfHZG5YJNnj6sR9UzRj7H+ifBh1AooYii4n9MW0h5MO7qRzwNWwXCy5sfx0KZgK0/6ECQFw2ZoxhXFa3Hqqew/h2i4LCmhNx9PSj/F9ez6TBTUxpPHnKUDUdtzPf0GKLRTUS4IYbjn2I7Z7MsL2+LZaV6F4=",
  "number": "4111 1111 1111 1111",
  "holder": "JOHN DOE",
  "expiresAt": "2029-01",
  "cvv": "444"
}
'

Boas práticas de segurança

  • É importante garantir que os dados do cartão (número, CVV, expiração e nome do portador) não serão enviados em texto plano para o seu servidor, trafegando apenas o hash gerado.
  • Não armazene dados PAN, CVV ou validade em logs, localStorage ou analytics.
  • Use HTTPS em toda a jornada (página, assets e backend).
  • Valide no cliente e também no servidor (sem reprocessar PAN); o servidor deve operar somente com o token.
  • Implemente mascaramento no UI e políticas de input (ex.: permitir apenas dígitos).
  • Rotacione a chave pública quando indicado e invalide versões antigas no cache do cliente.

Tratamento de erros e troubleshooting

  • Falha ao carregar chave pública: verifique conectividade, CORS e se o ambiente (true/false) está correto antes de _setPublicKey().
  • Erros de validação: capture exceções de validate e dos validadores para orientar o usuário com mensagens claras (sem expor detalhes internos).
  • Token vazio ou malformado: confirme que baasCard._publicKey está preenchida e no formato esperado (PEM/base64) antes de chamar encrypt.
  • Data de validade inválida: garanta o padrão YYYY-MM e ajuste mês/dia no fuso horário do cliente para evitar falsos vencimentos.