Skip to main content

Change Plan API

Full API docs for updating subscriptions.

Plan Change Preview

See charge amounts before changing plans.

Integration Guide

Step-by-step subscription setup.

O que é um upgrade ou downgrade de assinatura?

Altere o plano de assinatura de um cliente para movê-lo entre níveis, ajustar a quantidade de produtos baseados em assentos ou migrar para um novo produto. A API calcula automaticamente os valores proporcionais e as cobranças com base no seu modo de cobrança escolhido.
Plan changes can trigger an immediate charge depending on the proration mode you choose.

Quando usar alterações de plano

  • Upgrade when a customer needs more features, usage, or seats
  • Downgrade when usage decreases
  • Migrate users to a new product or price without cancelling their subscription

Plan Change Flow

Prerequisites

Before implementing subscription plan changes, ensure you have:
  • A Dodo Payments merchant account with active subscription products
  • API credentials (API key and webhook secret key) from the dashboard
  • An existing active subscription to modify
  • Webhook endpoint configured to handle subscription events
Para obter instruções detalhadas de configuração, consulte o Guia de integração.

Step-by-Step Implementation Guide

Follow this comprehensive guide to implement subscription plan changes in your application:
1

Understand Plan Change Requirements

Before implementing, determine:
  • Which subscription products can be changed to which others
  • What proration mode fits your business model
  • How to handle failed plan changes gracefully
  • Which webhook events to track for state management
Test plan changes thoroughly in test mode before implementing in production.
2

Choose Your Proration Strategy

Select the billing approach that aligns with your business needs:
Ideal para: aplicações SaaS que desejam creditar o tempo não utilizado do plano antigo.
  • Credita a parte não utilizada do ciclo atual, proporcionalmente ao tempo restante
  • Em seguida, cobra um ciclo completo no novo plano — o preço do novo plano nunca é calculado proporcionalmente
  • Cobrança líquida = ciclo completo do novo plano − (fração restante × ciclo completo do plano antigo)
3

Implement the Change Plan API

Use the Change Plan API to modify subscription details:
string
obrigatório
The ID of the active subscription to modify.
string
obrigatório
The new product ID to change the subscription to.
integer
obrigatório
Number of units for the new plan (for seat-based products).
string
obrigatório
How to handle immediate billing: prorated_immediately, full_immediately, difference_immediately, or do_not_bill.
array
Add-ons opcionais para o novo plano. Omitir este campo, enviar null ou enviar um array vazio remove quaisquer add-ons existentes; portanto, inclua os add-ons atuais para mantê-los.
string
Controls behavior when the plan change payment fails:
  • prevent_change: Keep subscription on current plan until payment succeeds
  • apply_change (default): Apply plan change immediately regardless of payment outcome
If not specified, uses the business-level default setting.
Cole o valor da alteração do plano com um link de pagamento em vez de cobrar o método de pagamento salvo da assinatura. O cliente paga em uma página de checkout hospedada.Requer que a empresa tenha o recurso allow_plan_change_via_payment_link (Settings → Subscriptions → Collect Plan Change Payments by Payment Link), effective_at: immediately e on_payment_failure: prevent_change. Consulte Collecting Payment via a Checkout Link. Ignorado pela rota de preview.
array
Códigos de desconto empilhados opcionais para aplicar ao novo plano (máximo de 20, aplicados na ordem do array). O comportamento depende do que você enviar:
  • Não fornecido / null — os descontos existentes com preserve_on_plan_change=true são preservados se forem aplicáveis ao novo produto.
  • [] (array vazio) — remove todos os descontos existentes da assinatura.
  • ["CODE_A", "CODE_B", ...] — substitui todos os descontos existentes por este conjunto empilhado.
string
obsoleto
Obsoleto — prefira discount_codes para novas integrações. Este campo ainda funciona para compatibilidade retroativa, mas não pode ser combinado com discount_codes na mesma solicitação.
string
padrão:"immediately"
Quando aplicar a alteração de plano:
  • immediately (padrão): aplica a alteração de plano imediatamente
  • next_billing_date: agenda a alteração para a próxima data de cobrança. O cliente mantém o plano atual até o fim do período de cobrança. Use essa opção para downgrades, para que os clientes mantenham os benefícios do plano atual até o fim do período de cobrança.
