# Recorrência

> Cobrança que se repete sozinha no cartão: os sete ciclos, o campo recurrence, as situações, o cancelamento e como acompanhar cada cobrança.

Fonte: https://app.thronecorporate.com/docs/cartao/recorrencias

## O que é

Uma cobrança que se repete sozinha no cartão do comprador, no intervalo que você escolher. Ele paga uma vez, no checkout de sempre, e as cobranças seguintes saem automaticamente.

A integração é a mesma: `POST /elements/checkout` com **um campo novo**, o mesmo Throne Elements na página, o mesmo webhook `transaction.paid` a cada cobrança.

> [!NOTE]
> O checkout é idêntico ao de uma venda única. Nenhum texto na tela diz que é recorrência, nenhuma data de cobrança aparece, o botão é o mesmo. Quem avisa o comprador é você, na sua página.

> [!NOTE]
> Nada a mudar no que já está no ar. Sem o campo novo, a requisição, a resposta e o webhook são os de hoje.

## Criar

```bash
curl -X POST https://app.thronecorporate.com/api/v1/elements/checkout \
  --max-time 60 \
  -H "Authorization: Bearer $THRONE_PK:$THRONE_SK" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "amount_cents": 4990,
    "currency": "brl",
    "acquirer": "apex",
    "recurrence": { "cycle": "monthly", "max_payments": 12 },
    "customer": { "name": "Ana Souza", "email": "ana@example.com" }
  }'
```

Resposta `201`, com três campos novos além dos de sempre:

```json
{
  "transaction_id": "a1b2c3d4-e5f6-4789-abcd-ef0123456789",
  "status": "pending",
  "checkout_url": "https://pay.example.com/checkout/0f1e2d3c4b5a69788796a5b4c3d2e1f0",
  "acquirer": "apex",
  "recurrence_id": "rec_7f3a9c1e5b2d4a6f8c0e1b3d",
  "cycle": "monthly",
  "next_charge_at": "2026-11-18T15:00:00Z"
}
```

O `transaction_id` é a **primeira cobrança**, que acontece no checkout. O `recurrence_id` é a assinatura, que você usa para consultar e cancelar. **Guarde o `recurrence_id`**: é por ele que você acompanha a cadência.

Os três campos aparecem só quando você envia `recurrence`.

> [!WARNING]
> Se `recurrence_id` vier `null` (com `next_charge_at` também `null`), a venda foi criada e o comprador pode pagar, mas **a assinatura não abriu**: não vão existir cobranças seguintes. Não repita a chamada com a mesma `Idempotency-Key`. Confira na sua conta se a venda nasceu e fale com o suporte.

## Ciclos aceitos

| Valor em `cycle` | Intervalo |
|---|---|
| `weekly` | semanal, a cada 7 dias |
| `biweekly` | quinzenal, a cada 14 dias |
| `monthly` | mensal |
| `bimonthly` | bimestral, a cada 2 meses |
| `quarterly` | trimestral, a cada 3 meses |
| `semiannually` | semestral, a cada 6 meses |
| `yearly` | anual |

Qualquer outro valor devolve `422 invalid_cycle` com a lista aceita. Nada é criado.

`max_payments` é opcional, de 2 a 120, e conta **todas** as cobranças, inclusive a primeira: `12` em um ciclo mensal significa doze meses. Quando a recorrência chega ao teto, ela vira `ended` e `next_charge_at` fica nulo. Sem o campo, ela segue até você cancelar.

O `next_charge_at` é sempre uma **estimativa** pelo ciclo: na criação, contada do dia da criação; depois, contada da data em que a última cobrança foi paga. Na consulta, ele vem nulo em `pending`, até a primeira cobrança ser confirmada, e depois que a recorrência para (`canceled` ou `ended`). A cobrança pode sair um dia antes ou depois. Não use essa data para liberar nem para cortar acesso: use o `transaction.paid` de cada cobrança.

## A primeira cobrança

A primeira cobrança é a venda do checkout, cobrada na hora, com uma passada só no cartão. Enquanto ela não aprova, a recorrência fica em `pending`.

Se o cartão é recusado, **nada é assinado**: o comprador vê a mensagem de recusa de sempre, tenta de novo no mesmo checkout (dentro do limite de tentativas) e a recorrência só passa para `active` quando uma tentativa aprovar. Um checkout que expira sem pagamento deixa a recorrência em `pending` para sempre, sem nunca cobrar nada.

