Skip to main content
Esta página é conceitual: explica o que determina quando cada fatura nasce e quando ela é cobrada. Os campos citados aqui são os mesmos que você envia ao criar uma assinatura — veja Assinaturas para o request completo e Faturas para o ciclo de vida de cada fatura.
Todas as datas internas do motor são normalizadas em UTC. O cálculo de ciclo é determinístico: depende apenas da data de início e da regra de recorrência (recurrence), sem relógio externo. Em transport (body/query), datas sempre viajam em ISO 8601 com offset — veja Convenções.

A regra de recorrência

Cada assinatura tem uma recurrence (herdada do preço do plano ou informada inline). Ela é o que define o tamanho do ciclo e o ponto de alinhamento das faturas. São cinco campos, e cada um responde a uma pergunta diferente: interval e unit andam juntos: 3 + month é trimestral. O anchor é o que decide se “mensal” quer dizer todo dia 15 ou a cada 30 dias a partir de quando assinou — a diferença está em Âncoras.
As âncoras day_of_month e end_of_month só fazem sentido com unit='month' ou unit='year'. Combiná-las com day/week é rejeitado na validação (“a cada 1 dia, todo dia 15” não tem semântica).

Âncoras

A âncora decide em que data cai o fim do ciclo atual — que é também o início do próximo ciclo e, por padrão, a data da próxima fatura.
O próximo ciclo é simplesmente início + intervalo. Preserva o horário (hora/min/seg) da data de início.Exemplo (unit=month, interval=1, início em 15/jan/2026 10:00):Para meses curtos vale o clamp de fim de mês (veja abaixo): início em 31/jan → próximo fim em 28/fev (ou 29/fev em ano bissexto). Diferente do day_of_month, o subscription_start não re-ancora no dia original: cada passo avança a partir do fim do ciclo anterior (já clampado), então depois de 28/fev o ciclo seguinte é 28/mar, depois 28/abr — o dia “encolhe” para o menor mês atravessado e não volta a 31.
Cobra sempre no dia anchorDay. A primeira fatura recorrente cai ao menos um intervalo à frente — nunca no mês corrente da assinatura. Isso evita ciclos curtos no arranque.Exemplo (unit=month, interval=1, anchorDay=10):Ou seja: compra dia 5 com âncora no dia 10 não cobra no dia 10 do mesmo mês — vai para o mês seguinte.
Se anchorDay for maior que o número de dias do mês alvo, o motor ajusta para o último dia do mês. anchorDay=31 em fevereiro vira 28/fev (ou 29/fev em ano bissexto). E como o alinhamento re-ancora no dia original a cada passo, não há drift: depois de 28/fev (31 clampado), o ciclo seguinte volta para 31/mar.
Cobra sempre no último dia de cada mês do ciclo, qualquer que seja seu tamanho.Exemplo (unit=month, interval=1, início em 10/jan):Assim como day_of_month, a primeira fatura recorrente cai um intervalo à frente, nunca no mês de início.
O horário (hora/minuto/segundo) da data de início é preservado ao avançar os ciclos. O clamp só mexe no dia, nunca no relógio.

Prepaid vs Postpaid

collectionTiming define onde, dentro do ciclo, a cobrança acontece.

prepaid (padrão)

Cobra no início de cada período. É o modelo clássico de SaaS/streaming: você paga pelo período que está começando.

postpaid

Cobra no fim de cada período. Modelo de consumo/utility: você paga pelo período que já passou.
No request de criação de assinatura há dois lugares que tratam timing:
  • collectionTiming no nível da assinatura — prepaid (default) ou postpaid.
  • collectionTiming dentro da própria recurrence — quando ausente, assume prepaid (retrocompatibilidade com preços antigos que não tinham o campo).
Ausência do campo sempre significa prepaid. Se você não definir nada, suas assinaturas cobram no início do ciclo.

Geração das faturas: just_in_time vs upfront

invoiceGenerationMode controla quantas faturas são criadas e quando.
invoiceGenerationMode='upfront' exige maxCycles informado (não pode ser nulo). Sem ele, a criação da assinatura é rejeitada na validação.
Em just_in_time, o número total de ciclos é limitado por maxCycles (quando informado); sem maxCycles, a assinatura é considerada perpétua e o agendador continua gerando uma fatura por ciclo indefinidamente.

Trial (período de teste)