4

Handle Webhook Events

Configure o tratamento de webhooks para acompanhar os resultados das alterações de plano:
  • subscription.active: alteração de plano bem-sucedida, assinatura atualizada
  • subscription.plan_changed: plano da assinatura alterado (upgrade/downgrade/atualização de addon)
  • subscription.on_hold: cobrança da alteração de plano falhou, renovações interrompidas
  • payment.succeeded: cobrança imediata da alteração de plano bem-sucedida
  • payment.failed: cobrança imediata falhou
Sempre verifique as assinaturas dos webhooks e implemente o processamento idempotente de eventos.
5

Update Your Application State

Com base nos eventos de webhook, atualize sua aplicação:
  • Conceda ou revogue recursos de acordo com o novo plano
  • Atualize o dashboard do cliente com os detalhes do novo plano
  • Envie e-mails de confirmação sobre as alterações de plano
  • Registre as alterações de cobrança para fins de auditoria
6

Test and Monitor

Teste sua implementação detalhadamente:
  • Teste todos os modos de cálculo proporcional em diferentes cenários
  • Verifique se o tratamento de webhooks funciona corretamente
  • Monitore as taxas de sucesso das alterações de plano
  • Configure alertas para alterações de plano com falha
Sua implementação de alteração de plano de assinatura está pronta para uso em produção.

Visualizar alterações de plano

Antes de confirmar uma alteração de plano, use a Preview API para mostrar aos clientes exatamente quanto será cobrado:
Use a Preview API para criar diálogos de confirmação que mostrem aos clientes o valor exato que será cobrado antes de confirmarem uma alteração de plano.

Change Plan API

Use a Change Plan API para modificar o produto, a quantidade e o comportamento do cálculo proporcional de uma assinatura ativa.

Exemplos de início rápido

Uma alteração de plano bem-sucedida retorna 200 OK imediatamente — antes que qualquer cobrança seja efetivamente liquidada. O conteúdo do corpo (ChangePlanResponse) depende de como a alteração foi cobrada:
Esta resposta confirma que a solicitação foi aceita, não que uma cobrança foi bem-sucedida. Para uma cobrança imediata comum, o resultado é resolvido off-session logo após a chamada. Para uma solicitação collect_via_payment_link, a assinatura permanece no plano atual até que o cliente conclua o pagamento.Confirme o resultado por webhook (payment.succeeded, payment.failed, subscription.plan_changed) ou lendo novamente a assinatura com GET /subscriptions/{subscription_id} — consulte What Happens While the Link Is Unpaid para o caso de payment link.
Se a cobrança imediata falhar, a assinatura poderá passar para o estado subscription.on_hold até que o pagamento seja concluído.
Por padrão, uma alteração imediata de plano cobra diretamente o método de pagamento salvo da assinatura. Defina collect_via_payment_link: true para enviar o cliente a uma página de checkout hospedada — útil quando não há um método de pagamento salvo ou quando você deseja que o cliente confirme ativamente o novo preço.
Isso habilita a opção Collect Plan Change Payments by Payment Link em Settings → Subscriptions, direcionando o fluxo de alteração de plano do Customer Portal para o checkout.

Requisitos

collect_via_payment_link: true só funciona quando todas as condições a seguir são atendidas — caso contrário, a solicitação falha com 422:
  • A empresa tem o recurso allow_plan_change_via_payment_link habilitado (Settings → Subscriptions → Collect Plan Change Payments by Payment Link).
  • effective_at é immediately (o padrão). Uma alteração agendada (next_billing_date) nunca precisa de uma página de checkout.
  • O on_payment_failure efetivo resolve para prevent_change. Não é necessário enviá-lo explicitamente — se o padrão no nível da empresa já for prevent_change, omitir o campo atende a essa condição. Um apply_change explícito falha com 422.
