# Assinar um plano (criar assinatura)

URL: https://staging.pagpolar.com/docs/referencia/assinaturas/create-subscription

> Cria uma assinatura de verdade para um cliente em uma oferta de plano existente. `id`
pode ser o id (uuid) **ou** o identifier da oferta de plano — mesma resolução usada em
`GET /offers/{identifier}`.

Só aceita **cartão de crédito**.

A cobrança do cartão é feita no gateway **depois** da resposta desta requisição: a
assinatura retorna com `status: DRAFT`. O webhook `SUBSCRIPTION_CONFIRMED` avisa que o
gateway aceitou a assinatura — o status continua `DRAFT` — e ela vira `ACTIVE` quando a
primeira fatura é paga. Se o gateway recusar, o webhook é `SUBSCRIPTION_FAILED` e o status
vira `FAILED`. Como alternativa aos webhooks, faça polling em `GET /subscriptions/{id}`.

O header `Idempotency-Key` é **obrigatório**. Em caso de timeout, reenvie a requisição
com a mesma chave: a resposta original será devolvida sem criar uma segunda assinatura.

**Uma assinatura não é cobrada diretamente — cada ciclo cobrado (o primeiro e todas as
renovações seguintes) gera uma `Transaction` própria**, a mesma entidade retornada por
`GET /sales`/`GET /sales/{identifier}`. Ou seja, para acompanhar os pagamentos de uma
assinatura ao longo do tempo, use os eventos de transação (`TRANSACTION_PAID`,
`TRANSACTION_CANCELED`, etc.) e `GET /sales` filtrando pelo cliente/período — os eventos
de assinatura (`SUBSCRIPTION_*`) informam mudanças de status da assinatura em si, não de
cada cobrança individual.

`POST /plans/offer/{id}/subscribe`

## Autenticação

- Token Bearer no header `Authorization` (esquema `BearerAuth`). Token de acesso devolvido por POST /auth/token. Envie como "Authorization: Bearer <token>". Vale 24 horas.

## Parâmetros de caminho

| Parâmetro | Tipo | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `id` | texto | sim | Exemplo: `b9c0d1e2-f3a4-4b5c-6d7e-8f9a0b1c2d3e`. |

## Parâmetros de header

| Parâmetro | Tipo | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `Idempotency-Key` | texto | sim | Exemplo: `2f1c4d2e-8f4a-4c1e-9f7b-6a2d1e3c5b90`. |

## Corpo da requisição

Content-type: `application/json`.

