Tokenização

Criptografe dados de cartão no navegador com o Bridge SDK da Tokeflow e troque-os por uma referência de token de uso único que seu backend pode cobrar.

A tokenização transforma dados brutos de cartão em uma referência de token segura de manipular, sem que esses dados jamais toquem seus servidores. Com o Bridge SDK, o portador do cartão digita nos campos seguros da Tokeflow, o SDK criptografa os dados no navegador e tokeflow.cards.tokenize() retorna um CardToken. Você envia apenas o tokenId para o seu backend, que cria uma transação com ele.

Isso mantém os dados sensíveis do cartão fora do escopo da sua aplicação, ao mesmo tempo em que você mantém controle total sobre a UI e o fluxo de pagamento.

Os campos seguros da Tokeflow rodam dentro de iframes isolados e cross-origin; os dados do cartão são criptografados no navegador e nunca tocam seus servidores. Os scripts da página não conseguem ler o PAN, a validade ou o CVC brutos.

Como a tokenização se encaixa

A tokenização é uma etapa do lado do cliente. O token que ela produz é trocado por uma cobrança no seu servidor, onde vive a sua chave secreta.

Nunca envie dados brutos de cartão (PAN, CVC, validade) para o seu próprio backend. Envie apenas o tokenId retornado por tokenize(). O objetivo da tokenização é justamente manter os dados do cartão fora do escopo PCI dos seus servidores.

tokeflow.cards.tokenize(input, options?)

O método cards.tokenize() criptografa os dados coletados pelos seus Elements de cartão e resolve para um CardToken. Ele aceita dois formatos de entrada — combinado ou dividido — mais o nome do portador do cartão e o endereço de cobrança opcionais.

Chame tokenize() somente após o SDK estar inicializado (await tokeflow.init()) e seu(s) elemento(s) de cartão estar(em) montado(s). Consulte o Quickstart para a configuração completa.

Entrada com elemento combinado

Use o CardElement combinado (número, validade e CVC em um único iframe) e passe-o como card:

const cardElement = tokeflow.createCardElement();
cardElement.mount('#card-element');

const token = await tokeflow.cards.tokenize({ card: cardElement });
console.log(token.tokenId); // tok_...

Entrada com campos divididos

Quando você coleta o número do cartão, a validade e o CVC em iframes separados, passe cada elemento sob sua própria chave:

const cardNumber = tokeflow.createCardNumberElement();
const cardExpiry = tokeflow.createCardExpirationElement();
const cardCvc = tokeflow.createCardCvcElement();

cardNumber.mount('#card-number');
cardExpiry.mount('#card-expiry');
cardCvc.mount('#card-cvc');

const token = await tokeflow.cards.tokenize({
  cardNumber,
  expiration: cardExpiry,
  cvc: cardCvc,
});

A chave da validade é expiration — não expirationDate nem expiry. Usar a chave errada deixa a validade sem definição e a tokenização falha na validação.

Nome do portador do cartão e endereço de cobrança opcionais

Ambas as entradas aceitam um cardholderName e um billingAddress opcionais. Cada campo pode ser fornecido como um elemento montado ou como uma string simples — combine conforme o seu formulário exigir.

const token = await tokeflow.cards.tokenize({
  card: cardElement,
  cardholderName: cardholderNameElement, // element or 'Jane Doe'
  billingAddress: {
    line1: addressLine1Element,          // element or string
    line2: 'Apt 4B',                     // string
    city: cityElement,                   // element or string
    state: 'CA',                         // string
    postalCode: postalCodeElement,       // element or string
    country: 'US',                       // ISO 3166-1 alpha-2
  },
});
FieldTypeRequiredDescription
cardCardElementCondicionalO elemento de cartão combinado. Obrigatório para a entrada combinada.
cardNumberCardNumberElementCondicionalElemento do número do cartão. Obrigatório para a entrada dividida.
expirationCardExpirationElementCondicionalElemento da validade. Obrigatório para a entrada dividida. Observe que a chave é expiration.
cvcCardCvcElementCondicionalElemento do CVC. Obrigatório para a entrada dividida.
cardholderNameCardholderNameElement | stringNãoNome no cartão, como um elemento montado ou uma string.
billingAddressBillingAddressInputNãoEndereço de cobrança. Cada subcampo é um elemento ou uma string.

Subcampos de BillingAddressInput: line1, line2, city, state, postalCode, country — cada um deles aceita um elemento ou uma string.

Opções

O segundo argumento opcional carrega metadados não sensíveis para armazenar junto com o token e — desde o SDK 2.6.0 — diz se o cartão pode ser salvo para depois.

type TokenPurpose = 'one_time' | 'instrument_enrollment';