collect_via_payment_link se aplica a qualquer alteração imediata que resulte em uma cobrança, inclusive downgrades, desde que os requisitos acima sejam atendidos.
Se a alteração resultar em zero ou em um crédito, nenhum payment link será emitido: payment_link e os outros campos de checkout retornam null, e a alteração é aplicada imediatamente. Isso não é um 422. Chame Preview Plan Change primeiro para verificar o valor antes de solicitar um link.
Uma solicitação bem-sucedida retorna os identificadores de checkout:
  • A assinatura permanece no plano atual — product_id, recurring_pre_tax_amount e next_billing_date permanecem inalterados até que o link seja pago.
  • Uma nova solicitação change-plan é rejeitada com 409 PendingPlanChangeExists enquanto o link está pendente. Cancele uma alteração agendada com DELETE /subscriptions/{subscription_id}/change-plan/scheduled, se necessário, mas esse endpoint não cancela uma alteração pendente por payment link — somente um pagamento bem-sucedido ou a expiração faz isso.
  • O cliente pode tentar novamente um cartão na mesma sessão de checkout após uma recusa; uma nova chamada change-plan não é o caminho para tentar novamente.
  • Se o link nunca for pago, ele deixará de funcionar após expires_on — a assinatura ficará automaticamente disponível para aceitar uma nova solicitação de alteração de plano pouco depois.
  • Se já existia uma alteração agendada e você a substituir por cancel_scheduled_change_plan: true, a programação original permanecerá enquanto o link não for pago e só será cancelada quando o link for pago — na mesma transação que aplica o novo plano.
Depois que uma alteração imediata por payment link é emitida, todas as solicitações seguintes de alteração de plano nessa assinatura — incluindo o preview sem efeitos colaterais — ficam bloqueadas até que o link seja resolvido. Não emita um link que você não pretende que o cliente pague imediatamente.

Gerenciar addons

Ao alterar planos de assinatura, você também pode modificar addons:
Os addons são incluídos no cálculo proporcional e serão cobrados de acordo com o modo de cálculo proporcional selecionado.

Aplicar códigos de desconto

Aplique um ou mais códigos de desconto empilhados ao alterar planos de assinatura (máximo de 20, aplicados na ordem do array):

Comportamento dos descontos na alteração de plano

O campo singular discount_code neste endpoint está obsoleto, mas ainda funciona para compatibilidade retroativa — as integrações existentes não precisam ser alteradas imediatamente. Ele não pode ser combinado com discount_codes na mesma solicitação. Migre para o formato de array quando for conveniente.
Use a Preview Plan Change API com discount_codes para mostrar aos clientes exatamente quanto eles economizarão antes de confirmar a alteração de plano.

Modos de cálculo proporcional

Escolha como cobrar o cliente ao alterar planos:

prorated_immediately

  • Credita a parte não utilizada do ciclo atual — plano base, quantidade e addons — proporcionalmente ao tempo restante
  • Em seguida, cobra um ciclo completo do novo plano, quantidade e addons. A cobrança em si nunca é proporcional
  • Cobrança imediata líquida = (ciclo completo novo) − (fração restante × ciclo completo antigo)
  • Se o crédito exceder a cobrança do novo ciclo (comum em downgrades), a diferença será mantida como crédito vinculado à assinatura para renovações futuras
  • Se estiver em trial, cobra imediatamente e muda para o novo plano agora

full_immediately

  • Cobra imediatamente o valor integral do novo plano
  • Ignora o tempo restante do plano antigo — não há crédito para o ciclo atual
Os créditos criados por prorated_immediately e por downgrades que usam difference_immediately são vinculados à assinatura e distintos dos benefícios de Credit-Based Billing. Eles são aplicados automaticamente a renovações futuras da mesma assinatura e não podem ser transferidos entre assinaturas.

difference_immediately

  • Upgrade: cobra imediatamente a diferença de preço entre os planos antigo e novo
  • Downgrade: adiciona o valor restante como crédito interno à assinatura e aplica automaticamente nas renovações

do_not_bill

  • Nenhuma cobrança ou crédito é calculado
  • O cliente muda imediatamente para o novo plano sem qualquer ajuste de cobrança
  • O ciclo de cobrança permanece inalterado
  • Ideal para migrações como cortesia, mudanças para planos gratuitos ou absorção de diferenças de custo

Cenários de exemplo

