SelectwinDOCS
Cartões

Criar um cartão

Cadastre um cartão de crédito ou débito de um cliente e receba de volta um token seguro (card…) que você usa em cobranças futuras sem nunca mais tocar nos dados sensíveis do cartão. Use este endpoint

Cadastre um cartão de crédito ou débito de um cliente e receba de volta um token seguro (card_…) que você usa em cobranças futuras sem nunca mais tocar nos dados sensíveis do cartão. Use este endpoint quando o titular autoriza salvar o cartão — por exemplo, no checkout, no onboarding do app ou para preparar uma assinatura recorrente.

POST /v1/cards

Como funciona

Quando você envia o número do cartão (PAN), a validade, o CVV e o nome do titular, a Selectwin faz três coisas em uma única chamada síncrona:

  1. Valida os dados — confere o número pelo algoritmo de Luhn, identifica a bandeira (brand) e verifica se a validade não está vencida.
  2. Tokeniza — armazena o cartão de forma segura e gera um identificador opaco (card_…). O número completo (PAN) e o CVV não ficam acessíveis depois disso: a resposta só devolve o BIN (firstDigits, 6 dígitos) e os 4 últimos dígitos (lastDigits).
  3. Associa o token ao cliente informado em customerId.

Tokenizar = trocar os dados crus do cartão por uma referência segura (o token). Você guarda o token, não o cartão — o que reduz drasticamente o seu escopo de conformidade PCI DSS.

A partir daí, o token é o que você passa para os outros recursos (transações, assinaturas). O cartão criado já nasce associado a um cliente; ele não existe "solto".

Manuseio de dados de cartão (PCI DSS)

Enviar PAN e CVV diretamente para esta API coloca o seu servidor no escopo PCI DSS. Sempre que possível, capture os dados do cartão por um fluxo que não passe pelo seu backend (campos hospedados / SDK de frontend) e trafegue apenas o token. Trafegue tudo exclusivamente sobre HTTPS/TLS e nunca registre PAN, CVV ou validade em logs.

Quando usar

  • Salvar um cartão apresentado pelo cliente para reuso (one-click, recorrência, cobrança futura).
  • Substituir um cartão vencido por um novo (crie o novo token; remova o antigo com Excluir Cartão).

Quando não usar:

  • Para cobrar agora sem salvar o cartão, use o recurso de transações diretamente.
  • O cartão é imutável: não há como editar número, validade ou bandeira de um token já criado. Para "atualizar", crie um novo cartão e exclua o anterior.

Requisição

Headers

CabeçalhoObrigatórioDescrição
SelectKeySimSua chave de API. Produção: sl_live_…; sandbox: sl_test_…. Veja Autenticação.
Content-Type: application/jsonSimO corpo é JSON.
X-Idempotency-KeyRecomendadoEvita criar o mesmo cartão duas vezes se a requisição for repetida (timeout, retry). Veja Idempotência.

Nunca use Authorization: Bearer/Basic — a autenticação é sempre pelo header SelectKey.

Corpo

CampoTipoObrigatórioDescrição
customerIdstringSimID do cliente dono do cartão (cus_…). Obrigatório ao usar /v1/cards de forma autônoma.
holderNamestringSimNome do titular impresso no cartão.
numberingstringSimNúmero do cartão (PAN). Validado por Luhn.
expirationMonthnumberSimMês de validade, de 1 a 12 (número, não string).
expirationYearintegerSimAno de validade (2 ou 4 dígitos), ex.: 2028.
securityCodestringSimCVV/CVC, 3 ou 4 dígitos (^\d{3,4}$).
primarybooleanNãoDefine este como cartão principal do cliente.

Nomes de entrada vs. de saída

No corpo da requisição, a flag é primary (não isPrimary). Já na resposta os campos booleanos aparecem sem o prefixo is (primary, active, valid, …). Em respostas de lista, os mesmos campos voltam com prefixo (isPrimary, isActive, …) — veja Listar Cartões.

Exemplo de requisição

curl -X POST https://api.selectwin.io/v1/cards \
  -H "SelectKey: sl_live_aBcDeFgHiJkLmNoPqRsTuVwXyZ" \
  -H "Content-Type: application/json" \
  -H "X-Idempotency-Key: 8f1c0c2e-2b4a-4f3e-9a6c-1d2e3f4a5b6c" \
  -d '{
    "customerId": "cus_01hqzvabc",
    "holderName": "JOAO SILVA",
    "numbering": "4111111111111111",
    "expirationMonth": 12,
    "expirationYear": 2028,
    "securityCode": "123",
    "primary": true
  }'

Resposta

201 Created. O corpo é o objeto completo do cartão tokenizado (a mesma forma retornada por Ler Cartão), já com bandeira detectada, dígitos mascarados e os links HATEOAS para as próximas ações.

