> ## 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.

# Salvar cartão para cobrar depois

> Cadastre o cartão uma vez, guarde-o como credencial segura e reutilizável e cobre quando precisar.

O **cadastro de cartão** permite coletar o cartão de um cliente uma vez, salvá-lo
como uma credencial reutilizável e cobrar depois. O comprador digita o cartão na
sua página; a Chargefy devolve um identificador (`pm_*`) sem que o número do
cartão 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** — salve o novo cartão e escolha separadamente onde ele passa a ser o padrão.
* **Checkout white-label** — você controla a coleta no seu frontend e deixa a cobrança para depois.

## Os objetos

A feature combina objetos com papéis distintos. O `setup_intent` acompanha o
cadastro, cada confirmação gera um `setup_attempt`, o cartão salvo é o
`payment_method` e a cobrança futura é um `payment_intent`. O token existe como
mecanismo interno e API de baixo nível; o fluxo recomendado não o expõe.

| Origem                  | Ação                             | Resultado                                     |
| ----------------------- | -------------------------------- | --------------------------------------------- |
| `customer`              | É informado no setup intent      | Define a quem o cartão salvo pertence.        |
| Browser com Chargefy.js | Chama `confirmSetup()`           | Coleta o cartão e devolve o `payment_method`. |
| `setup_intent`          | É confirmado                     | Cria o `payment_method` salvo.                |
| `setup_attempt`         | Registra cada confirmação        | Preserva sucesso, falha e detalhes seguros.   |
| `payment_method`        | É vinculado ao customer          | Fica disponível para cobranças futuras.       |
| `payment_method`        | É informado em um payment intent | Permite cobrar o cartão depois.               |

| Objeto                                  | Papel                                                                                            | Duração                              |
| --------------------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------ |
| [`token`](/api-reference/tokens/object) | Credencial intermediária usada internamente pelo SDK ou por integrações de baixo nível.          | Efêmero, uso único.                  |
| `setup_intent`                          | O **cadastro de cartão**: acompanha o processo de salvar sem cobrar e carrega o `client_secret`. | Temporário, ligado ao cadastro.      |
| `setup_attempt`                         | O histórico de uma confirmação do cadastro.                                                      | Imutável por 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>
  Cadastrar **não** cobra nada: um `setup_intent` não cria charge, invoice,
  pré-autorização ou reserva de limite. Para **cobrar agora**, use um [Payment
  Intent](/payments/payment-intents).
</Note>

## Como funciona, ponta a ponta

São três passos: o backend inicia o cadastro, o navegador salva o cartão e o
backend cobra com um payment intent quando precisar.

| Etapa | Responsável           | Ação                                            | Resultado                                                                |
| ----- | --------------------- | ----------------------------------------------- | ------------------------------------------------------------------------ |
| 1     | Seu backend           | `POST /v1/setup-intents` com o `customer`       | Recebe o cadastro e seu `client_secret`.                                 |
| 2     | Frontend do comprador | `chargefy.confirmSetup()`                       | Recebe `status: succeeded`; o cartão fica salvo e vinculado ao customer. |
| 3     | Seu backend           | `POST /v1/payment-intents` quando chegar a hora | Cobra usando o cartão salvo.                                             |

<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="Inicie o cadastro de cartão">
    `POST /v1/setup-intents`. A resposta traz o `client_secret`, com `status` em
    `requires_payment_method`.
  </Step>

  <Step title="Colete e conclua no navegador">
    Inicialize o [Chargefy.js](/api/chargefy-js) com a chave publicável e
    chame `confirmSetup` com `client_secret` e os dados do cartão. Em sucesso, o
    `status` vira `succeeded` e um `payment_method` (`pm_*`) é salvo e vinculado
    ao customer. O token de uso único fica interno ao SDK.
  </Step>

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

### 1. Iniciar o cadastro

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

```json theme={"theme":"css-variables"}
{
  "id": "seti_cE1YP2YUUxZbJB4b",
  "object": "setup_intent",
  "canceled_at": null,
  "cancellation_reason": null,
  "client_secret": "seti_cE1YP2YUUxZbJB4b_secret_001933f1ffbc4bd523e36e1a16ccb2c2a7a7b335233af4e5",
  "created_at": "2026-05-16T14:09:27Z",
  "customer": "cus_ESYjFSb97WsTEvsC",
  "last_setup_error": null,
  "latest_attempt": null,
  "livemode": false,
  "metadata": {},
  "next_action": null,
  "payment_method": null,
  "payment_method_types": [
    "credit_card"
  ],
  "status": "requires_payment_method",
  "updated_at": "2026-05-16T14:09:27Z",
  "usage": "off_session"
}
```