Use estes números canônicos de forma consistente:
  • Plano atual: Basic a $30/mês
  • Destino do upgrade: Pro a $80/mês
  • Destino do downgrade (a partir do Pro): Starter a $20/mês
  • Ciclo de cobrança: 30 dias, iniciado em 1º de janeiro
  • A alteração de plano ocorre em 16 de janeiro (15 dias restantes, 15 dias utilizados)

Como cada modo processa a cobrança

Escolha prorated_immediately para creditar o tempo não utilizado do plano antigo e cobrar um ciclo completo do novo; escolha full_immediately para reiniciar a cobrança; use difference_immediately para upgrades simples e crédito automático em downgrades; ou use do_not_bill para mudar de plano sem qualquer ajuste de cobrança.

Tratar falhas de pagamento

Controle o que acontece quando o pagamento de uma alteração de plano falha usando o parâmetro on_payment_failure.

Modos de falha de pagamento

Se não for especificado, o parâmetro on_payment_failure usará a configuração padrão da empresa definida no dashboard.

Quando usar cada modo

Padrões de empresa e cobrança

Defina o comportamento padrão de upgrades e downgrades no nível da empresa em Settings → Subscriptions. Esses padrões se aplicam a todas as alterações de plano pelo customer portal e podem ser substituídos por coleção de produtos. Existem padrões separados para upgrades e downgrades: Configure os padrões da empresa em Settings → Subscriptions e as substituições de coleção em cada coleção de produtos. Cada campo da coleção é independente — deixe-o não definido para herdar o padrão da empresa ou defina um valor para substituí-lo.

Ordem de resolução

Para qualquer alteração de plano, cada configuração é resolvida nesta ordem:
Um valor passado explicitamente à Change Plan API sempre tem prioridade. Os padrões da empresa e da coleção só entram em vigor quando nenhum valor explícito é fornecido — o que ocorre em todas as alterações de plano iniciadas pelo customer portal.
Uma configuração comum: mantenha os upgrades em immediately + difference_immediately para que os clientes paguem a diferença e obtenham acesso imediatamente, e mantenha os downgrades em next_billing_date para que os clientes conservem o plano atual até o fim do ciclo.

Tratar webhooks

Acompanhe o estado da assinatura por meio de webhooks para confirmar alterações de plano e pagamentos.

Tipos de evento a tratar

  • subscription.active: assinatura ativada
  • subscription.plan_changed: plano da assinatura alterado (upgrade/downgrade/alterações de addon)
  • subscription.on_hold: cobrança falhou, renovações interrompidas
  • subscription.renewed: renovação bem-sucedida
  • payment.succeeded: pagamento da alteração de plano ou renovação bem-sucedido
  • payment.failed: pagamento falhou
Baseie a lógica de negócio nos eventos de assinatura e use os eventos de pagamento para confirmação e reconciliação.

Verificar assinaturas e tratar intenções

Para obter os schemas detalhados dos payloads, consulte Subscription webhook payloads e Payment webhook payloads.

Práticas recomendadas

Estratégia de alteração de plano

  • Teste detalhadamente: sempre teste alterações de plano no modo de teste antes da produção
  • Escolha o cálculo proporcional com cuidado: selecione o modo que esteja alinhado ao seu modelo de negócio
  • Trate falhas adequadamente: implemente tratamento de erros e lógica de novas tentativas
  • Monitore as taxas de sucesso: acompanhe as taxas de sucesso/falha das alterações de plano e investigue os problemas

Implementação de webhook

  • Verifique as assinaturas: sempre valide as assinaturas dos webhooks para garantir a autenticidade
  • Implemente idempotência: trate eventos de webhook duplicados adequadamente
  • Processe de forma assíncrona: não bloqueie as respostas dos webhooks com operações pesadas
  • Registre tudo: mantenha logs detalhados para depuração e auditoria

Experiência do usuário

  • Comunique-se claramente: informe os clientes sobre as alterações de cobrança e o momento em que ocorrerão
  • Forneça confirmações: envie confirmações por e-mail para alterações de plano bem-sucedidas
  • Trate casos extremos: considere períodos de trial, cálculos proporcionais e pagamentos recusados
  • Atualize a interface imediatamente: reflita as alterações de plano na interface da aplicação

