SelectwinDOCS
Assinaturas

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 em currentCharge na 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 quantityunitPrice, 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

CampoTipoDescrição
idstringID da assinatura (subs_...), opaco.
statusstringEstado atual da assinatura. Veja Ciclo de vida.
currencystringMoeda ISO 4217 — atualmente BRL.
methodstringMétodo de cobrança recorrente: credit, billet ou pix.
typestringModelo de faturamento da assinatura (ex.: prepaid).
currentCycleobjectCiclo de cobrança vigente — ver tabela abaixo.
currentChargeobjectSó no create. A transação (tra_...) da primeira cobrança, com status, payment e timeline.
customerobjectCliente associado (cus_...). Em listas vem só customerId.
billingobjectAgenda de cobrança (frequency, frequencyCount, freeTrialDays, endDate, exactDay) e address.
discountobjectDesconto: value (centavos ou %), type (flat ou percentage).
shippable / shippingboolean / objectSe a assinatura entrega produto físico e os dados de envio.
spplitedbooleantrue se há splits configurados.
splitsarrayRegras de divisão de receita. Veja Splits.
itemsarrayItens recorrentes (item_...) com quantity, unitPrice, name. Veja Itens.
callback.webhookUrlstringURL para callbacks de status da assinatura/ciclo.
externalReferencestringSua referência externa para correlação.
metadataobjectPares chave/valor (até 40 chaves).
merchantobjectVendedor dono do recurso (merchantId, isSubAccount).
_linksobjectLinks HATEOAS (self, cancel, list, create) para as próximas ações.

Campos de currentCycle

CampoTipoDescrição
idstringID do ciclo (cyc_...).
cycleintegerNúmero sequencial do ciclo (1, 2, 3, …).
statusstringEstado do ciclo (ex.: billed, paid, canceled).
startDate / endDatedate-timeInício e fim do período coberto pelo ciclo.
dueDatedate-timeVencimento da cobrança do ciclo.
billedAtdate-timeQuando 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:

StatusDescrição
pendingCriada, aguardando a confirmação da primeira cobrança.
trialingEm período de teste (trial), antes da primeira cobrança efetiva.
activeAtiva e em dia.
pastdueA cobrança de um ciclo falhou; a assinatura está em retentativa.
unpaidRetentativas esgotadas sem pagamento.
pausedPausada (não gera cobrança até ser retomada).
canceledCancelada — 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çãoMétodo e caminhoPágina
Criar assinaturaPOST /v1/subscriptionsCriar
Listar assinaturasGET /v1/subscriptionsListar
Consultar assinaturaGET /v1/subscriptions/{subscriptionId}Consultar
Cancelar assinaturaDELETE /v1/subscriptions/{subscriptionId}Cancelar
Listar ciclosGET /v1/subscriptions/{subscriptionId}/cyclesCiclos
Renovar/cobrar cicloPOST /v1/subscriptions/{subscriptionId}/cyclesCiclos
Consultar um cicloGET /v1/subscriptions/{subscriptionId}/cycles/{cycleId}Ciclos
Listar itensGET /v1/subscriptions/{subscriptionId}/itemsItens
Adicionar itemPOST /v1/subscriptions/{subscriptionId}/itemsItens
Consultar itemGET /v1/subscriptions/{subscriptionId}/items/{itemId}Itens
Atualizar itemPUT /v1/subscriptions/{subscriptionId}/items/{itemId}Itens
Remover itemDELETE /v1/subscriptions/{subscriptionId}/items?itemId=...Itens
Listar splitsGET /v1/subscriptions/{subscriptionId}/splitsSplits
Adicionar splitPOST /v1/subscriptions/{subscriptionId}/splitsSplits
Consultar splitGET /v1/subscriptions/{subscriptionId}/splits/{splitId}Splits
Atualizar splitPUT /v1/subscriptions/{subscriptionId}/splits/{splitId}Splits
Remover splitDELETE /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 o currentCycle; o histórico está em Ciclos.
  • Transações (tra_...) — cada ciclo cobrado gera uma transação. Na criação, ela aparece em currentCharge.
  • Clientes (cus_...) — toda assinatura pertence a um cliente. Você pode informar customer.id (existente) ou os dados completos para criação implícita.
  • Cupons / descontos (dis_...) — aplicáveis via discount (por id de cupom existente ou desconto avulso flat/percentage).
  • Splits (split_...) — dividem a receita de cada cobrança entre destinatários, por percentage (0–100) ou flat (centavos). Veja Splits.
  • Webhooks — a forma recomendada de acompanhar mudanças. Configure callback.webhookUrl na 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.codeHTTPQuando ocorre
billingNotAcceptedInStripeStrict422Você enviou campos de precificação manual em billing[*].
amountOnlyNotAllowedInSubscription422Você enviou amount no corpo da assinatura (o preço vem da variante).
manualItemNotAllowedInSubscription422Um item não referencia variante (id ausente).
oneTimeVariantNotAllowedInSubscription422Você usou uma variante avulsa (não recorrente) na assinatura.
variantScheduleDivergent422Os 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

  1. 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.
  2. Garanta agendas consistentes. Todos os itens de uma mesma assinatura devem ter a mesma periodicidade — variantes divergentes geram variantScheduleDivergent.
  3. Use idempotência ao criar. Envie X-Idempotency-Key no POST para não duplicar assinaturas em caso de retry de rede. Veja Idempotência.
  4. Reaja a webhooks, não faça polling das transições de status e renovações de ciclo. Veja Proibição de Polling.
  5. Trate pastdue/unpaid ativamente. Notifique o cliente para atualizar o método de pagamento antes que as retentativas se esgotem e a assinatura caia para unpaid/canceled.
  6. Correlacione com seu sistema via externalReference e metadata (até 40 chaves) — facilita reconciliação e suporte sem depender do subs_id.
  7. Some os splits com cuidado. Acompanhe remainingPercentage/remainingAmount retornados ao adicionar splits para não ultrapassar 100% da receita. Veja Splits.

Veja também

How is this guide?

On this page