trialSpec define um período inicial sem cobrança, e tem dois campos: durationDays, a duração em dias, e requiresPaymentMethod, que decide se o cartão é exigido para o teste começar. É o requiresPaymentMethod que muda o estado inicial. Com true e sem forma de pagamento, a assinatura nasce incomplete — não trialing — e expira em cerca de 23 horas se nada for anexado. Com false, o teste começa mesmo sem cartão, e a cobrança só é um problema no dia em que o teste acaba. Assinatura criada pelo checkout sempre chega com forma de pagamento, então a distinção não a alcança. Durante o trial a assinatura fica no status trialing e nenhuma fatura é cobrada. Ao final do trial, o motor gera a primeira fatura e a assinatura entra em cobrança normal.
trialSpec e bootstrapPayment são mutuamente exclusivos. Trial implica que o ciclo 1 ainda não foi cobrado (é o fim do trial que gera a 1ª fatura); bootstrapPayment significa que o ciclo 1 já foi pago externamente. Enviar os dois juntos é rejeitado.
O trialSpec no nível da assinatura tem precedência sobre o trial derivado de itens baseados em plano (que vem do preço). Use o override no nível da assinatura quando o trial é decidido fora do plano — por exemplo, checkout inline com itens sem preço associado.

Antecedência da cobrança

Uma fatura tem duas datas: quando ela é disparada para cobrança (chargeAt — o momento em que abre e o boleto ou o PIX é criado) e quando vence (dueAt). A distância entre as duas depende da forma de pagamento da assinatura: Exemplo: uma fatura de boleto que vence em 20/jun é disparada para cobrança em 18/jun, dando dois dias para o boleto circular antes do vencimento.
Esse chargeAt ainda passa pela política de cobrança do lojista, configurada no painel: a data pode ser deslocada para o próximo dia útil, e o horário fica dentro da janela comercial definida, no fuso horário dele. O ajuste mexe apenas no chargeAt — o dueAt contratual não muda.

Dunning — o que acontece quando a cobrança falha

Quando uma cobrança recorrente falha, o motor entra em dunning (régua de inadimplência): ele decide se reagenda uma nova tentativa ou se desiste e aplica a política final. Por padrão são três retentativas, com 3, 5 e 7 dias de espera — e esgotá-las encerra a recobrança daquela fatura, não a assinatura. A assinatura segue outra régua: fica past_due desde a primeira falha e só é marcada unpaid por um verificador periódico, quando a fatura vencida mais antiga passa do teto de inadimplência — 90 dias de atraso, por padrão. Todos esses números são ajustáveis pelo lojista no painel — a API não os lê nem os escreve —, então uma integração não deve tratá-los como fixos: leia o estado da assinatura em vez de prever datas.

Como a régua funciona

1

Cobrança falha

A fatura sai de open e vai para past_due. A tentativa é registrada com a categoria da recusa.
2

Ainda há retentativas?

Se ainda restam tentativas e a recusa não é definitiva, o motor agenda a próxima somando ao momento da falha o intervalo correspondente. A assinatura permanece ativa e a fatura segue em past_due.
3

Tentativas esgotadas

Esgota ao usar todas as tentativas ou quando a recusa é definitiva — essa vai direto ao desfecho, sem retentar.
4

Desfecho

A fatura permanece past_due e sai da régua — nenhuma cobrança automática volta a tentá-la. A assinatura continua past_due até a fatura vencida mais antiga completar o teto de inadimplência (90 dias de atraso, por padrão); aí o verificador a marca unpaid — ou a cancela, se o lojista configurou o cancelamento como desfecho.
A transição padrão da assinatura quando a cobrança falha é active/cobrando → past_due (primeira falha) → unpaid (fatura vencida há mais que o teto — 90 dias por padrão). Esgotar as retentativas não muda o status da assinatura — só encerra a recobrança daquela fatura. Configurada para cancelar, o desfecho final é canceled em vez de unpaid.
Exemplo concreto (com os padrões acima), cobrança inicial falhando em 01/jun:
Faturas de adesão (kind=enrollment) não entram em dunning: a falha é terminal, sem retentativa. A fatura sai de open para past_due (para não ser recobrada de hora em hora) e a trilha de adesão decide o cancelamento/encerramento da assinatura.
Para os status detalhados da assinatura (incomplete, trialing, active, past_due, unpaid, paused, canceled, completed) veja Assinaturas. Para os códigos de erro de chamadas à API veja Erros.

Veja também

Assinaturas

Criar e gerenciar assinaturas — request completo com recurrence, trialSpec, collectionTiming e demais campos.

Planos e preços

De onde a recurrence é herdada quando a assinatura é baseada em plano.

Faturas

Ciclo de vida de cada fatura — open, past_due, paid e os campos chargeAt/dueAt.

Visão geral de assinaturas

Conceitos do módulo de recorrência da Z2Pay.