> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chargefy.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Tokenização de cartão

> Colete o cartão do cliente uma vez, guarde-o como credencial segura e reutilizável, e cobre quando precisar — sem nunca tocar o número do cartão no seu backend.

A **tokenização de cartão** é o recurso da Chargefy para **coletar o cartão de um cliente uma única vez** e guardá-lo como uma credencial durável e segura. O comprador informa o cartão uma vez; a Chargefy tokeniza, retém só o que é seguro reter e devolve um identificador (`pm_*`) que você pode cobrar de novo no futuro — sem pedir os dados outra vez e sem que o número do cartão jamais passe pelo seu servidor.

<Info>
  **O que fica guardado — e o que nunca fica**

  A Chargefy persiste apenas o necessário para você reconhecer o cartão: a **bandeira**, os **quatro últimos dígitos** e o **mês/ano de validade**. O número completo (PAN) e o código de segurança (CVC) **nunca** são armazenados nem retornados — existem só em trânsito, no instante em que o cartão é tokenizado no navegador do comprador.
</Info>

## O que essa feature permite

Tokenizar o cartão separa **coletar** de **cobrar**, e isso destrava cobranças em que o comprador não está presente:

* **Assinaturas e trials** — guarde o cartão no cadastro e cobre automaticamente quando o trial termina e a cada renovação.
* **Recompra com um clique** — o cliente compra de novo sem redigitar o cartão.
* **Cobrança sob demanda (off-session)** — gere uma cobrança a qualquer momento usando o cartão salvo.
* **Troca de cartão padrão** — o cliente atualiza o cartão da assinatura sem refazer o cadastro.
* **Checkout white-label** — você controla a coleta no seu frontend e deixa a cobrança para depois.

## Os objetos

A feature combina alguns objetos com papéis distintos. Transformar o cartão em uma credencial segura é o trabalho do **token**; **salvar** é o setup intent; a credencial salva é o **payment method**; **cobrar** é o payment intent — sempre em um passo separado.

```mermaid theme={}
flowchart LR
  C[Customer] --> SI[Setup Intent]
  B[Browser: Chargefy.js] -- token_id --> SI
  SI -- confirm --> PM[Payment Method salvo]
  PM -. vira padrão de .-> C
  PM -. cobrado depois por .-> PI[Payment Intent]
```

| Objeto                                  | Papel                                                                                                                                             | Duração                              |
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ |
| [`token`](/api-reference/tokens/object) | O cartão recém-digitado, transformado numa credencial opaca de **uso único** (`tok_*`). Gerado no navegador, trocado uma vez por um cartão salvo. | Efêmero, uso único.                  |
| `setup_intent`                          | A tentativa de **coletar e salvar** um cartão, sem cobrar. Carrega o estado e o `client_secret`.                                                  | Temporário, ligado à tentativa.      |
| `payment_method`                        | O **cartão tokenizado** salvo e reutilizável (`pm_*`).                                                                                            | Durável, usado em cobranças futuras. |
| `payment_intent`                        | A **cobrança em si**, criada depois, referenciando o cartão salvo.                                                                                | Por cobrança.                        |

<Note>
  Tokenizar **não** cobra nada: um setup intent não cria charge, invoice ou movimentação financeira. Para **cobrar agora**, use um [Payment Intent](/features/payment-intents). Para **salvar agora e cobrar depois**, use a tokenização descrita aqui.
</Note>

## Como funciona, ponta a ponta

São quatro passos: criar o setup intent, tokenizar o cartão no browser, confirmar (o cartão é salvo e vira o padrão do customer) e — quando precisar — cobrar com um payment intent.

```mermaid theme={}
sequenceDiagram
  participant App as Seu backend
  participant API as Chargefy API
  participant Browser as Frontend (comprador)

  App->>API: POST /v1/setup-intents (customer)
  API-->>App: setup_intent<br/>status: requires_payment_method
  Browser->>Browser: tokeniza o cartão com Chargefy.js (token_id)
  Browser->>App: token_id
  App->>API: POST /v1/setup-intents/:id/confirm (token_id)
  API-->>App: status: succeeded + payment_method (pm_*)
  Note over API: cartão vira default do customer
  App->>API: POST /v1/payment-intents (customer, payment_method, confirm: true)
  API-->>App: payment_intent succeeded
```

<Steps>
  <Step title="Tenha um customer pronto">
    O cartão salvo pertence a um cliente. Crie ou encontre o `customer` (`cus_*`) antes de começar.
  </Step>

  <Step title="Crie o setup intent">
    `POST /v1/setup-intents`. A resposta traz o `client_secret`, com `status` em `requires_payment_method`.
  </Step>

  <Step title="Tokenize o cartão no frontend">
    Use o [Chargefy.js](/features/chargefy-js) no navegador do comprador para coletar e tokenizar o cartão. O resultado é um `token_id` de uso único — o número do cartão nunca toca o seu backend.
  </Step>

  <Step title="Confirme o setup intent">
    `POST /v1/setup-intents/:id/confirm` com o `token_id`. Em sucesso, o `status` vira `succeeded` e um `payment_method` (`pm_*`) é salvo e definido como padrão do customer.
  </Step>

  <Step title="Cobre quando precisar">
    `POST /v1/payment-intents` referenciando `customer` + `payment_method`, confirmando na mesma chamada com `confirm: true`.
  </Step>