| Campo | Tipo | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `installments` | inteiro | sim | O máximo real pode ser menor que 12: é limitado pela configuração da oferta (consulte max_credit_card_installments em GET /offers/{identifier}). Acima do limite da oferta, retorna 400. Exemplo: `3`. |
| `customer` | objeto | sim | — |
| `customer.name` | texto | sim | Exemplo: `Fulano de Tal`. |
| `customer.email` | texto (email) | sim | Exemplo: `fulano@exemplo.com`. |
| `customer.document` | texto | sim | CPF (11 dígitos) ou CNPJ (14 dígitos), com ou sem pontuação: `12345678909` ou `123.456.789-09`. A API grava só os dígitos. Fora disso, 400. Exemplo: `12345678909`. |
| `customer.phone` | texto | sim | DDD e número, com 10 ou 11 dígitos (12 ou 13 com o código do país 55). Pontuação, espaços, parênteses e `+` são aceitos: `11999998888`, `(11) 99999-8888` ou `+55 11 99999-8888`. A API grava só os dígitos. Fora disso, 400. Exemplo: `11999999999`. |
| `address` | objeto | não | Obrigatório quando a oferta é de produto físico (`requires_shipping: true`); nos demais casos é opcional e não é usado no processamento da venda. |
| `address.street` | texto | sim | Exemplo: `Rua das Flores`. |
| `address.number` | texto | sim | Exemplo: `123`. |
| `address.complement` | texto | não | Exemplo: `Apto 4B`. Pode ser nulo. |
| `address.neighborhood` | texto | sim | Exemplo: `Centro`. |
| `address.city` | texto | sim | Exemplo: `São Paulo`. |
| `address.state` | texto | sim | Exemplo: `SP`. |
| `address.postal_code` | texto | sim | Exemplo: `01000-000`. |
| `credit_card` | objeto | sim | Dados do cartão de crédito usado na cobrança. |
| `credit_card.holder_name` | texto | sim | Exemplo: `FULANO DE TAL`. |
| `credit_card.holder_document` | texto | sim | CPF (11 dígitos) ou CNPJ (14 dígitos) do titular do cartão, com ou sem pontuação. A API grava só os dígitos. Fora disso, 400. Exemplo: `12345678909`. |
| `credit_card.number` | texto | sim | Exemplo: `4111111111111111`. |
| `credit_card.expiration_month` | inteiro | sim | Exemplo: `12`. |
| `credit_card.expiration_year` | inteiro | sim | Exemplo: `2030`. |
| `credit_card.cvv` | texto | sim | Exemplo: `123`. |
| `buyer_ip` | texto | não | IP do comprador final. Melhora a análise antifraude. Exemplo: `203.0.113.10`. |
| `buyer_user_agent` | texto | não | — |
| `affiliate_identifier` | texto | não | Código do afiliado que trouxe a venda, no formato `PAO` seguido de 10 dígitos. Formato inválido retorna `400`. Código de afiliado inexistente, de outro produto, inativo ou sem a oferta liberada é **ignorado**: a venda é processada normalmente, sem afiliado. Não há cookie nem regra de primeiro ou último clique — vale o código enviado. Exemplo: `PAO1234567890`. |
| `external_reference` | texto | não | Referência do pedido no seu sistema (por exemplo, o número do pedido). Opcional. Depois você consulta a venda por ela em `GET /sales/{identifier}` e filtra em `GET /sales?external_reference=`. Pode se repetir entre pedidos: a consulta devolve a venda mais recente com essa referência. Exemplo: `PED-2026-0001`. |

### Exemplo do corpo

Assinar plano mensal:

```json
{
  "installments": 1,
  "customer": {
    "name": "Fulano de Tal",
    "email": "fulano@exemplo.com",
    "document": "12345678909",
    "phone": "11999999999"
  },
  "credit_card": {
    "holder_name": "FULANO DE TAL",
    "holder_document": "12345678909",
    "number": "4111111111111111",
    "expiration_month": 12,
    "expiration_year": 2030,
    "cvv": "123"
  },
  "buyer_ip": "203.0.113.10"
}
```

## Respostas

### 201 — Assinatura criada (status inicial DRAFT, aguardando confirmação do gateway)

| Campo | Tipo | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `data` | [Assinatura](/docs/referencia/entidades/assinatura) | não | — |

#### Exemplo

default:

```json
{
  "data": {
    "id": "f7a8b9c0-d1e2-4f3a-4b5c-6d7e8f9a0b1c",
    "status": "DRAFT",
    "payment_method": "CREDIT_CARD",
    "start_at": null,
    "next_billing_at": null,
    "next_billing_amount": null,
    "total_amount": null,
    "canceled_at": null,
    "created_at": "2026-01-15T12:00:00.000Z"
  }
}
```

## Erros

| Status | Descrição |
| --- | --- |
| `400` | Dados inválidos, Idempotency-Key ausente, número de parcelas acima do limite da oferta, ou documento/telefone fora do formato (CPF 11 dígitos, CNPJ 14, telefone 10 a 13 dígitos) |
| `401` | Token ausente, inválido ou expirado, ou credencial revogada ou expirada. Chame POST /auth/token para obter um token novo. |
| `403` | IP não autorizado |
| `404` | Oferta de plano não encontrada |
| `409` | Oferta inativa/expirada, método não habilitado ou requisição idêntica em processamento |
| `429` | Limite de requisições excedido |
| `503` | Serviço de limite indisponível — repita a requisição com a mesma Idempotency-Key |

Lista completa de códigos e como tratá-los: [Erros](/docs/guias/fundamentos/erros).