{
  "id": "card_01hqzvabc",
  "holderName": "JOÃO SILVA",
  "brand": "visa",
  "firstDigits": "411111",
  "lastDigits": "1111",
  "expirationMonth": "12",
  "expirationYear": "2025",
  "primary": true,
  "active": true,
  "valid": true,
  "verified": true,
  "associated": true,
  "metadata": {},
  "createdAt": "2026-04-12T17:56:33.000Z",
  "updatedAt": "2026-04-12T17:56:33.000Z",
  "merchant": {
    "name": "Seller Name",
    "merchantId": "bus_1234567890",
    "isSubAccount": false
  },
  "_links": {
    "self":   { "href": "https://api.selectwin.io/v1/cards/card_01hqzvabc", "method": "GET",    "description": "Read a card." },
    "create": { "href": "https://api.selectwin.io/v1/cards",                "method": "POST",   "description": "Create a new card." },
    "update": { "href": "https://api.selectwin.io/v1/cards/card_01hqzvabc", "method": "PUT",    "description": "Update the card." },
    "delete": { "href": "https://api.selectwin.io/v1/cards/card_01hqzvabc", "method": "DELETE", "description": "Delete the card." },
    "list":   { "href": "https://api.selectwin.io/v1/cards",                "method": "GET",    "description": "List all cards." }
  }
}

Campos da resposta

CampoTipoDescrição
idstringToken/identificador opaco do cartão (card_…). Guarde este valor.
holderNamestringNome do titular (pode vir normalizado em maiúsculas).
brandstringBandeira detectada (ex.: visa, mastercard).
firstDigitsstringBIN — os 6 primeiros dígitos.
lastDigitsstringOs 4 últimos dígitos.
expirationMonth / expirationYearstringValidade (na resposta vêm como string).
primarybooleanSe é o cartão principal do cliente.
activebooleanCartão ativo.
validbooleanPassou nas validações.
verifiedbooleanCartão verificado.
associatedbooleanVinculado a um cliente.
metadataobjectMetadados livres (objeto vazio se não houver).
createdAt / updatedAtstring (date-time)Timestamps em ISO 8601 UTC.
merchantobjectConta/sub-conta dona do cartão (name, merchantId, isSubAccount).
_linksobjectLinks HATEOAS para as próximas ações: self, create, update, delete, list.

O PAN não volta

Por segurança, o número completo e o CVV nunca aparecem na resposta. Para identificar o cartão na sua interface, use brand + lastDigits (ex.: "Visa •••• 1111"). Trate id como opaco: armazene a string inteira, sem fazer parsing.

Erros

A API responde com o envelope de erro padrão. Trate sempre pelo error.code, não pela message. Códigos específicos de Cards e os transversais relevantes neste endpoint:

error.codeHTTPQuando ocorre
invalidParameters400Validação genérica do corpo; veja error.params para o campo culpado.
cardIdIsInvalid400Um ID de cartão informado tem formato inválido.
cardExpired400A validade (expirationMonth/expirationYear) já passou.
invalidCardData422Dados do cartão inválidos (ex.: número reprovado no Luhn, CVV malformado).
cardBrandNotSupported422A bandeira detectada não é aceita.
cardCreateNotProcessable422O cadastro não pôde ser processado (regra de negócio).
cardAndCustomerOfCompanyNotSame422O customerId não pertence à mesma conta/empresa do cartão.
limitReached403Limite de cartões da conta atingido.
unauthorized401SelectKey ausente, inválida ou revogada.
forbidden403Autenticado, mas sem permissão para a operação.
tooManyRequests429Limite de requisições excedido — respeite error.retryAfterMinutes.
serverError500Erro interno — repita com backoff; se persistir, contate o suporte.

Exemplo de falha de validação (422):

{
  "error": {
    "code": "invalidCardData",
    "statusCode": 422,
    "category": "validation",
    "message": "Invalid card data.",
    "params": [
      { "numbering": "Invalid card number. Please check if the number is correct." }
    ]
  }
}

Consulte o Catálogo de Códigos de Erro para a lista completa.

Boas práticas

  • Valide no cliente antes de enviar. Cheque Luhn, mês 1..12, ano não vencido e CVV de 3–4 dígitos no frontend — isso evita ida e volta e reduz invalidCardData/cardExpired.
  • Sempre envie X-Idempotency-Key. Um retry após timeout não deve gerar dois tokens do mesmo cartão. Veja Idempotência.
  • Garanta o casamento cliente×cartão. Use um customerId que pertença à sua conta para não cair em cardAndCustomerOfCompanyNotSame.
  • Nunca persista PAN/CVV. Guarde apenas o id (token) e, para exibição, brand + lastDigits. Não registre dados sensíveis em logs.
  • Exiba o cartão mascarado. "Visa •••• 1111" a partir de brand/lastDigits — o número completo não retorna.
  • Confirme a autorização do titular. Tenha consentimento explícito antes de salvar um cartão para cobranças futuras.
  • Trate limitReached (403) com mensagem útil. Peça ao cliente para remover um cartão antigo via Excluir Cartão antes de adicionar outro.

Veja também

How is this guide?

On this page