Problemas comuns e soluções

Resolva problemas típicos encontrados durante alterações de planos de assinatura:
Sintomas: a chamada à API é bem-sucedida, mas a assinatura permanece no plano antigoCausas comuns:
  • O processamento do webhook falhou ou foi atrasado
  • O estado da aplicação não foi atualizado após o recebimento dos webhooks
  • Problemas na transação do banco de dados durante a atualização do estado
Soluções:
  • Implemente o tratamento de webhooks com lógica de novas tentativas
  • Use operações idempotentes para atualizações de estado
  • Adicione monitoramento para detectar e alertar sobre eventos de webhook perdidos
  • Verifique se o endpoint do webhook está acessível e respondendo corretamente
Sintomas: o cliente faz downgrade, mas não vê o saldo de créditoCausas comuns:
  • Expectativas sobre o modo de cálculo proporcional: downgrades creditam a diferença integral de preço do plano com difference_immediately, enquanto prorated_immediately credita o tempo não utilizado do ciclo antigo e depois cobra um ciclo completo do novo plano — portanto, um saldo de crédito só permanece quando esse crédito excede o preço do novo plano
  • Os créditos são específicos da assinatura e não são transferidos entre assinaturas
  • O saldo de crédito não está visível no dashboard do cliente
Soluções:
  • Use difference_immediately para downgrades quando quiser créditos automáticos
  • Explique aos clientes que os créditos se aplicam a renovações futuras da mesma assinatura
  • Implemente o customer portal para exibir saldos de crédito
  • Verifique o preview da próxima fatura para visualizar os créditos aplicados
Sintomas: eventos de webhook rejeitados devido a uma assinatura inválidaCausas comuns:
  • Chave secreta do webhook incorreta
  • Corpo bruto da solicitação modificado antes da verificação da assinatura
  • Algoritmo incorreto de verificação da assinatura
Soluções:
  • Verifique se está usando o DODO_PAYMENTS_WEBHOOK_KEY correto do dashboard
  • Leia o corpo bruto da solicitação antes de qualquer middleware de parsing de JSON
  • Use a biblioteca padrão de verificação de webhooks da sua plataforma
  • Teste a verificação da assinatura do webhook no ambiente de desenvolvimento
Sintomas: a API retorna o erro 422 Unprocessable EntityCausas comuns:
  • ID de assinatura ou ID de produto inválido
  • Assinatura não está no estado ativo
  • Parâmetros obrigatórios ausentes
  • Produto indisponível para alterações de plano
Soluções:
  • Verifique se a assinatura existe e está ativa
  • Confirme se o ID do produto é válido e está disponível
  • Garanta que todos os parâmetros obrigatórios sejam fornecidos
  • Consulte a documentação da API para conhecer os requisitos dos parâmetros
Sintomas: alteração de plano iniciada, mas a cobrança imediata falhaCausas comuns:
  • Saldo insuficiente no método de pagamento do cliente
  • Método de pagamento expirado ou inválido
  • O banco recusou a transação
  • A detecção de fraude bloqueou a cobrança
Soluções:
  • Trate os eventos de webhook payment.failed adequadamente
  • Notifique o cliente para atualizar o método de pagamento
  • Implemente lógica de novas tentativas para falhas temporárias
  • Considere permitir alterações de plano com cobranças imediatas recusadas
Sintomas: a cobrança da alteração de plano falha e a assinatura passa para o estado on_holdO que acontece: Quando a cobrança de uma alteração de plano falha, a assinatura é automaticamente colocada no estado on_hold. A assinatura não será renovada automaticamente até que o método de pagamento seja atualizado.Solução: atualize o método de pagamento para reativar a assinaturaPara reativar uma assinatura no estado on_hold após uma alteração de plano malsucedida:
  1. Atualize o método de pagamento usando a Update Payment Method API
  2. Criação automática da cobrança: a API cria automaticamente uma cobrança para os valores restantes
  3. Geração da fatura: uma fatura é gerada para a cobrança
  4. Processamento do pagamento: o pagamento é processado usando o novo método de pagamento
  5. Reativação: após o pagamento bem-sucedido, a assinatura é reativada para o estado active
