PagnovoPagnovodocs

Subscriptions

Subscriptions (visão geral)

Subscription é a representação de uma assinatura recorrente: contém o cliente, o valor cobrado por ciclo, o ciclo (mensal, anual, etc.) e quando a próxima cobrança vai acontecer. Toda Subscription é dona de uma sequência de Invoices — uma por ciclo.

Uma Subscription tipicamente nasce do Checkout de uma Offer recorrente (URL pública /o/seu-user/:slug), mas você também pode criar diretamente via POST /v2/subscriptions (útil pra migrar clientes de outro sistema, ou pra cenários B2B com assinatura standalone — sem Offer, com amount e ciclo definidos direto pelo Customer).

Subscription criada → nextBillingAt chega → cron gera Invoice → cliente paga → marca PAID
                                                ↓ (se não paga)
                                          status: OVERDUE / PAST_DUE
                                                ↓
                              retry baseado em daysBeforeDueToBill

Snapshot pattern

Quando você cria uma Subscription a partir de uma Offer (offerId: "off_xyz..."), a Pagnovo copia amount, billingCycle, billingCycleCount e maxCycles da Offer pra dentro da Subscription. A partir daí, a Subscription tem vida própria — alterações posteriores na Offer não afetam essa Subscription.

Mais ainda: quando você edita uma Subscription via PATCH /v2/subscriptions/:id, as mudanças só valem a partir da próxima cobrança. Invoices já criadas (PENDING, PAID, OVERDUE) ficam congeladas com os valores que tinham no momento da criação.

Cenários comuns:

  • Aumentar valor: a próxima invoice gerada vai com o valor novo; a Invoice deste mês (já criada) mantém o valor antigo.
  • Mudar lateFeeValue: invoices futuras usam a nova multa; invoices que já estão vencidas mantêm a multa do momento em que foram geradas.
  • Mudar nextBillingAt: empurra ou antecipa a próxima cobrança. Não mexe nas Invoices já existentes.

Isso garante que o cliente nunca seja cobrado retroativamente — o histórico reflete o que foi acordado em cada momento.

Estados da Subscription

StatusO que significaAceita pause?Aceita resume?Próxima invoice?
TRIALPeríodo de teste em andamento (definido por trialDays da Offer ou nextBillingAt setado pra futuro).Quando nextBillingAt chegar
ACTIVEEm cobrança regular. Última invoice paga ou ainda dentro do prazo.Sim, no nextBillingAt
PAST_DUEÚltima invoice venceu e não foi paga. Sub continua tentando.Sim, conforme daysBeforeDueToBill
PAUSEDVocê pausou manualmente. Não gera novas invoices.Não
CANCELEDEncerrada (manualmente via /cancel ou por exceder maxCycles/expiresAt). Final.Não
EXPIREDChegou em expiresAt. Auto-transição. Final.Não

Pause vs cancel:

  • Pause (POST /:id/pause) — para temporariamente. Pode reativar via POST /:id/resume; se nextBillingAt já está no passado, ele é reagendado pro próximo ciclo a partir de agora.
  • Cancel (POST /:id/cancel) — final. Cancela todas as invoices PENDING, OVERDUE e DRAFT da subscription em transação atômica.

Cancele quando o cliente saiu de vez. Pause quando ele pode voltar.

Ciclo de cobrança

A Pagnovo roda um job de billing recorrente que processa todas as Subscriptions com nextBillingAt chegando.

daysBeforeDueToBill (default 5) — quantos dias antes do vencimento o sistema gera a Invoice. Default: 5. Range: 0–60.

Ex: se nextBillingAt é dia 25, com daysBeforeDueToBill: 5, a Invoice é criada dia 20 com dueDate 25. O cliente recebe a fatura, tem 5 dias pra pagar.

daysBeforeDueToNotify (default 3) — quantos dias antes do vencimento o sistema envia notificação de lembrete (se notificações estiverem habilitadas).

Fluxo do cron:

  1. Cron acorda → busca todas Subscriptions com nextBillingAt <= now + daysBeforeDueToBill e status ACTIVE/PAST_DUE/TRIAL.
  2. Pra cada uma, cria uma nova Invoice com dueDate = nextBillingAt.
  3. Avança nextBillingAt para o próximo ciclo (+1 mês, +1 ano, etc).
  4. Incrementa currentCycle. Se currentCycle >= maxCycles, marca a Subscription como CANCELED após essa cobrança.
  5. Cliente final recebe notificação e tem até dueDate pra pagar.
  6. Se paga: Invoice → PAID. Subscription mantém ACTIVE.
  7. Se não paga até dueDate: Invoice → OVERDUE. Subscription → PAST_DUE. Multa e juros aplicam (se configurados).

Multas e juros

Quando uma Invoice fica em atraso, a Pagnovo pode aplicar multa única + juros diários proporcionais automaticamente.

lateFeeType — tipo de multa:

  • NONE (default) — sem multa.
  • FIXED — multa em valor absoluto. lateFeeValue em centavos. Ex: lateFeeValue: 500 = R$ 5,00 de multa.
  • PERCENTAGE — multa percentual sobre o valor da invoice. lateFeeValue em basis points (1.000 = 10%, 10.000 = 100%). Limite: LATE_FEE_PERCENT_MAX.

interestRatePerMonth — juros mensais aplicados proporcionalmente por dia de atraso. Em basis points. Ex: interestRatePerMonth: 100 = 1% ao mês = ~0,033% ao dia.

⚠️ Atenção: quando lateFeeType: "PERCENTAGE", lateFeeValue: 500 é 5%. Quando lateFeeType: "FIXED", lateFeeValue: 500 é R$ 5,00. Não confunda os dois — confira o tipo antes de mandar.

A multa/juro é aplicada apenas em invoices que entram em OVERDUE. Cada attempt da Invoice carrega o lateFeeApplied e interestApplied no momento da tentativa.

maxCycles vs expiresAt

Tem duas formas de fazer uma Subscription terminar sozinha:

maxCycles — limite numérico. Ex: maxCycles: 12 com billingCycle: "MONTHLY" = anual parcelado em 12 cobranças, depois encerra. Cron cancela a Subscription após a 12ª cobrança gerada.

expiresAt — data fixa. Ex: expiresAt: "2026-12-31T23:59:59Z" = a Subscription termina nessa data, independente de quantos ciclos foram cobrados.

Pode usar os dois juntos — o que acontecer primeiro encerra. Ou só um, ou nenhum (Subscription "infinita", típica de SaaS recorrente sem fim).