</Steps>

### 1. Criar o setup intent

```bash theme={}
curl -X POST "https://api.chargefy.io/v1/setup-intents" \
  -H "Authorization: Bearer {{API_KEY}}" \
  -H "Content-Type: application/json" \
  -d '{
    "customer": "cus_123",
    "usage": "off_session"
  }'
```

```json theme={}
{
  "id": "seti_123",
  "object": "setup_intent",
  "client_secret": "seti_123_secret_abc",
  "customer": "cus_123",
  "payment_method": null,
  "status": "requires_payment_method",
  "usage": "off_session"
}
```

O `client_secret` identifica aquele setup intent específico. Trate-o como dado sensível. Neste fluxo a confirmação acontece no seu backend (com a chave de API), então o `client_secret` não precisa ir para o browser — a tokenização usa o [Chargefy.js](/features/chargefy-js), que não expõe a sua chave.

`usage` declara como o cartão será cobrado depois: `off_session` (padrão) quando a cobrança acontece **sem o comprador presente** (renovação, cobrança sob demanda) ou `on_session` quando ele estará presente na sessão.

### 2. Tokenizar o cartão no frontend

Os dados do cartão são coletados e tokenizados **no navegador do comprador** com o [Chargefy.js](/features/chargefy-js) — sua chave de API nunca vai para o browser, e o número do cartão nunca toca o seu backend. O resultado é um `token_id` de uso único que representa o cartão recém-digitado; é ele que você envia para confirmar.

```html theme={}
<script src="https://api.chargefy.io/v1/chargefy.js"></script>
```

```js theme={}
const chargefy = Chargefy({ environment: "live" });

const token = await chargefy.createPaymentToken({
  number: cardNumber,
  exp_month: expMonth,
  exp_year: expYear,
  cvc: cvc,
  name: holderName,
});

// Envie token.id ao seu backend para confirmar o setup intent.
```

### 3. Confirmar o setup intent

Confirmar é o passo que efetivamente salva o cartão e o define como **padrão do customer**.

```bash theme={}
curl -X POST "https://api.chargefy.io/v1/setup-intents/seti_123/confirm" \
  -H "Authorization: Bearer {{API_KEY}}" \
  -H "Content-Type: application/json" \
  -d '{
    "token_id": "tok_123"
  }'
```

```json theme={}
{
  "id": "seti_123",
  "object": "setup_intent",
  "client_secret": "seti_123_secret_abc",
  "customer": "cus_123",
  "payment_method": "pm_456",
  "status": "succeeded",
  "usage": "off_session"
}
```

Há três formas de fornecer o cartão ao confirmar:

| Forma                     | Quando usar                                                                                 |
| ------------------------- | ------------------------------------------------------------------------------------------- |
| `token_id` (`tok_*`)      | **Recomendado.** Token de cartão de uso único, gerado no frontend — salva um cartão novo.   |
| `card_id`                 | Cartão já salvo que **pertence a este customer**. A propriedade é validada antes de salvar. |
| `payment_method` (`pm_*`) | Um método já salvo no mesmo customer, ainda não definido no setup intent.                   |

<Warning>
  Se o cartão for recusado ao salvar, a resposta é `402` com `type: card_error`. O setup intent **não** trava: ele volta para `requires_payment_method`, registra o motivo em `last_setup_error` e dispara `setup.intent.failed`. Você pode pedir outro cartão e confirmar de novo no mesmo setup intent.
</Warning>

<Tip>
  Se você já tem o `token_id` em mãos, pule a etapa intermediária enviando `confirm: true` no create — equivale a criar e confirmar em uma única chamada.
</Tip>

### 4. Cobrar o cartão salvo depois

Com o `pm_*` salvo, a cobrança futura é um payment intent comum referenciando o `customer` e o `payment_method`. Como o comprador não está presente, basta informar o cartão salvo e confirmar na mesma chamada.

```bash theme={}
curl -X POST "https://api.chargefy.io/v1/payment-intents" \
  -H "Authorization: Bearer {{API_KEY}}" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 9900,
    "confirm": true,
    "currency": "brl",
    "customer": "cus_123",
    "payment_method": "pm_456"
  }'
```

<Tip>
  Não precisa repassar o `payment_method` se ele já é o padrão do customer — a cobrança pode partir só do `customer`. Passar o `pm_*` explícito é o caminho mais previsível quando o cliente tem mais de um cartão salvo.
</Tip>

## Ciclo de vida do setup intent

