Skip to main content
A tokenização transforma os dados sensíveis do cartão (PAN, CVV, portador) em um token opaco (cvt_*) que você usa no lugar do cartão para criar pagamentos. O cartão real nunca passa pelo seu servidor — só o navegador do comprador e a LegacyPay enxergam os dados completos. Com o token você:
  • Cria transações em /payin sem nunca tocar em PAN/CVV.
  • Cobra o mesmo cliente novamente (card-on-file) sem precisar guardar cartão.
  • Permite que o comprador escolha entre cartões salvos em uma próxima compra.
Tudo isso é gerenciado pelo SDK LegacyPay (legacy-pay.js) — você não precisa conhecer nem chamar nenhuma rota interna da plataforma.

Importando o SDK

<script src="https://api.holdinglegacy.io/checkout/sdk/legacy-pay.js"></script>
<script>
  var client = LegacyPay.init({
    publicKey: "pk_live_xxx",
    apiBaseUrl: "https://api.holdinglegacy.io"
  });
</script>
A publicKey (pk_live_* ou pk_test_*) é segura para ficar exposta no navegador. Nunca coloque a sk_live_* no front-end.

Criar token a partir do cartão

var tokenized = await client.tokenizeCard({
  amount: 9900,
  installments: 1,
  referenceId: "pedido-123",
  card: {
    holderName: "MARIA OLIVEIRA",
    number: "4111111111111111",
    expirationMonth: "12",
    expirationYear: "2028",
    cvv: "123"
  },
  customer: {
    name: "Maria Oliveira",
    document: "12345678909",
    email: "maria@email.com",
    phone: "11988887777",
    address: {
      street: "Av Paulista",
      number: "1000",
      zipCode: "01310100",
      city: "São Paulo",
      state: "SP"
    }
  }
});
Resposta:
{
  "token": "cvt_live_5XY8...",
  "source": "tokenized",
  "brand": "visa",
  "last4": "1111",
  "bin": "411111",
  "expiresAt": "2028-12-31T23:59:59.000Z"
}
tokenizeCard() faz tokenização pura — não executa 3DS nem antifraude. Use prepareCardPayment() para o fluxo completo com 3DS e antifraude. Veja 3D Secure.

Usar o token no /payin

Esse passo é feito no seu backend, com Basic Auth (pk + sk):
POST https://api.holdinglegacy.io/payin
Authorization: Basic base64(pk_live_...:sk_live_...)

{
  "paymentMethod": "CREDIT_CARD",
  "amount": 9900,
  "referenceId": "pedido-123",
  "isPhysicalProduct": true,
  "payerIp": "203.0.113.1",
  "customer": { /* mesmo customer */ },
  "items": [{ "title": "Produto", "quantity": 1, "unitPrice": 9900 }],
  "card": {
    "token": "cvt_live_5XY8...",
    "installments": 1
  }
}
Quando a tokenização é exigida, enviar PAN/CVV bruto no /payin retorna 400 INVALID_DATA. Use sempre o token gerado pelo SDK.

CVV e PCI-DSS

O CVV é capturado pelo SDK, enviado para a LegacyPay junto com a tokenização, e nunca persiste em banco. Ele fica disponível por até 5 minutos para a primeira /payin após a tokenização — depois disso, é descartado. Para lojas onde o CVV precisa ser informado em cada cobrança (você descobre via client.getConfig(), campo capabilities.tokenization.cvvRequired), o comprador precisa digitar o CVV novamente em re-cobranças.

Card-on-file (cartões salvos)

Depois que o cliente paga uma primeira vez, o token continua válido até a data de expiração do cartão. Você pode listar cartões salvos do mesmo comprador, cobrar de novo e revogar quando o cliente pedir.

Listar cartões salvos

var cards = await client.listSavedCards({ document: "12345678909" });
// → [
//     {
//       token: "cvt_live_...",
//       brand: "visa",
//       last4: "1111",
//       expMonth: 12,
//       expYear: 2028,
//       lastUsedAt: "2026-05-10T15:00:00Z",
//       useCount: 3
//     }
//   ]
Use document (CPF) — o SDK pede ao backend para identificar o cliente.

Cobrar com cartão salvo

var payload = await client.payWithSavedCard({
  token: "cvt_live_...",
  cvv: "123",          // pode ser exigido — veja capabilities.tokenization.cvvRequired
  amount: 9900,
  referenceId: "pedido-456",
  installments: 1,
  customer: { name, email, document, phone }
});
// payload já está formatado para você enviar ao /payin no backend.
Se a loja exige CVV em re-cobrança e você não passou, o método lança LegacyPayError("CVV_REQUIRED", ...).

Revogar cartão

await client.revokeCard("cvt_live_...", { reason: "customer_request" });
O token sai de ACTIVE e a próxima /payin que tentar usá-lo é rejeitada.

Detectar capacidades da loja

var config = await client.getConfig();
// config.capabilities.tokenization = {
//   enabled: true,
//   mode: "backend",
//   cardOnFile: true,     // re-cobrança sem PAN
//   cvvRequired: false    // CVV exigido em re-cobrança?
// }
Cada loja configurada na plataforma tem um perfil próprio — você só consulta o que está disponível. Os detalhes de implementação (qual adquirente está atrás, quais regras de fraude se aplicam) não são expostos ao integrador.

Erros possíveis

Código (LegacyPayError.code)Quando ocorre
TOKENIZATION_UNSUPPORTEDLoja não tem tokenização habilitada. Contate o suporte.
THREEDS_FAILEDFalha na autenticação 3DS (banco recusou, tempo esgotado, navegador incompatível).
CVV_REQUIREDLoja exige CVV em re-cobrança. Pergunte o CVV ao cliente.
MISSING_CUSTOMER_KEYlistSavedCards foi chamado sem customerKey ou document.
MISSING_TOKENpayWithSavedCard ou revokeCard chamado sem token.
Detalhe para /payin (erros retornados pela API):
Código HTTPErroQuando ocorre
400INVALID_DATAA tokenização é exigida e o request veio com PAN bruto. Tokenize primeiro.
409INVALID_DATAJá existe uma cobrança em andamento com challenge 3DS aberto para esse token. Aguarde finalizar.
Token revogado ou expirado também é rejeitado com 400 ao tentar usá-lo no /payin.

Endpoints REST (referência)

O SDK abstrai estas rotas — documentadas aqui apenas para referência. Todas exigem a publicKey no header x-public-key.
MétodoRotaDescrição
POST/checkout/tokenizeGera o token (cvt_*) a partir do cartão.
POST/checkout/tokenize/:token/3dsAnexa dados de autenticação 3DS a um token.
GET/checkout/cardsLista cartões salvos (customerKey ou document).
DELETE/checkout/tokenize/:tokenRevoga um token.