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

# Assinaturas

> PIX recorrente amarrado a um produto, com a cobrança sendo gerada sozinha.

Assinatura é PIX recorrente. Você cria uma vez, escolhe a frequência, e a cobrança passa
a ser gerada automaticamente. Cada cobrança gerada dispara o webhook na mesma
`callbackUrl`.

<Note>
  Assinatura sempre nasce de um produto cadastrado. O valor e o nome saem dele, então
  antes de criar a assinatura você precisa de um `productId` ativo. Veja
  [Produtos](/guias/produtos).
</Note>

## Criando

```bash theme={null}
curl -X POST https://api.purincash.com/v1/subscriptions \
  -H "Authorization: Bearer $PURINCASH_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "productId": "65f0c2a1e4b0a1b2c3d4e5f6",
    "customer": { "name": "João Silva", "externalId": "user_42" },
    "frequency": "MONTHLY",
    "dayGenerateCharge": 15,
    "callbackUrl": "https://minhaloja.com/webhooks/purincash",
    "metadata": "{\"plano\":\"premium\"}"
  }'
```

<ParamField body="productId" type="string" required>
  Produto ativo que define valor e nome da assinatura.
</ParamField>

<ParamField body="customer.name" type="string" required>
  Nome do assinante. Aqui ele é obrigatório, diferente do resto da API.
</ParamField>

<ParamField body="frequency" type="string" default="MONTHLY">
  `WEEKLY`, `MONTHLY`, `SEMIANNUALLY` ou `ANNUALLY`.
</ParamField>

<ParamField body="dayGenerateCharge" type="integer">
  Dia do mês em que a cobrança é gerada, entre 4 e 28.
</ParamField>

<ParamField body="callbackUrl" type="string">
  Recebe o webhook de **cada** cobrança da assinatura, não só da primeira.
</ParamField>

<ParamField body="metadata" type="string">
  String JSON de até 2 KB, devolvida sem alteração em toda cobrança.
</ParamField>

```json Resposta theme={null}
{
  "paymentId": "psa_sub_a1b2c3d4",
  "status": "pending",
  "type": "subscription",
  "subscriptionId": "sub_9f8e7d6c",
  "amountCents": 4990,
  "currency": "BRL",
  "productName": "Plano Premium",
  "frequency": "MONTHLY",
  "environment": "live",
  "pix": {
    "brCode": "00020126580014br.gov.bcb.pix...",
    "paymentLinkUrl": "https://pay.exemplo.com/sub_9f8e7d6c"
  },
  "dayGenerateCharge": 15
}
```

<Tip>
  O `dayGenerateCharge` vai até 28 de propósito. Assinatura marcada para dia 30 pularia
  fevereiro, e isso é uma classe inteira de bug que ninguém quer no faturamento.
</Tip>

## Por que 4 a 28, e não 1 a 31

O limite inferior existe porque a cobrança precisa de alguns dias de antecedência para o
cliente pagar antes do vencimento. O superior evita mês sem aquele dia. Se o seu produto
tem data comercial fixa fora dessa faixa, o caminho é gerar a cobrança você mesmo com
`POST /v1/payments` no dia que quiser.

## Acompanhando

```bash theme={null}
curl "https://api.purincash.com/v1/subscriptions?limit=20&status=paid" \
  -H "Authorization: Bearer $PURINCASH_KEY"
```

A listagem aceita `limit` (1 a 100, padrão 50), `offset` e `status`.

```json theme={null}
{
  "subscriptions": [
    {
      "paymentId": "psa_sub_a1b2c3d4",
      "subscriptionId": "sub_9f8e7d6c",
      "status": "pending",
      "amountCents": 4990,
      "currency": "BRL",
      "productName": "Plano Premium",
      "customer": { "name": "João Silva", "email": "", "externalId": "user_42" },
      "metadata": "{\"plano\":\"premium\"}",
      "paidAt": null,
      "createdAt": "2026-03-18T10:00:00.000Z"
    }
  ],
  "total": 5,
  "limit": 20,
  "offset": 0
}
```

## Controlando o acesso do assinante

A API não bloqueia o cliente sozinho. Quem decide se o acesso continua é você, e o dado
que sustenta essa decisão é o webhook.

<Steps>
  <Step title="Guarde o subscriptionId no seu usuário">
    É a chave estável entre as cobranças. O `paymentId` muda a cada ciclo.
  </Step>

  <Step title="Renove a validade a cada pagamento">
    Ao receber o webhook com `status: "paid"`, empurre a data de expiração do acesso para
    frente conforme a frequência.
  </Step>

  <Step title="Deixe o acesso expirar sozinho">
    Se o ciclo passou sem pagamento, a data vence e o acesso cai. É mais confiável do que
    tentar reagir a um evento de cancelamento.
  </Step>
</Steps>

<Warning>
  Sempre confirme por `subscriptionId` antes de renovar. Um assinante com duas assinaturas
  ativas do mesmo produto é raro, mas acontece, e renovar pelo produto em vez da
  assinatura dá acesso de graça.
</Warning>
