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.

What is a subscription upgrade or downgrade?

Changing plans lets you move a customer between subscription tiers or quantities. Use it to:
  • Align pricing with usage or features
  • Move from monthly to annual (or vice versa)
  • Adjust quantity for seat-based products
Plan changes can trigger an immediate charge depending on the proration mode you choose.

When to use plan changes

  • 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
For detailed setup instructions, see our Integration Guide.

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:
Best for: SaaS applications wanting to charge fairly for unused time
  • Calculates exact prorated amount based on remaining cycle time
  • Charges a prorated amount based on unused time remaining in the cycle
  • Provides transparent billing to customers
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
Optional addons for the new plan. Leaving this empty removes any existing addons.
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 a capacidade allow_plan_change_via_payment_link da empresa (Settings → Subscriptions → Collect Plan Change Payments by Payment Link), effective_at: immediately e on_payment_failure: prevent_change. Consulte Coletando pagamento por meio de um link de checkout.Ignorado pela rota de preview.
array
Códigos de desconto empilhados opcionais para aplicar ao novo plano (máx. 20, aplicados na ordem do array). O comportamento depende do que você enviar:
  • Não informado / null — os descontos existentes com preserve_on_plan_change=true são preservados quando 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 do plano:
  • immediately (padrão): aplica a alteração do 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 next_billing_date 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 do plano concluída, assinatura atualizada
  • subscription.plan_changed: plano da assinatura alterado (upgrade/downgrade/atualização de addon)
  • subscription.on_hold: cobrança da alteração do plano falhou, renovações interrompidas
  • payment.succeeded: cobrança imediata da alteração do plano concluída
  • 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 com base no novo plano
  • Atualize o dashboard do cliente com os detalhes do novo plano
  • Envie emails de confirmação sobre as alterações do 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 proration 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 malsucedidas
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 de proration 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 coletada:
Em todos os casos, esta resposta não é um resultado de pagamento — indica apenas que a própria solicitação foi aceita. Ela não informa se uma cobrança imediata foi realmente concluída.Para uma cobrança imediata comum, o resultado é resolvido fora da sessão, logo após a chamada.Para uma solicitação collect_via_payment_link, o resultado é resolvido posteriormente e de forma assíncrona — a resposta fornece apenas um link de checkout, a assinatura permanece no plano atual e nada se sabe sobre o resultado até que o cliente conclua o pagamento nesse link.De qualquer forma, não deduza o resultado a partir desta resposta. Confirme-o por meio de um webhook (payment.succeeded, payment.failed, subscription.plan_changed) ou lendo novamente a assinatura com GET /subscriptions/{subscription_id} — consulte O que acontece enquanto o link não é pago especificamente para o caso de link de pagamento.
Se a cobrança imediata falhar, a assinatura poderá passar para 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 que você possa cobrar fora da sessão ou quando você quer que o cliente confirme ativamente o novo preço.
Isso também habilita o toggle Collect Plan Change Payments by Payment Link em Settings → Subscriptions, que direciona o fluxo de alteração de plano do Customer Portal integrado para o checkout, em vez do cartão salvo.

Requisitos