O `status` começa em `requires_payment_method` (ou `requires_confirmation`, quando já há um método) e caminha até um estado terminal — `succeeded` ou `canceled`.

| `status`                  | Significado                                                                                    | Terminal? |
| ------------------------- | ---------------------------------------------------------------------------------------------- | --------- |
| `requires_payment_method` | Ainda não há cartão definido. Estado inicial; também para onde volta se uma confirmação falha. | Não       |
| `requires_confirmation`   | Há um cartão definido, aguardando confirmação.                                                 | Não       |
| `processing`              | A confirmação está em andamento.                                                               | Não       |
| `succeeded`               | O cartão foi salvo e definido como padrão do customer.                                         | Sim       |
| `canceled`                | Encerrado sem salvar o cartão.                                                                 | Sim       |

Se o comprador desiste antes de confirmar, encerre com `POST /v1/setup-intents/{id}/cancel`. Estados terminais são imutáveis: confirmar ou cancelar de novo retorna `409`.

## O cartão salvo (`payment_method`)

O resultado durável da tokenização é um `payment_method` (`pm_*`). Ele guarda só os dados não sensíveis do cartão e pertence ao customer enquanto estiver anexado.

| Campo                              | Descrição                                                         |
| ---------------------------------- | ----------------------------------------------------------------- |
| `card.brand`                       | Bandeira (`visa`, `mastercard`, …).                               |
| `card.last4`                       | Quatro últimos dígitos.                                           |
| `card.exp_month` / `card.exp_year` | Validade.                                                         |
| `billing_details`                  | Dados de cobrança derivados do customer de contexto.              |
| `customer`                         | Customer ao qual o cartão está anexado; `null` quando desanexado. |

<Warning>
  O número completo (PAN) e o CVC **nunca** entram em `card` nem em qualquer outro campo. A Chargefy só persiste e retorna o suficiente para você reconhecer o cartão na sua interface.
</Warning>

### Anexar, desanexar e atualizar

Anexar liga o cartão a um customer como método padrão; desanexar desfaz esse vínculo. **Nenhuma das duas apaga a credencial** — só mudam se o cartão está ligado àquele customer.

| Operação  | Endpoint                               | Efeito                                                                    |
| --------- | -------------------------------------- | ------------------------------------------------------------------------- |
| Anexar    | `POST /v1/payment-methods/{id}/attach` | Liga o cartão ao `customer` como padrão.                                  |
| Desanexar | `POST /v1/payment-methods/{id}/detach` | Desliga o cartão do customer (a credencial continua existindo).           |
| Atualizar | `POST /v1/payment-methods/{id}`        | Único campo editável é `metadata` (merge). Dados do cartão são imutáveis. |
| Listar    | `GET /v1/payment-methods`              | Lista os cartões de um customer (`customer` é obrigatório).               |

<Tip>
  Não existe `DELETE` de payment method. "Tirar de uso" é o **detach** — desligar o cartão do customer. Para trocar o cartão, salve um novo.
</Tip>

## Webhooks

| Evento                    | Quando dispara                                         |
| ------------------------- | ------------------------------------------------------ |
| `setup.intent.created`    | O setup intent foi criado.                             |
| `setup.intent.succeeded`  | O cartão foi salvo e definido como padrão do customer. |
| `setup.intent.failed`     | Uma confirmação falhou ao salvar o cartão.             |
| `setup.intent.canceled`   | O setup intent foi encerrado sem salvar.               |
| `payment.method.created`  | Um cartão novo foi tokenizado e salvo.                 |
| `payment.method.attached` | O cartão foi definido como padrão do customer.         |
| `payment.method.updated`  | O `metadata` do cartão mudou.                          |
| `payment.method.detached` | O cartão foi desligado do customer.                    |

Cartão novo salvo com sucesso dispara, em ordem: `setup.intent.created` → `payment.method.created` → `payment.method.attached` → `setup.intent.succeeded`.

O `token` em si **não emite webhooks** — por ser de uso único e efêmero, os eventos do ciclo de vida do cartão vêm do setup intent e do payment method, depois que o token é consumido.

## Próximos passos

<CardGroup cols={2}>
  <Card title="Objeto token" icon="cube" href="/api-reference/tokens/object">
    O token de uso único — o ponto de entrada da tokenização.
  </Card>

  <Card title="Objeto setup_intent" icon="cube" href="/api-reference/setup-intents">
    Contrato completo de create, confirm, cancel e list.
  </Card>

  <Card title="Objeto payment_method" icon="credit-card" href="/api-reference/payment-methods">
    Schema do cartão salvo e operações de attach, detach, update e list.
  </Card>

  <Card title="API de payment intents" icon="bolt" href="/api-reference/payment-intents">
    Como cobrar o cartão salvo quando precisar.
  </Card>

  <Card title="Assinaturas" icon="rotate" href="/api-reference/subscriptions">
    Como o cartão salvo cobra trials e renovações.
  </Card>
</CardGroup>