interface TokenizeOptions {
  metadata?: Record<string, any>; // custom metadata stored with the token
  saveCard?: boolean;             // inside a checkout session: enroll the card for later use
  purpose?: TokenPurpose;         // standalone tokenization: which kind of token to mint
}
OpçãoOnde se aplicaEfeito
saveCardApenas dentro de uma sessão de checkout (checkoutSessionId definido).Para uma oferta avulsa, true emite um token instrument_enrollment para que o cartão possa ser salvo como instrumento de pagamento. Uma oferta recorrente sempre cadastra, então a flag é redundante nesse caso. Ignorada fora de uma sessão.
purposeApenas na tokenização standalone (sem sessão de checkout).one_time (padrão) emite um token de uso único que expira; instrument_enrollment emite um token sem expiração que pode ser salvo. Dentro de uma sessão de checkout o servidor deriva a finalidade da oferta e de saveCard, e ignora esta opção.
metadataEm qualquer lugar.Dados personalizados não sensíveis armazenados com o token.
// Dentro de uma sessão de checkout — o cliente marcou "salvar meu cartão"
const token = await tokeflow.cards.tokenize(
  { card: cardElement },
  { saveCard: true, metadata: { cartId: 'cart_123' } }
);

// Tokenização standalone — emita um token que possa ser salvo
const token = await tokeflow.cards.tokenize(
  { card: cardElement },
  { purpose: 'instrument_enrollment' }
);

As duas opções são omitidas da requisição quando não definidas, então deixá-las de fora não é o mesmo que enviar false. Peça o consentimento do cliente antes de solicitar um token cadastrável.

Nunca coloque PII do portador do cartão ou dados de cartão em metadata. São apenas dados personalizados não sensíveis.

tokenize() sempre retorna um CardToken; ele nunca salva o cartão por conta própria. Se o cartão vira um instrumento reutilizável é decidido no servidor — pela sessão de checkout, por save_payment_instrument na cobrança, ou por uma chamada explícita de cadastro — e cada um deles recusa um token one_time. Leia o purpose do token retornado para saber o que recebeu. Veja Upsells e downsells em um clique para o fluxo completo.

A resposta CardToken

interface CardToken {
  tokenId: string;       // your Tokeflow token reference, e.g. 'tok_...'
  type: 'card';
  brand: string;         // 'visa', 'mastercard', etc.
  last4: string;         // last 4 digits of the card
  expiryMonth: string;   // e.g. '12'
  expiryYear: string;    // e.g. '2029'
  bin?: string;          // bank identification number (optional)
  createdAt?: string;    // ISO 8601 timestamp (optional)
  purpose?: TokenPurpose; // 'one_time' | 'instrument_enrollment' — what the server actually minted
}
FieldTypeDescription
tokenIdstringA referência de token para enviar ao seu backend. Prefixada com tok_.
type'card'Sempre card para tokenização de cartão.
brandstringBandeira do cartão detectada (ex.: visa, mastercard).
last4stringÚltimos quatro dígitos, seguros para exibição.
expiryMonthstringMês de validade com dois dígitos, como string.
expiryYearstringAno de validade com quatro dígitos, como string.
binstring?Número de identificação do banco, quando disponível.
createdAtstring?Timestamp de criação em ISO 8601, quando presente.
purposeTokenPurpose?A finalidade com que o servidor emitiu o token — one_time ou instrument_enrollment. Confira quando você pediu um token cadastrável: uma divergência não falha aqui, mas é recusada depois, no cadastro ou na cobrança.

Valor de exemplo:

{
  "tokenId": "tok_8f3c2a1b9d4e",
  "type": "card",
  "brand": "visa",
  "last4": "4242",
  "expiryMonth": "12",
  "expiryYear": "2029",
  "bin": "424242",
  "createdAt": "2026-01-15T12:30:00.000Z",
  "purpose": "one_time"
}

brand, last4, bin e a validade são não sensíveis e seguros para exibir na sua UI — úteis para uma confirmação do tipo "terminando em 4242". O PAN completo e o CVC nunca são retornados.

Teste o Bridge SDK sem código

Quer um token para experimentar a API antes de conectar o SDK? A Tokeflow hospeda um testador em card.tokeflow.com que roda o Bridge SDK contra o seu merchant e mostra o token retornado — a mesma referência tok_… criptografada que a sua própria integração recebe. Use-o para ver exatamente o que a tokenização retorna e para alimentar valores reais de token nos endpoints de pagamento.

  1. Abra card.tokeflow.com e informe a chave pública do seu merchant (pk_test_… ou pk_live_…). Chaves secretas nunca são usadas no navegador.
  2. Preencha os campos seguros de cartão e envie. O cartão é criptografado dentro dos iframes isolados e cross-origin da Tokeflow — exatamente como no seu próprio site — de modo que o PAN bruto nunca sai do navegador.
  3. Inspecione a referência de token retornada (tok_…) junto com seus detalhes não sensíveis (brand, last4, validade).
  4. Passe esse valor como card_ciphertext_id para testar seus endpoints de método de pagamento — por exemplo POST /api/v1/transactions.

