Tokenize um cartão
Guarde um cartão do comprador como token reutilizável e cobre com ele em compras futuras, sem armazenar o número do cartão.
/api/v1/card-tokensSuperfície API, chamada do seu servidorA tokenização troca os dados do cartão por um identificador reutilizável, o cardTokenUid (ctok_…). Você grava esse identificador junto ao cliente no seu sistema e o usa no lugar do número do cartão nas próximas cobranças. Criar um token não cobra nada: cada pagamento continua sendo uma cobrança criada explicitamente pelo seu servidor.
Crie o token
curl -X POST "$DM_API_BASE/api/v1/card-tokens" \
-H "Authorization: $DM_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: cliente-1001-cartao-tentativa-1" \
-d '{
"card": {
"number": "5555555555554444",
"expMonth": 12,
"expYear": 2030,
"cvv": "123",
"holderName": "MARIA SOUZA"
},
"customerId": "cliente-1001"
}'| Campo | Tipo | Obrigatório | Regra |
|---|---|---|---|
card.number | string | Sim | De 12 a 19 dígitos, com dígito verificador válido (Luhn). Espaços e hífens são ignorados. |
card.expMonth | inteiro | Sim | De 1 a 12. |
card.expYear | inteiro | Sim | Ano com quatro dígitos. O cartão não pode estar vencido; ele vale até o último dia do mês de validade. |
card.cvv | string | Não | 3 ou 4 dígitos. Sem ele, o token nasce com cvvStored: false. |
card.holderName | string | Não | Nome impresso no cartão. |
customerId | string | Não | Identificador estável do cliente no seu sistema. Recomendado: é ele que separa os cartões de clientes diferentes. |
idempotencyKey | string | Condicional | Alternativa ao cabeçalho Idempotency-Key. Se enviar os dois, os valores precisam ser iguais. |
Nesta rota o código de segurança é cvv
Na criação de cobrança o campo se chama cvc; aqui ele se chama cvv. Enviar card.cvc (ou cvv2, securityCode) nesta rota retorna 400 validation_failed.
Resposta
{
"cardTokenUid": "ctok_01M0FVG11PZK94T569VFYE4FY3",
"brand": "MASTERCARD",
"bin": "555555",
"last4": "4444",
"expMonth": 12,
"expYear": 2030,
"status": "ACTIVE",
"cvvStored": true,
"deduplicated": false
}| Campo | Descrição |
|---|---|
cardTokenUid | O token. ctok_ seguido de 26 caracteres maiúsculos. Guarde-o associado à conta e ao cliente. |
brand | VISA, MASTERCARD, ELO, HIPERCARD, AMERICAN_EXPRESS, DINERS, DISCOVER, JCB ou UNSPECIFIED. Bandeira não identificada não impede a criação. |
bin | Os seis primeiros dígitos do cartão. |
last4 | Os quatro últimos dígitos, para exibir ao comprador. |
expMonth, expYear | Validade registrada no token. |
status | ACTIVE para um token novo. Um token reaproveitado pode vir SUSPENDED. |
cvvStored | Se o código de segurança ficou guardado para a próxima cobrança. |
deduplicated | true quando a API devolveu um token já existente em vez de criar outro. |
Cartão já tokenizado
Se o mesmo cartão já tiver um token ativo para o mesmo customerId na sua conta, a API não cria outro: responde 200 OK com o token existente e deduplicated: true. Um token novo responde 201 Created.
Três detalhes desse reaproveitamento:
- Sem
customerId, todos os cartões da conta são tratados como de um mesmo cliente. O mesmo cartão enviado duas vezes semcustomerIddevolve o mesmo token. Envie semprecustomerIdse a sua base tem clientes diferentes. - A validade não é atualizada. Um cartão renovado (mesmo número, validade nova) devolve o token antigo com a validade antiga. Compare
expMonth/expYearda resposta com o que o comprador digitou. - O código de segurança é substituído. Se você enviar
cvv, ele passa a ser o guardado.
Cobre com o token
Na criação da cobrança, troque os dados do cartão por card.token. O restante da compra continua igual: comprador, split, valor, moeda e sessão 3DS.
"paymentMethods": [{
"type": "CreditCard",
"amount": 10000,
"card": { "token": "ctok_01M0FVG11PZK94T569VFYE4FY3" }
}]- Use o token na mesma conta em que ele foi criado.
- Se o token e os dados do cartão vierem juntos, o token vence e os outros campos são ignorados. Para trocar de cartão, crie outro token.
- Na requisição o campo é
card.token.cardTokenUidaparece só nas respostas e nos webhooks, dentro depaymentMethods[].card. - Um token inválido não faz a API tentar outro instrumento automaticamente.
Erros ao cobrar com token
| HTTP | type | Significado | Ação |
|---|---|---|---|
422 | card_token_not_found | Token com formato inválido, inexistente ou de outra conta. | Confira a conta e o valor enviado. |
422 | card_token_not_usable | Token revogado, suspenso ou sem credencial ativa. | Peça outro cartão ao comprador. |
503 | vault_unavailable | Indisponibilidade temporária do cofre de cartões. | Repita com a mesma Idempotency-Key e o mesmo corpo, respeitando Retry-After. |
Idempotência da tokenização
A tokenização tem regras próprias, diferentes das da criação de cobrança:
| Regra | Requisito |
|---|---|
| Chave | Obrigatória, no cabeçalho Idempotency-Key ou no campo idempotencyKey. |
| Formato | De 8 a 255 caracteres: letras ASCII, números e _ . : -. Fora disso a resposta é 400 invalid_card. |
| Retenção | 24 horas. |
| Repetição com mesma chave e mesmo corpo | Devolve a resposta original, com o mesmo status HTTP. |
| Mesma chave, corpo diferente | 409 idempotency_conflict. |
| Repetição enquanto a primeira ainda processa | 409 idempotency_in_flight. Aguarde alguns segundos e repita com a mesma chave. |
Erros de validação e falhas de indisponibilidade não consomem a chave: repetir com a mesma chave executa de novo.
Erros da tokenização
Esta rota responde erros num envelope próprio, com code e message:
{
"code": "validation_failed",
"message": "Field 'card.cvc' is not supported; use 'card.cvv' for the card security code."
}| HTTP | code | Causa | Ação |
|---|---|---|---|
400 | validation_failed | Campo cvc em vez de cvv, chave de idempotência ausente ou chaves diferentes no cabeçalho e no corpo. | Corrija a requisição. |
400 | invalid_card | Número, validade ou código de segurança inválidos, cartão vencido, ou chave de idempotência em formato inválido. | Revise os dados e a chave. |
400 | sem code | JSON malformado ou campo obrigatório ausente (card, number, expMonth, expYear). Corpo em Problem Details. | Corrija a requisição. |
409 | idempotency_conflict | A chave já foi usada com outro conteúdo. | Use uma chave nova para uma solicitação nova. |
409 | idempotency_in_flight | A mesma solicitação ainda está em andamento. | Repita com a mesma chave e o mesmo corpo após um intervalo. |
429 | rate_limited | Mais de 600 tokenizações por minuto na conta. | Respeite o cabeçalho Retry-After. |
503 | vault_unavailable | Indisponibilidade temporária. | Repita preservando chave e corpo, com espera crescente. |
Nesta integração o número do cartão passa pelo seu servidor. Proteja o transporte, não registre número nem código de segurança em logs e mantenha o ambiente dentro das exigências do PCI DSS que se aplicam a você. Se preferir que os dados do cartão não passem pelo seu servidor, use o SDK de campos: ele gera um token temporário (tok_…) direto no navegador. Esse token serve para uma cobrança; o ctok_… desta página é o cartão salvo, para compras futuras.
Não exponha ao comprador a resposta técnica. Oriente-o a revisar o cartão ou escolher outro meio de pagamento, e guarde o código, o id do PaymentIntent e a chave de idempotência para diagnóstico.