collect_via_payment_link: true só funciona quando todos os requisitos a seguir são atendidos — caso contrário, a solicitação falha com 422:
  • A empresa tem a capacidade allow_plan_change_via_payment_link habilitada (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, pois nada é cobrado até que seja aplicada.
  • O on_payment_failure efetivo é resolvido como prevent_change. Você não precisa enviá-lo explicitamente — se o padrão no nível da empresa (consulte Padrões da empresa e de cobrança abaixo) já for prevent_change, omitir o campo também atende a esse requisito. Um apply_change explícito ou um padrão resolvido como apply_change falha com 422.
collect_via_payment_link não se limita a upgrades — ele se aplica a qualquer alteração imediata que resulte em uma cobrança, incluindo downgrades, desde que os requisitos acima sejam atendidos.
Se a alteração resultar em zero ou um créditoproration_billing_mode: do_not_bill ou outro modo que ocasionalmente resulte em zero neste ciclo — não há nada a colocar em uma página de checkout. Nenhum link de pagamento é emitido, payment_link e similares retornam null, e a alteração é aplicada imediatamente, da mesma forma que seria sem collect_via_payment_link. Isso não é um 422; o sinalizador só tem efeito quando há um valor positivo a cobrar. Se você definir collect_via_payment_link genericamente nas alterações de plano, em vez de usá-lo apenas em upgrades claros, chame Preview Plan Change primeiro e solicite um link somente quando o valor exibido na preview justificar a cobrança.
Uma solicitação bem-sucedida retorna os identificadores de checkout:
  • A assinatura permanece no plano atualproduct_id, recurring_pre_tax_amount e next_billing_date permanecem inalterados até que o link seja pago.
  • Uma nova solicitação change-plan para a mesma assinatura é rejeitada com 409 PendingPlanChangeExists enquanto o link estiver 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 link de pagamento — apenas um pagamento bem-sucedido ou a expiração faz isso.
  • O cliente pode tentar novamente com 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 será automaticamente liberada para aceitar uma nova solicitação de alteração de plano pouco depois.
  • Se já existia uma alteração agendada (next_billing_date) e você a substituir por cancel_scheduled_change_plan: true, o agendamento original permanece enquanto o link não for pago e só é cancelado quando o link é pago — na mesma transação que aplica o novo plano.
Depois que uma alteração imediata por link de pagamento é emitida, todas as solicitações posteriores de alteração de plano nessa assinatura — incluindo a preview sem efeitos colaterais — são bloqueadas até que o link seja resolvido. Não emita um link que você não pretenda que o cliente pague imediatamente.

Gerenciando addons

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

Aplicando códigos de desconto

Você pode aplicar um ou mais códigos de desconto empilhados ao alterar os planos de assinatura (máx. 20, aplicados na ordem do array). Isso é útil para oferecer preços promocionais em upgrades ou migrações.

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 do plano.

Modos de proration

Escolha como cobrar o cliente ao alterar os planos:

prorated_immediately

  • Cobra a diferença proporcional referente ao ciclo atual
  • Se estiver em trial, cobra imediatamente e muda para o novo plano agora
  • Downgrade: pode gerar um crédito proporcional aplicado a renovações futuras

full_immediately

  • Cobra imediatamente o valor total do novo plano
  • Ignora o tempo restante do plano antigo
Os créditos criados por downgrades usando difference_immediately são específicos da 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 de 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 (do Pro): Starter a $20/mês
  • Ciclo de cobrança: 30 dias, iniciado em 1º de janeiro
  • A alteração do plano ocorre em 16 de janeiro (15 dias restantes, 15 dias usados)

Como cada modo processa a cobrança

Escolha prorated_immediately para uma contabilização justa baseada no tempo; 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.

Tratando 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 no nível da empresa definida no dashboard.

Quando usar cada modo

Padrões da empresa e de cobrança

Em vez de enviar parâmetros de proration em cada alteração de plano, você pode definir o comportamento padrão de upgrade e downgrade uma vez no nível da empresa. Esses padrões se aplicam a todas as alterações de plano no portal do cliente e podem ser substituídos por coleção de produtos. Há 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 de coleção é independente — deixe-o sem definição para herdar o padrão da empresa ou defina um valor para substituí-lo apenas nessa coleção.

Ordem de resolução

Para qualquer alteração de plano, cada configuração é resolvida nesta ordem:
Um valor enviado 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 portal do cliente.
Uma configuração comum: manter upgrades em immediately + difference_immediately para que os clientes paguem a diferença e obtenham acesso imediatamente, e manter downgrades em next_billing_date para que os clientes mantenham o plano atual até o fim do ciclo.

Tratando 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 concluída
  • payment.succeeded: pagamento da alteração do plano ou renovação concluído
  • payment.failed: pagamento falhou
Recomendamos conduzir a lógica de negócios a partir dos eventos de assinatura e usar eventos de pagamento para confirmação e reconciliação.

Verifique assinaturas e trate intents

Para obter os schemas detalhados dos payloads, consulte os payloads de webhook de assinatura e os payloads de webhook de pagamento.

Práticas recomendadas

Siga estas recomendações para alterações confiáveis de planos de assinatura:

Estratégia de alteração de plano

  • Teste detalhadamente: sempre teste as alterações de plano em modo de teste antes da produção
  • Escolha o proration com cuidado: selecione o modo de proration alinhado ao seu modelo de negócios
  • Trate as falhas de forma adequada: 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 seus prazos
  • Forneça confirmações: envie emails de confirmação para alterações de plano bem-sucedidas
  • Trate casos extremos: considere períodos de trial, proration e pagamentos malsucedidos
  • Atualize a UI imediatamente: reflita as alterações de plano na interface da sua 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 um tratamento robusto 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 não recebidos
  • Verifique se o endpoint de webhook está acessível e respondendo corretamente
Sintomas: o cliente faz downgrade, mas não vê o saldo de créditoCausas comuns:
  • Expectativas em relação ao modo de proration: downgrades creditam a diferença total de preço do plano com difference_immediately, enquanto prorated_immediately cria um crédito proporcional com base no tempo restante do ciclo
  • 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 portal do cliente para exibir os saldos de crédito
  • Verifique a preview da próxima invoice para ver os créditos aplicados
Sintomas: eventos de webhook rejeitados devido a uma assinatura inválidaCausas comuns:
  • Chave secreta de 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 você está usando o DODO_WEBHOOK_SECRET correto do dashboard
  • Leia o corpo bruto da solicitação antes de qualquer middleware de parsing JSON
  • Use a biblioteca padrão de verificação de webhook 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 não disponível para alterações de plano
Soluções:
  • Verifique se a assinatura existe e está ativa
  • Verifique 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 malsucedidas
Sintomas: a cobrança da alteração do plano falha e a assinatura passa para o estado on_holdO que acontece: Quando uma cobrança de 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 invoice: uma invoice é 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 do plano falha)
  • payment.succeeded: pagamento dos valores restantes concluído (após a atualização do 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 do 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 de novas tentativas automáticas 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.

Testando sua implementação

Siga estas etapas para testar 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 o endpoint de webhook de teste
  • Configure monitoramento e logging
2

Test different proration modes

  • Teste prorated_immediately em várias posições do ciclo de cobrança
  • Teste difference_immediately para upgrades e downgrades
  • Teste full_immediately para reiniciar os 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 da assinatura do webhook
  • 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 e timeouts de rede
  • 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 tickets de suporte ao cliente relacionados a problemas de alteração de plano

Tratamento de erros

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

Códigos de status HTTP

Solicitação de alteração de plano processada com sucesso. O corpo da resposta está vazio, exceto no caso de uma solicitação collect_via_payment_link bem-sucedida, que retorna identificadores de checkout — consulte Coletando pagamento por meio de um link de checkout. Se on_payment_failure=prevent_change, a alteração do 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 seu DODO_PAYMENTS_API_KEY está correto e tem as permissões adequadas.
ID da assinatura não encontrado ou não pertence à sua conta.
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 link de pagamento pendente, não há endpoint de cancelamento — a assinatura aceita uma nova solicitação de alteração de plano quando o cliente paga ou o link expira.
A assinatura está inativa ou sob demanda, ou a solicitação não é elegível para collect_via_payment_link — a empresa não tem a capacidade habilitada, effective_at não é immediately ou on_payment_failure não é prevent_change. Consulte Requisitos.
Ocorreu um erro no servidor. Tente novamente após um breve intervalo.

Formato da resposta de erro

Próximas etapas

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