Em adquirente cuja aprovação não é imediata, como a [Vortex](/docs/cartao/vortex#recorrencia), a primeira cobrança pode ficar em análise por alguns instantes. Nesse intervalo a venda fica `pending`, a recorrência fica `pending` e nenhuma cobrança seguinte sai; as duas seguem quando a análise libera. Se a análise reprovar, nada é assinado, e a tentativa é gasta como uma recusa.

## Como acompanhar

**Cada cobrança é uma venda**, com `transaction_id` próprio, e chega no seu webhook no formato de sempre. A primeira acontece no checkout; as seguintes aparecem sozinhas, no dia do ciclo.

> [!NOTE]
> O webhook não ganha campo novo: o formato é o mesmo de todas as suas vendas de cartão. Para acompanhar a assinatura, consulte a recorrência. No painel, a área Recorrências lista as cobranças de cada uma.

```bash
curl https://app.thronecorporate.com/api/v1/recurrences/rec_7f3a9c1e5b2d4a6f8c0e1b3d \
  -H "Authorization: Bearer $THRONE_PK:$THRONE_SK" \
  -H "Accept: application/json"
```

```json
{
  "recurrence_id": "rec_7f3a9c1e5b2d4a6f8c0e1b3d",
  "status": "active",
  "cycle": "monthly",
  "amount_cents": 4990,
  "currency": "BRL",
  "native_amount_cents": 4990,
  "max_payments": 12,
  "charges_count": 3,
  "last_charge_at": "2026-12-18T18:07:22Z",
  "next_charge_at": "2027-01-18T15:00:00Z",
  "product_name": null,
  "origin_transaction_id": "a1b2c3d4-e5f6-4789-abcd-ef0123456789",
  "canceled_at": null,
  "created_at": "2026-10-18T18:04:11Z",
  "metadata": {}
}
```

- `currency` e `native_amount_cents` são a moeda e o valor que você mandou; `amount_cents` é o valor em reais, pela cotação fixada na criação. A mesma convenção das vendas de cartão.
- `origin_transaction_id` é a venda da primeira cobrança, o mesmo id que o `201` devolveu.
- `charges_count` é quantas cobranças desta recorrência existem na sua conta, e `last_charge_at` é a data da última. **Quem diz se ela ainda cobra é o `status`**, não essa conta.
- `product_name` fica nulo: a criação do checkout não recebe nome de produto.

`GET /recurrences` lista as suas recorrências, as mais recentes primeiro, em `data`, com a paginação em `meta`, como nos outros endpoints de listagem. Aceita `per_page`, de 1 a 100 (padrão 25).

Os três endpoints usam as permissões que **já existem**: `transactions:read` nas duas leituras e `transactions:write` no cancelamento. Nenhuma permissão nova foi criada e nenhuma chave precisa ser gerada de novo. Se a sua chave só cria cobrança, ela cancela, mas para ler a recorrência ligue também `transactions:read` nela.

## Situações

| `status` | O que significa |
|---|---|
| `pending` | criada, esperando o pagamento da primeira cobrança |
| `active` | cobrando no ciclo |
| `past_due` | a última cobrança foi recusada. A assinatura continua, e volta para `active` quando uma cobrança aprovar |
| `canceled` | você cancelou. Não cobra mais |
| `ended` | chegou ao teto de `max_payments` e parou sozinha |

**Cobrança recusada não cria venda**: nenhum `transaction.paid` chega e nenhuma venda nova aparece na sua conta. Você vê a situação `past_due` na consulta e no painel.

## Cancelar

```bash
curl -X POST https://app.thronecorporate.com/api/v1/recurrences/rec_7f3a9c1e5b2d4a6f8c0e1b3d/cancel \
  -H "Authorization: Bearer $THRONE_PK:$THRONE_SK" \
  -H "Accept: application/json"
```

Com o `200`, as cobranças param na hora, e a resposta traz a recorrência. Cancelar uma recorrência que já estava parada também responde `200`, sem efeito nenhum.

Cancelar **não** estorna o que já foi pago e **não** mexe em venda nenhuma: para devolver dinheiro, fale com o suporte. Você também cancela pelo painel, na área Recorrências.

Quando o cancelamento não é confirmado, a resposta é de erro:

| Status | `error` | Significado | O que fazer |
|---|---|---|---|
| `422` | `cancel_failed` | Esta recorrência não é cancelada por aqui | Fale com o suporte |
| `503` | `cancel_failed` | O cancelamento não foi confirmado agora | Repita a mesma chamada em instantes, até receber `200` |

Enquanto a resposta não for `200`, trate a recorrência como ativa.

## Moeda

Você manda o valor na moeda que quiser, como em qualquer venda de cartão, e a cotação é fixada **na criação**. Os ciclos seguintes cobram o mesmo valor fixado: a cotação não é refeita a cada mês. Se você precisa acompanhar a variação da moeda, cancele e crie uma recorrência nova com o valor atualizado.

## Perguntas que aparecem sempre

**O comprador sabe que assinou?** Pelo checkout, não: a tela é a de uma venda única. Quem informa é você, na sua página, e é o certo a fazer: o comprador que não reconhece uma cobrança abre contestação.

**Posso mudar o valor, o ciclo ou o teto de uma recorrência ativa?** Não. Cancele e crie outra.

**Posso mandar `recurrence` e `one_click_from` na mesma chamada?** Mande um ou o outro. Os dois campos são aceitos juntos e nenhum erro é devolvido, mas a cobrança em um clique não abre assinatura: o checkout que vira a primeira cobrança de uma recorrência é o que pede o cartão ao comprador.

**Dá para oferecer upsell em um clique depois de uma cobrança de recorrência?** Não. A cobrança de recorrência não deixa cartão guardado, então `one_click_from` com o id dela devolve `one_click: false` e o comprador digita o cartão. Veja [Upsell em um clique](/docs/cartao/oneclick).

**Em quais adquirentes funciona?** Na **Apex** e na **Vortex**. Mandar `recurrence` em outra devolve `422 recurrence_not_supported`, dizendo qual aceita. Nada é criado. Na Vortex, a [integração direta por API](/docs/cartao/vortex-direto#recorrencia) também aceita.

**Serve para Pix?** Não. Recorrência existe só no cartão.

## Referência dos campos

| Campo | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
| `recurrence.cycle` | corpo do `POST /elements/checkout` | string | sim, dentro do objeto | um dos sete ciclos |
| `recurrence.max_payments` | idem | inteiro de 2 a 120 | não | teto de cobranças, contando a primeira |
| `recurrence_id` | resposta `201` | string | só quando `recurrence` foi enviado | identificador da assinatura (`rec_` e 24 caracteres) |
| `cycle` | resposta `201` | string | idem | o ciclo gravado |
| `next_charge_at` | resposta `201` | data ISO 8601, em UTC | idem | estimativa da próxima cobrança |
