Visão geral
O recurso de Assinaturas (Subscriptions) orquestra cobranças recorrentes de ponta a ponta: ele agrupa um cliente, um ou mais itens recorrentes e um método de pagamento, e a Selectwin gera e cobra auto
O recurso de Assinaturas (Subscriptions) orquestra cobranças recorrentes de ponta a ponta: ele agrupa um cliente, um ou mais itens recorrentes e um método de pagamento, e a Selectwin gera e cobra automaticamente cada ciclo de faturamento, emitindo webhooks a cada mudança de estado. Use-o para planos mensais/anuais, períodos de teste (trial), assinaturas com vários itens (add-ons, upsells) e divisão de receita (splits).
O que é uma assinatura
Pense em uma assinatura como um contrato de cobrança que se repete. Você a cria uma vez; a partir daí a Selectwin:
- gera um ciclo (
cyc_...) a cada período de faturamento (mensal, anual, etc.); - cobra cada ciclo gerando uma transação (
tra_...) — visível emcurrentChargena criação; - avança o status da assinatura conforme o pagamento é aprovado, falha ou esgota retentativas;
- dispara webhooks a cada transição, para você reagir sem fazer polling.
Você controla o catálogo (variantes), as quantidades, os splits e os metadados; a Selectwin controla o relógio de cobrança.
Modelo orientado a catálogo (Stripe-strict)
A criação de assinaturas é orientada ao catálogo: o preço vem das variantes recorrentes (var_...), não de valores digitados na hora. Por isso, no POST /v1/subscriptions, cada item referencia uma variante por id e você só ajusta quantity — unitPrice, currency e a agenda de cobrança derivam da variante. Itens manuais e precificação avulsa são rejeitados. Os detalhes e os error.code estão em Criar Assinatura.
Modelo do objeto
O exemplo abaixo é a forma completa retornada por Consultar (GET /v1/subscriptions/{id}). A criação (Create) devolve um corpo parecido, acrescido de currentCharge (a transação da 1ª cobrança); a Listagem devolve uma projeção mais leve de cada assinatura (sem customer/billing.address completos).
{
"id": "subs_01hqzvabc", // ID opaco da assinatura (prefixo subs_)
"status": "active", // estado atual (ver Ciclo de vida)
"currency": "BRL", // ISO 4217 — atualmente apenas BRL
"method": "credit", // método de cobrança: credit | billet | pix
"type": "prepaid", // modelo de faturamento da assinatura
"currentCycle": { // ciclo de cobrança vigente
"id": "cyc_01hqzvabc",
"cycle": 3, // número sequencial do ciclo (1, 2, 3, …)
"status": "billed", // estado do ciclo
"startDate": "2026-04-01T00:00:00.000Z",
"endDate": "2026-04-30T23:59:59.000Z",
"dueDate": "2026-04-01T00:00:00.000Z", // vencimento da cobrança do ciclo
"billedAt": "2026-04-01T10:15:00.000Z", // quando o ciclo foi cobrado (null se ainda não)
"updatedAt": "2026-04-12T17:56:33.000Z",
"createdAt": "2026-04-01T00:00:00.000Z"
},
"customer": { // cliente associado
"id": "cus_01hqzvabc",
"firstName": "João",
"lastName": "Silva",
"email": "[email protected]",
"document": { "type": "cpf", "number": "12345678901" },
"delinquent": false, // true se o cliente tem cobrança em aberto
"externalReference": "CRM-USER-001"
},
"billing": { // agenda + endereço de cobrança
"frequency": "monthly", // periodicidade (deriva da variante)
"frequencyCount": 1, // a cada N períodos
"endDate": null, // data de término (null = sem fim)
"exactDay": null, // dia fixo de cobrança, se configurado
"freeTrialDays": 0, // dias de trial antes da 1ª cobrança
"address": { "street": "Av. Paulista", "number": "1000", "city": "São Paulo", "state": "SP", "country": "BR", "postcode": "01310-100" }
},
"discount": { // desconto aplicado (cupom ou avulso)
"value": 500, // 500 = R$ 5,00 quando type=flat
"type": "flat", // "flat" (centavos) ou "percentage"
"percentageOfAmount": null
},
"shippable": false,
"shipping": null,
"spplited": true, // true se há divisão de receita (splits)
"splits": [ // regras de repasse (ver Splits)
{ "id": "split_01hqzvabc", "recipient": "bus_9876543210", "type": "percentage", "value": 10, "chargeProcessingFee": false, "liable": true }
],
"items": [ // itens recorrentes da assinatura
{
"id": "item_01hqzvabc", // ID da linha (item_), não da variante
"quantity": 1,
"unitPrice": 9900, // preço unitário em centavos (R$ 99,00)
"pricingSchema": "unit",
"name": "Premium Plan",
"enabled": true,
"currency": "BRL"
}
],
"callback": { "webhookUrl": "https://example.com/webhook", "active": true },
"externalReference": "SUB-1001", // sua referência externa
"metadata": { "campaign": "launch" }, // pares chave/valor (até 40 chaves)
"updatedAt": "2026-04-12T17:56:33.000Z",
"createdAt": "2026-04-12T17:56:33.000Z",
"merchant": { "name": "Seller Name", "merchantId": "bus_1234567890", "isSubAccount": false },
"_links": { } // links HATEOAS para próximas ações
}Importante
Dinheiro sempre em centavos inteiros (9900 = R$ 99,00) e datas em ISO 8601 UTC (sufixo Z). IDs são opacos — guarde a string inteira, não faça parsing do prefixo. Veja Convenções.
Campos principais
| Campo | Tipo | Descrição |
|---|---|---|
id | string | ID da assinatura (subs_...), opaco. |
status | string | Estado atual da assinatura. Veja Ciclo de vida. |
currency | string | Moeda ISO 4217 — atualmente BRL. |
method | string | Método de cobrança recorrente: credit, billet ou pix. |
type | string | Modelo de faturamento da assinatura (ex.: prepaid). |
currentCycle | object | Ciclo de cobrança vigente — ver tabela abaixo. |
currentCharge | object | Só no create. A transação (tra_...) da primeira cobrança, com status, payment e timeline. |
customer | object | Cliente associado (cus_...). Em listas vem só customerId. |
billing | object | Agenda de cobrança (frequency, frequencyCount, freeTrialDays, endDate, exactDay) e address. |
discount | object | Desconto: value (centavos ou %), type (flat ou percentage). |
shippable / shipping | boolean / object | Se a assinatura entrega produto físico e os dados de envio. |
spplited | boolean | true se há splits configurados. |
splits | array | Regras de divisão de receita. Veja Splits. |
items | array | Itens recorrentes (item_...) com quantity, unitPrice, name. Veja Itens. |
callback.webhookUrl | string | URL para callbacks de status da assinatura/ciclo. |
externalReference | string | Sua referência externa para correlação. |
metadata | object | Pares chave/valor (até 40 chaves). |
merchant | object | Vendedor dono do recurso (merchantId, isSubAccount). |
_links | object | Links HATEOAS (self, cancel, list, create) para as próximas ações. |
Campos de currentCycle
| Campo | Tipo | Descrição |
|---|---|---|
id | string | ID do ciclo (cyc_...). |
cycle | integer | Número sequencial do ciclo (1, 2, 3, …). |
status | string | Estado do ciclo (ex.: billed, paid, canceled). |
startDate / endDate | date-time | Início e fim do período coberto pelo ciclo. |
dueDate | date-time | Vencimento da cobrança do ciclo. |
billedAt | date-time | Quando o ciclo foi cobrado (null se ainda não). |
Ciclo de vida
O status da assinatura é o que você acompanha para saber se a receita está fluindo. Os valores possíveis (também aceitos como filtro status em Listar) são:
| Status | Descrição |
|---|---|
pending | Criada, aguardando a confirmação da primeira cobrança. |
trialing | Em período de teste (trial), antes da primeira cobrança efetiva. |
active | Ativa e em dia. |
pastdue | A cobrança de um ciclo falhou; a assinatura está em retentativa. |
unpaid | Retentativas esgotadas sem pagamento. |
paused | Pausada (não gera cobrança até ser retomada). |
canceled | Cancelada — não gera novos ciclos. |
Dica
Não fique consultando o status em loop. Reaja aos webhooks de assinatura (transições de estado e renovações de ciclo) — é mais rápido e econômico. Veja Proibição de Polling e o catálogo em Webhook Events.
Operações disponíveis
Base URL: https://api.selectwin.io/v1. Todas as chamadas autenticam pelo header SelectKey (nunca Authorization: Bearer/Basic) — veja Autenticação.
| Operação | Método e caminho | Página |
|---|---|---|
| Criar assinatura | POST /v1/subscriptions | Criar |
| Listar assinaturas | GET /v1/subscriptions | Listar |
| Consultar assinatura | GET /v1/subscriptions/{subscriptionId} | Consultar |
| Cancelar assinatura | DELETE /v1/subscriptions/{subscriptionId} | Cancelar |
| Listar ciclos | GET /v1/subscriptions/{subscriptionId}/cycles | Ciclos |
| Renovar/cobrar ciclo | POST /v1/subscriptions/{subscriptionId}/cycles | Ciclos |
| Consultar um ciclo | GET /v1/subscriptions/{subscriptionId}/cycles/{cycleId} | Ciclos |
| Listar itens | GET /v1/subscriptions/{subscriptionId}/items | Itens |
| Adicionar item | POST /v1/subscriptions/{subscriptionId}/items | Itens |
| Consultar item | GET /v1/subscriptions/{subscriptionId}/items/{itemId} | Itens |
| Atualizar item | PUT /v1/subscriptions/{subscriptionId}/items/{itemId} | Itens |
| Remover item | DELETE /v1/subscriptions/{subscriptionId}/items?itemId=... | Itens |
| Listar splits | GET /v1/subscriptions/{subscriptionId}/splits | Splits |
| Adicionar split | POST /v1/subscriptions/{subscriptionId}/splits | Splits |
| Consultar split | GET /v1/subscriptions/{subscriptionId}/splits/{splitId} | Splits |
| Atualizar split | PUT /v1/subscriptions/{subscriptionId}/splits/{splitId} | Splits |
| Remover split | DELETE /v1/subscriptions/{subscriptionId}/splits?splitId=... | Splits |
Remover item e remover split usam query string (
?itemId=.../?splitId=...), não o ID no caminho. Veja as páginas respectivas.
Exemplo: consultar uma assinatura
curl https://api.selectwin.io/v1/subscriptions/subs_01hqzvabc \
-H "SelectKey: sl_live_aBcDeFgHiJkLmNoPqRsTuVwXyZ"Em sandbox, a chave começa com sl_test_. Em requisições com corpo (criar, adicionar item, etc.), envie também Content-Type: application/json.
Conceitos e relações
- Variantes recorrentes (
var_...) — definem preço, moeda e agenda de cobrança. Os itens da assinatura referenciam variantes; é o catálogo de Produtos & Variantes que governa o valor cobrado. - Ciclos (
cyc_...) — cada período de faturamento. A assinatura sempre expõe ocurrentCycle; o histórico está em Ciclos. - Transações (
tra_...) — cada ciclo cobrado gera uma transação. Na criação, ela aparece emcurrentCharge. - Clientes (
cus_...) — toda assinatura pertence a um cliente. Você pode informarcustomer.id(existente) ou os dados completos para criação implícita. - Cupons / descontos (
dis_...) — aplicáveis viadiscount(poridde cupom existente ou desconto avulsoflat/percentage). - Splits (
split_...) — dividem a receita de cada cobrança entre destinatários, porpercentage(0–100) ouflat(centavos). Veja Splits. - Webhooks — a forma recomendada de acompanhar mudanças. Configure
callback.webhookUrlna assinatura ou endpoints globais; o catálogo de eventos e a verificação de assinatura estão em Webhook Events.
Tratamento de erros
Trate sempre pelo error.code (estável), nunca pela message. Além dos transversais — 401 (unauthorized), 403 (forbidden), 422 (unprocessableEntity), 429 (tooManyRequests), 500 (serverError) —, a criação de assinaturas tem códigos próprios do modelo orientado a catálogo:
error.code | HTTP | Quando ocorre |
|---|---|---|
billingNotAcceptedInStripeStrict | 422 | Você enviou campos de precificação manual em billing[*]. |
amountOnlyNotAllowedInSubscription | 422 | Você enviou amount no corpo da assinatura (o preço vem da variante). |
manualItemNotAllowedInSubscription | 422 | Um item não referencia variante (id ausente). |
oneTimeVariantNotAllowedInSubscription | 422 | Você usou uma variante avulsa (não recorrente) na assinatura. |
variantScheduleDivergent | 422 | Os itens referenciam variantes com agendas de cobrança divergentes entre si. |
O catálogo completo (incluindo os transversais e o envelope de erro) está em Códigos de Erro.
Boas práticas
- Modele o preço no catálogo, não na assinatura. Crie variantes recorrentes e referencie-as nos
items; assim você reaproveita preço/agenda e evita os erros*NotAllowedInSubscription. - Garanta agendas consistentes. Todos os itens de uma mesma assinatura devem ter a mesma periodicidade — variantes divergentes geram
variantScheduleDivergent. - Use idempotência ao criar. Envie
X-Idempotency-KeynoPOSTpara não duplicar assinaturas em caso de retry de rede. Veja Idempotência. - Reaja a webhooks, não faça polling das transições de status e renovações de ciclo. Veja Proibição de Polling.
- Trate
pastdue/unpaidativamente. Notifique o cliente para atualizar o método de pagamento antes que as retentativas se esgotem e a assinatura caia paraunpaid/canceled. - Correlacione com seu sistema via
externalReferenceemetadata(até 40 chaves) — facilita reconciliação e suporte sem depender dosubs_id. - Some os splits com cuidado. Acompanhe
remainingPercentage/remainingAmountretornados ao adicionar splits para não ultrapassar 100% da receita. Veja Splits.
Veja também
- Criar Assinatura — corpo completo, regras do catálogo e exemplos.
- Listar · Consultar · Cancelar
- Ciclos · Itens · Splits
- Convenções · Autenticação · Códigos de Erro
- Idempotência · Paginação · Proibição de Polling
- Webhook Events — catálogo de eventos e verificação de assinatura.
How is this guide?