Eventos de webhook a monitorar:
  • subscription.on_hold: assinatura colocada em espera (recebido quando a cobrança da alteração de plano falha)
  • payment.succeeded: pagamento dos valores restantes bem-sucedido (após atualizar o método de pagamento)
  • subscription.active: assinatura reativada após pagamento bem-sucedido
Práticas recomendadas:
  • Notifique os clientes imediatamente quando uma cobrança de alteração de plano falhar
  • Forneça instruções claras sobre como atualizar o método de pagamento
  • Monitore os eventos de webhook para acompanhar o status da reativação
  • Considere implementar lógica automática de novas tentativas para falhas temporárias de pagamento

Update Payment Method API Reference

Consulte a documentação completa da API para atualizar métodos de pagamento e reativar assinaturas.

Testar sua implementação

Teste detalhadamente sua implementação de alteração de plano de assinatura:
1

Set up test environment

  • Use API keys de teste e produtos de teste
  • Crie assinaturas de teste com diferentes tipos de plano
  • Configure um endpoint de webhook de teste
  • Configure monitoramento e logging
2

Test different proration modes

  • Teste prorated_immediately com diferentes posições no ciclo de cobrança
  • Teste difference_immediately para upgrades e downgrades
  • Teste full_immediately para redefinir ciclos de cobrança
  • Teste do_not_bill para mudanças de plano sem cobrança/crédito
  • Verifique se os cálculos de crédito estão corretos
3

Test webhook handling

  • Verifique se todos os eventos de webhook relevantes são recebidos
  • Teste a verificação das assinaturas dos webhooks
  • Trate eventos de webhook duplicados adequadamente
  • Teste cenários de falha no processamento de webhooks
4

Test error scenarios

  • Teste com IDs de assinatura inválidos
  • Teste com métodos de pagamento expirados
  • Teste falhas de rede e timeouts
  • Teste com saldo insuficiente
5

Monitor in production

  • Configure alertas para alterações de plano malsucedidas
  • Monitore os tempos de processamento dos webhooks
  • Acompanhe as taxas de sucesso das alterações de plano
  • Analise os chamados do suporte ao cliente relacionados a problemas de alteração de plano

Tratamento de erros

Trate os erros comuns da API adequadamente na sua implementação:

HTTP Status Codes

Solicitação de alteração de plano processada com sucesso. O corpo da resposta é um ChangePlanResponse com payment_id, payment_link, client_secret e expires_on. Os quatro valores podem ser nulos, portanto o corpo é serializado como {} para uma alteração off-session comum; eles são preenchidos para uma solicitação collect_via_payment_link bem-sucedida, que retorna identificadores de checkout — consulte Collecting Payment via a Checkout Link. Se on_payment_failure=prevent_change, a alteração de plano permanece pendente até que o pagamento seja concluído.
Parâmetros de solicitação inválidos. Verifique se todos os campos obrigatórios foram fornecidos e estão formatados corretamente.
API key inválida ou ausente. Verifique se o DODO_PAYMENTS_API_KEY está correto e possui as permissões adequadas.
Já existe uma alteração de plano pendente para esta assinatura (PendingPlanChangeExists). Para uma alteração agendada, cancele-a com DELETE /subscriptions/{subscription_id}/change-plan/scheduled antes de enviar uma nova. Para uma alteração por payment link pendente, não há endpoint de cancelamento — a assinatura aceitará uma nova solicitação de alteração de plano quando o cliente pagar ou o link expirar.
A assinatura está inativa ou é on-demand, ou a solicitação não é elegível para collect_via_payment_link — a empresa não tem o recurso habilitado, effective_at não é immediately ou on_payment_failure não é prevent_change. Consulte Requirements. Um ID de assinatura inexistente ou que não pertença à sua conta retorna 404 com o código NOT_FOUND.
Ocorreu um erro no servidor. Tente novamente após um breve intervalo.

Formato da resposta de erro

Os erros retornam um corpo JSON com um code e um message legível por humanos:
Consulte Error Codes para ver a lista completa.

Próximas etapas

Última modificação em 26 de setembro de 2026