Cada token é de uso único e de curta duração — gere um novo para cada cobrança de teste. Use uma chave pública de teste (pk_test_…) durante a integração para que nenhum valor real seja envolvido. Consulte Ambientes e chaves.

Trocando o token por uma cobrança

O token é uma referência, não uma cobrança. Depois que tokenize() resolve, envie o tokenId para o seu próprio backend e deixe seu servidor criar a transação com a sua chave secreta.

1. Tokenize no navegador

const token = await tokeflow.cards.tokenize({ card: cardElement });

await fetch('/api/payments', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ tokenId: token.tokenId }),
});

2. Crie a transação a partir do seu servidor

Seu backend troca o tokenId por uma transação. Use uma chave secreta — nunca a exponha no navegador — e envie um Idempotency-Key para que retentativas não gerem cobrança dupla.

curl -X POST https://api.tokeflow.com/api/v1/transactions \
  -H "Authorization: Bearer sk_live_mer_xxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6b1f7e2c-9a44-4f1e-8c3d-1a2b3c4d5e6f" \
  -d '{
    "amount": 9900,
    "currency": "BRL",
    "payment_method": "credit_card",
    "card_ciphertext_id": "tok_8f3c2a1b9d4e",
    "customer_id": "cust_9f2a1c"
  }'

Exemplo de resposta de sucesso:

{
  "success": true,
  "data": {
    "id": "tx_4d2e1a9c7b",
    "status": "authorized",
    "amount": 9900,
    "currency": "BRL",
    "payment_method": "credit_card",
    "charge_type": "payment",
    "customer_id": "cust_9f2a1c",
    "created_at": "2026-01-15T12:30:01.000Z"
  },
  "request_id": "req_8f3c2a1b",
  "timestamp": "2026-01-15T12:30:01.000Z"
}

O valor está em unidades menores inteiras (centavos). 9900 com "currency": "BRL" é R$99,00. Sempre envie a currency em ISO 4217.

Valores monetários e decisões de roteamento são feitos no seu servidor com a sua chave secreta. O navegador nunca vê a chave secreta, nem o valor que ele não pode adulterar, nem o connector que processa a cobrança. Consulte Autenticação para o escopo das chaves.

Tratamento de erros

tokenize() rejeita com um TokeflowError carregando um code legível por máquina. Trate os casos comuns para dar ao portador do cartão um feedback acionável. Consulte a lista completa em Tratamento de erros.

import { TokeflowError, TokeflowErrorCode } from '@tokeflow_com/bridge-js';

try {
  const token = await tokeflow.cards.tokenize({ card: cardElement });
  // ... send token.tokenId to your backend
} catch (error) {
  if (error instanceof TokeflowError) {
    switch (error.code) {
      case TokeflowErrorCode.ELEMENT_INCOMPLETE:
        showError('Please complete all card fields');
        break;
      case TokeflowErrorCode.INVALID_CARD:
        showError('Please check your card number');
        break;
      case TokeflowErrorCode.EXPIRED_CARD:
        showError('This card has expired');
        break;
      case TokeflowErrorCode.UNSUPPORTED_CARD_BRAND:
        showError('This card brand is not supported');
        break;
      case TokeflowErrorCode.NETWORK_ERROR:
        showError('Network error. Please try again.');
        break;
      default:
        showError(error.message);
    }
  }
}
CodeQuando acontece
ELEMENT_INCOMPLETEUm campo de cartão obrigatório não foi totalmente preenchido.
ELEMENT_INVALIDO valor de um elemento é inválido.
INVALID_CARDO número do cartão falhou na validação.
EXPIRED_CARDA data de validade do cartão está no passado.
UNSUPPORTED_CARD_BRANDA bandeira do cartão não está habilitada para este merchant.
TOKENIZATION_FAILEDA tokenização não pôde ser concluída.
NOT_INITIALIZEDtokenize() foi chamado antes de init() resolver.
ELEMENT_NOT_MOUNTEDUm elemento passado não foi montado no DOM.
NETWORK_ERRORA requisição para a Tokeflow falhou na camada de rede.

Leia o getState() do elemento ({ empty, valid, invalid, complete }) antes de chamar tokenize() e desabilite seu botão de pagamento até que state.complete && state.valid. Isso captura entradas incompletas antes de um ida e volta. Consulte Elements.

Próximos passos

  • Elements — crie e estilize os campos seguros que você passa para tokenize().
  • Upsells e downsells em um clique — salve o cartão durante a compra e cobre-o de novo com um clique.
  • Checkout — vincule uma sessão criada no backend para conduzir um fluxo de checkout completo.
  • Tratamento de erros — a referência completa de TokeflowErrorCode.
  • Autenticação — chaves públicas vs. secretas e escopo de chaves.

Nesta página