O `client_secret`, combinado com a `pk_*`, autoriza consultar e concluir somente
aquele cadastro. Envie-o à página do comprador, mas não o coloque em analytics
ou logs.

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

Os dados do cartão são coletados **no navegador do comprador** com o
[Chargefy.js](/api/chargefy-js). A chave secreta nunca vai para o browser e
o número do cartão nunca toca o seu backend.

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

```js theme={"theme":"css-variables"}
const chargefy = Chargefy("pk_live_...");

const cardSetup = await chargefy.confirmSetup({
  client_secret: setupIntent.client_secret,
  payment_method_data: {
    type: "credit_card",
    card: {
      number: cardNumber,
      exp_month: expMonth,
      exp_year: expYear,
      cvc,
    },
    billing_details: {
      name: holderName,
    },
  },
});
```

```json theme={"theme":"css-variables"}
{
  "id": "seti_cE1YP2YUUxZbJB4b",
  "object": "setup_intent",
  "client_secret": "seti_cE1YP2YUUxZbJB4b_secret_001933f1ffbc4bd523e36e1a16ccb2c2a7a7b335233af4e5",
  "created_at": "2026-05-16T14:09:27Z",
  "last_setup_error": null,
  "livemode": false,
  "next_action": null,
  "payment_method": "pm_3FnF2oJH3xBjRqB4",
  "payment_method_types": [
    "credit_card"
  ],
  "status": "succeeded",
  "usage": "off_session",
  "...": "campos server-side omitidos no navegador"
}
```

Se preferir controlar a conclusão no servidor, envie o `token_id` para
[`POST /v1/setup-intents/{id}/confirm`](/api-reference/setup-intents/confirm)
com sua chave de API. O resultado é o mesmo.

O backend também pode concluir com cartões já existentes:

| Forma                     | Quando usar                                                                                 |
| ------------------------- | ------------------------------------------------------------------------------------------- |
| `payment_method_data`     | **Recomendado para cartão novo no browser.** O SDK cuida da tokenização e confirmação.      |
| `token_id` (`tok_*`)      | API de baixo nível para quem controla explicitamente a credencial intermediária.            |
| `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 não puder ser salvo, a resposta é `402 card_setup_failed`. O
  cadastro volta para `requires_payment_method`, registra `last_setup_error` e
  dispara `setup.intent.failed`. Corrija ou troque o cartão e chame
  `confirmSetup()` novamente.
</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={"theme":"css-variables"}
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_ESYjFSb97WsTEvsC",
    "payment_method": "pm_3FnF2oJH3xBjRqB4"
  }'
```

<Tip>
  Passe o `pm_*` retornado explicitamente na cobrança. Se quiser que ele seja o
  padrão do customer, faça essa escolha separadamente com `POST
      /v1/payment-methods/{id}/attach`; depois disso, cobranças que usam o padrão
  podem partir só do `customer`.
</Tip>

## Ciclo de vida do cadastro

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       |
| `requires_action`         | Exige ação adicional do comprador; o processador atual não produz este estado.                 | Não       |
| `processing`              | Reservado para confirmação assíncrona; não é o retorno normal do fluxo atual.                  | Não       |
| `succeeded`               | O cartão foi salvo e vinculado ao 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`.

<Warning>
  O cadastro aceita hoje apenas `credit_card`. Ele não verifica saldo, não faz
  pré-autorização e não garante aprovação futura. Um cadastro avulso também não
  expira sozinho; cancele-o se o comprador abandonar o fluxo.
</Warning>

## 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 cadastro de cartão foi iniciado.          |
| `setup.intent.succeeded`  | O cartão foi salvo e vinculado ao 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 vinculado ao 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**. Cada confirmação fica registrada em um
`setup_attempt`; os eventos do ciclo de vida vêm do setup intent e do payment
method.

## Próximos passos

<CardGroup cols={2}>
  <Card title="Tentativas de cadastro" icon="clock" href="/api-reference/setup-attempts/object">
    Veja o histórico de cada confirmação e falha.
  </Card>

  <Card title="Cadastro de cartão" icon="cube" href="/api-reference/setup-intents">
    Contrato completo, limitações, erros e operações.
  </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/object">
    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>
