Skip to main content
POST
Trocar o plano da assinatura
POST /subscriptions/:id/change-plan Faz parte do recurso Assinaturas — o conceito e os dez estados estão lá. Troca o que a assinatura cobra: outro plano do catálogo em planId, ou um conjunto de itens avulsos em items. Pelo menos um dos dois — mandando os dois, planId vence e items é ignorado.

Quando a troca passa a valer

O preço do destino determina o momento. Plano mais caro vale na hora. O que resta do ciclo é acertado por rateio: uma fatura separada nasce em aberto, com o crédito do que sobrou do plano atual e o débito do novo. A fatura do período corrente não é alterada. Plano mais barato é agendado para a virada do ciclo. A assinatura segue no plano atual até o fim do período, e o novo entra no ciclo seguinte.
Pedir effectiveAt: "now" num plano mais barato responde 409. Omita o campo: sem ele, o rebaixamento é agendado para a virada.

A conta do rateio

O cálculo é por dia, e o dia corrente conta como usado. Numa troca de R100,00paraR 100,00 para R 129,90 faltando 25 dias de um ciclo de 31: netAmount traz esse total em centavos. Numa troca agendada ele é zero.
A fatura da diferença pode não estar disponível imediatamente. O prorationInvoiceId vem nesta resposta, mas GET /invoices/{id} pode responder 404 nos instantes seguintes — o mesmo vale para o latestInvoiceId da assinatura, que aponta para ela. Escute o webhook invoice.issued para saber quando a fatura existe.
Para ver a conta antes de confirmar, use simular a troca. Ela devolve o mesmo valor e as duas pernas separadas.
Rateio a favor do cliente responde 409. Como todo rebaixamento é agendado para a virada, e uma troca agendada não cobra nada hoje, o caso não aparece no fluxo normal.

Cortesia: trocar sem cobrar

prorationBehavior: "none" troca na hora e não cobra a diferença. Nenhuma fatura é emitida — prorationInvoiceId volta null e netAmount, zero. Só vale junto de effectiveAt: "now" — pedida numa troca agendada, a chamada responde 409.

O plano novo vale antes de a fatura ser paga

A troca é aplicada no ato, e a fatura da diferença segue a régua de cobrança normal. Se ela não for paga, a troca não é desfeita: quem entra em inadimplência é a assinatura, pelo caminho de sempre.

O destino precisa ser compatível

O contrato vigente fixa três coisas, e o plano de destino tem de respeitá-las:
  • moeda — a mesma da assinatura;
  • recorrência — mensal continua mensal; não dá para migrar de mensal para anual por aqui;
  • momento de cobrança — antecipado continua antecipado.
Qualquer divergência responde 409. Assinatura que não esteja ativa também, assim como contrato com cobrança antecipada de todos os ciclos, cujas faturas futuras já foram emitidas.
A simulação recusa pelos mesmos motivos. Use change-plan/preview na tela onde o cliente escolhe o plano: o erro aparece ali, e não na confirmação.

Como saber que há uma troca agendada

O campo scheduledPlanChange da assinatura traz { planId, effectiveDate } enquanto houver troca marcada, e null quando não houver. Ele aparece no GET /subscriptions/{id} e no corpo desta rota. É por ele que se sabe se há o que desfazer — e se o desfazer funcionou.

Desfazer

Enquanto a troca estiver agendada, DELETE /subscriptions/:id/change-plan a apaga. Depois que ela entra em vigor, o caminho de volta é uma nova troca.

Authorizations

x-api-key
string
header
required

API Key da Credential (gerada no Backoffice)

Headers

Idempotency-Key
string

Chave única para garantir idempotência da requisição

Path Parameters

id
string
required

ID da assinatura

Body

application/json
planId
string

Plano de destino. Ausente ⇒ o destino é avulso e items é obrigatório.

Minimum string length: 1
items
object[]

Itens do destino avulso (referência ou inline). Ignorado quando há planId.

itemOverrides
object

Override de quantidade por componente do plano destino.

effectiveAt
enum<string>

Quando a troca vale. Ausente ⇒ imediata para plano mais caro, na virada para mais barato. Pedir now num plano mais barato é recusado.

Available options:
now,
period_end
prorationBehavior
enum<string>
default:create_prorations

none troca agora sem cobrar a diferença (cortesia). Só vale com effectiveAt=now.

Available options:
create_prorations,
none

Response

Plano trocado ou troca agendada para a virada