Documentation Index
Fetch the complete documentation index at: https://docs.dodopayments.com/llms.txt
Use this file to discover all available pages before exploring further.
Change Plan API
Plan Change Preview
Integration Guide
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
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
Step-by-Step Implementation Guide
Follow this comprehensive guide to implement subscription plan changes in your application:Understand Plan Change Requirements
- 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
Choose Your Proration Strategy
- prorated_immediately
- difference_immediately
- full_immediately
- do_not_bill
- 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
Implement the Change Plan API
prorated_immediately, full_immediately, difference_immediately, or do_not_bill.prevent_change: Keep subscription on current plan until payment succeedsapply_change(default): Apply plan change immediately regardless of payment outcome
- Não fornecido /
null— descontos existentes compreserve_on_plan_change=truesão preservados se aplicáveis ao novo produto. [](array vazio) — remove todos os descontos existentes da assinatura.["CODE_A", "CODE_B", ...]— substitui quaisquer descontos existentes por este conjunto empilhado.
discount_codes para novas integrações. Este campo ainda funciona para compatibilidade com versões anteriores, mas não pode ser combinado com discount_codes na mesma solicitação.immediately(padrão): Aplica a mudança de plano imediatamentenext_billing_date: Agenda a mudança para a próxima data de cobrança. O cliente mantém o plano atual até o final do período de cobrança.
next_billing_date para downgrades para que os clientes mantenham os benefícios do plano atual até o final do período de cobrança.Handle Webhook Events
subscription.active: Mudança de plano bem-sucedida, assinatura atualizadasubscription.plan_changed: Plano de assinatura alterado (upgrade/downgrade/atualização de addon)subscription.on_hold: Cobrança de mudança de plano falhou, assinatura pausadapayment.succeeded: Cobrança imediata para mudança de plano bem-sucedidapayment.failed: Cobrança imediata falhou
Update Your Application State
- Conceda/revoque recursos com base no novo plano
- Atualize o painel do cliente com os detalhes do novo plano
- Envie emails de confirmação sobre mudanças de plano
- Registre alterações de cobrança para auditoria
Test and Monitor
- Teste todos os modos de rateio com diferentes cenários
- Verifique se o manuseio de webhook funciona corretamente
- Monitore as taxas de sucesso de mudança de plano
- Configure alertas para mudanças de plano falhadas
Prever Mudanças de Plano
Antes de confirmar uma mudança de plano, use a API de Pré-visualização para mostrar aos clientes exatamente o que será cobrado:- Node.js SDK
- Python SDK
API de Mudança de Plano
Use a API de Mudança de Plano para modificar o produto, quantidade e comportamento de rateio para uma assinatura ativa.Exemplos de início rápido
- Node.js SDK
- Python SDK
- Go SDK
- HTTP
invoice_id e payment_id são retornados apenas quando uma cobrança imediata e/ou fatura é criada durante a mudança de plano. Sempre dependa de eventos de webhook (e.g., payment.succeeded, subscription.plan_changed) para confirmar os resultados.Gerenciando Addons
Ao alterar planos de assinatura, você também pode modificar addons:Aplicando Códigos de Desconto
Você pode aplicar um ou mais códigos de desconto empilhados ao alterar planos de assinatura (máximo de 20, aplicados na ordem do array). Isso é útil para oferecer preços promocionais em upgrades ou migrações.- Node.js SDK
- Python SDK
- HTTP
Comportamento do desconto na mudança de plano
discount_codes valor | Comportamento |
|---|---|
Não fornecido / null | Descontos existentes com preserve_on_plan_change=true são automaticamente preservados se aplicáveis ao novo produto. |
[] (array vazio) | Todos os descontos existentes são removidos da assinatura. |
["CODE_A", "CODE_B", ...] | Substitui quaisquer descontos existentes por este conjunto empilhado, validado e aplicado na ordem do array. |
discount_code neste endpoint está descontinuado, mas ainda funciona para compatibilidade com versões anteriores — integrações existentes não precisam mudar imediatamente. Não pode ser combinado com discount_codes na mesma solicitação. Migre para a forma de array quando conveniente.Modos de Rateio
Escolha como cobrar o cliente ao mudar de plano:prorated_immediately
- Cobra pela diferença parcial do ciclo atual
- Se estiver em teste, cobra imediatamente e muda para o novo plano agora
- Downgrade: pode gerar um crédito rateado aplicado a futuras renovações
full_immediately
- Cobra o valor total do novo plano imediatamente
- Ignora o tempo restante do antigo plano
difference_immediately são específicos da assinatura e distintos de direitos de Faturamento Baseado em Crédito. Aplica-se automaticamente a futuras renovações da mesma assinatura e não são transferíveis entre assinaturas.difference_immediately
- Upgrade: cobra imediatamente a diferença de preço entre os planos antigo e novo
- Downgrade: adiciona 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 para o novo plano imediatamente sem ajuste de cobrança
- O ciclo de cobrança permanece inalterado
- Melhor para migrações de cortesia, trocas de planos gratuitos ou absorção de diferenças de custo
| Recurso | prorated_immediately | difference_immediately | full_immediately | do_not_bill |
|---|---|---|---|---|
| Cobrança por upgrade | Diferença rateada para dias restantes | Diferença total de preço entre planos | Preço total do novo plano | Sem cobrança |
| Crédito por downgrade | Crédito rateado para dias restantes | Diferença total de preço como crédito | Sem crédito | Sem crédito |
| Ciclo de cobrança | Inalterado | Inalterado | Reinicia para hoje | Inalterado |
| Comportamento de teste | Termina teste, cobra imediatamente | Termina teste, cobra imediatamente | Termina teste, cobra valor total | Termina teste, sem cobrança |
| Melhor para | Cobrança justa baseada no tempo | Matemática simples de upgrade/downgrade | Reinício de ciclos de cobrança | Migrações gratuitas ou trocas de cortesia |
| Complexidade | Média (cálculo de dia) | Baixa (subtração simples) | Baixa (cobrança total) | Nenhuma |
Exemplos de cenários
Use esses números canônicos de forma consistente:- Plano atual: Básico a $30/mês
- Objetivo de upgrade: Pro a $80/mês
- Objetivo de downgrade (de Pro): Inicial a $20/mês
- Ciclo de cobrança: 30 dias, iniciado em 1º de janeiro
- Mudança de plano ocorre em 16 de janeiro (15 dias restantes, 15 dias usados)
Upgrade: Basic ($30) → Pro ($80) with prorated_immediately
Upgrade: Basic ($30) → Pro ($80) with prorated_immediately
Downgrade: Pro ($80) → Starter ($20) with prorated_immediately
Downgrade: Pro ($80) → Starter ($20) with prorated_immediately
Upgrade: Basic ($30) → Pro ($80) with difference_immediately
Upgrade: Basic ($30) → Pro ($80) with difference_immediately
Downgrade: Pro ($80) → Starter ($20) with difference_immediately
Downgrade: Pro ($80) → Starter ($20) with difference_immediately
Upgrade: Basic ($30) → Pro ($80) with full_immediately
Upgrade: Basic ($30) → Pro ($80) with full_immediately
Mid-cycle upgrade with add-ons using prorated_immediately
Mid-cycle upgrade with add-ons using prorated_immediately
Como cada modo processa a cobrança
Lidando com Falhas de Pagamento
Controle o que acontece quando uma cobrança de mudança de plano falha usando o parâmetroon_payment_failure.
Modos de Falha de Pagamento
- prevent_change (Recommended for critical upgrades)
- apply_change (Default)
- A mudança de plano é marcada como “pendente”
- O cliente mantém acesso ao seu plano atual
- A assinatura muda para o estado
activeapenas após o pagamento bem-sucedido - Útil quando você quer garantir o pagamento antes de conceder recursos atualizados
on_payment_failure usa a configuração padrão do nível de negócio configurada no painel.Quando Usar Cada Modo
| Cenário | Modo Recomendado | Razão |
|---|---|---|
| Atualização para recursos premium | prevent_change | Garantir pagamento antes de conceder acesso |
| Aumento de quantidade (mais assentos) | prevent_change | Prevenir uso sem pagamento |
| Downgrade de planos | apply_change | Cliente está reduzindo despesas |
| Clientes corporativos confiáveis | apply_change | Menor risco de falta de pagamento |
| Conversão de teste para pago | prevent_change | Momento crítico de pagamento |
Lidando com Webhooks
Acompanhe o estado da assinatura através de webhooks para confirmar mudanças de plano e pagamentos.Tipos de eventos a serem tratados
subscription.active: assinatura ativadasubscription.plan_changed: plano de assinatura alterado (upgrade/downgrade/mudanças de addon)subscription.on_hold: cobrança falhou, assinatura pausadasubscription.renewed: renovação bem-sucedidapayment.succeeded: pagamento para mudança de plano ou renovação bem-sucedidopayment.failed: pagamento falhou
Verifique assinaturas e gerencie intenções
- Next.js Route Handler
- Express.js
Melhores Práticas
Siga estas recomendações para mudanças de plano de assinatura confiáveis:Estratégia de Mudança de Plano
- Teste completamente: Sempre teste mudanças de plano em modo de teste antes da produção
- Escolha o rateio com cuidado: Selecione o modo de rateio que alinha com seu modelo de negócios
- Lide graciosamente com falhas: Implemente tratamento de erro adequado e lógica de retry
- Monitore taxas de sucesso: Acompanhe taxas de sucesso/falha de mudança de plano e investigue problemas
Implementação de Webhook
- Verifique assinaturas: Sempre valide assinaturas de webhook para garantir autenticidade
- Implemente idempotência: Lide graciosamente com eventos duplicados de webhook
- Processe de forma assíncrona: Não bloqueie respostas de webhook com operações pesadas
- Registre tudo: Mantenha logs detalhados para depuração e auditoria
Experiência do Usuário
- Comunique claramente: Informe os clientes sobre mudanças de cobrança e tempos
- Forneça confirmações: Envie confirmações por email para mudanças de plano bem-sucedidas
- Lide com casos extremos: Considere períodos de teste, rateios e pagamentos falhados
- Atualize a UI imediatamente: Reflita mudanças de plano na interface do seu aplicativo
Problemas Comuns e Soluções
Resolva problemas típicos encontrados durante mudanças de plano de assinatura:Charge created but subscription not updated
Charge created but subscription not updated
- Processamento de Webhook falhou ou foi atrasado
- Estado da aplicação não atualizado após receber webhooks
- Problemas de transação de banco de dados durante atualização de estado
- Implemente um manuseio robusto de webhook com lógica de retry
- Use operações idempotentes para atualizações de estado
- Adicione monitoramento para detectar e alertar sobre eventos de webhook perdidos
- Verifique se o endpoint de webhook está acessível e respondendo corretamente
Credits not applied after downgrade
Credits not applied after downgrade
- Expectativas do modo de rateio: downgrades creditam a diferença total do preço do plano com
difference_immediately, enquantoprorated_immediatelycria um crédito rateado com base no tempo restante no ciclo - Créditos são específicos da assinatura e não se transferem entre assinaturas
- Saldo de crédito não visível no painel do cliente
- Use
difference_immediatelypara downgrades quando você quer créditos automáticos - Explique aos clientes que os créditos se aplicam a futuras renovações da mesma assinatura
- Implemente um portal do cliente para mostrar saldos de crédito
- Verifique a pré-visualização da próxima fatura para ver créditos aplicados
Webhook signature verification fails
Webhook signature verification fails
- Chave secreta de webhook incorreta
- Corpo da solicitação bruto modificado antes da verificação de assinatura
- Algoritmo de verificação de assinatura errado
- Verifique se você está usando o correto
DODO_WEBHOOK_SECRETdo painel - Leia o corpo da solicitação bruto antes de qualquer middleware de análise JSON
- Use a biblioteca padrão de verificação de webhook para sua plataforma
- Teste a verificação de assinatura de webhook no ambiente de desenvolvimento
Plan change fails with 422 error
Plan change fails with 422 error
- ID de assinatura ou ID de produto inválido
- Assinatura não está em estado ativo
- Parâmetros obrigatórios ausentes
- Produto não disponível para mudanças de plano
- Verifique se a assinatura existe e está ativa
- Verifique se o ID do produto é válido e disponível
- Certifique-se de que todos os parâmetros obrigatórios são fornecidos
- Revise a documentação da API para requisitos de parâmetro
Immediate charge fails during plan change
Immediate charge fails during plan change
- Fundos insuficientes no método de pagamento do cliente
- Método de pagamento expirado ou inválido
- Banco recusou a transação
- Detecção de fraude bloqueou a cobrança
- Lide apropriadamente com eventos de webhook
payment.failed - Notifique o cliente para atualizar o método de pagamento
- Implemente lógica de retry para falhas temporárias
- Considere permitir mudanças de plano com cobranças imediatas falhadas
Subscription on hold after plan change
Subscription on hold after plan change
on_holdO que acontece:
Quando uma cobrança de mudança de plano falha, a assinatura é automaticamente colocada em 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 do estado on_hold após uma mudança de plano falhada:- Atualize o método de pagamento usando a API de Atualização de Método de Pagamento
- Criação automática de cobrança: A API cria automaticamente uma cobrança para as dívidas restantes
- Geração de fatura: Uma fatura é gerada para a cobrança
- Processamento de pagamento: O pagamento é processado usando o novo método de pagamento
- Reativação: Após o pagamento bem-sucedido, a assinatura é reativada para o estado
active
subscription.on_hold: Assinatura colocada em espera (recebido quando cobrança de mudança de plano falha)payment.succeeded: Pagamento pelas dívidas restantes bem-sucedido (após atualização do método de pagamento)subscription.active: Assinatura reativada após pagamento bem-sucedido
- Notifique os clientes imediatamente quando uma cobrança de mudança de plano falhar
- Forneça instruções claras sobre como atualizar seu método de pagamento
- Monitore eventos de webhook para acompanhar o status de reativação
- Considere implementar lógica de retry automático para falhas temporárias de pagamento
Update Payment Method API Reference
Testando Sua Implementação
Siga estas etapas para testar completamente sua implementação de mudança de plano de assinatura:Set up test environment
- Use chaves de API de teste e produtos de teste
- Crie assinaturas de teste com diferentes tipos de plano
- Configure endpoint de webhook de teste
- Configure monitoramento e registro
Test different proration modes
- Teste
prorated_immediatelycom várias posições de ciclo de cobrança - Teste
difference_immediatelypara upgrades e downgrades - Teste
full_immediatelypara reiniciar ciclos de cobrança - Teste
do_not_billpara trocas de plano sem cobrança/crédito - Verifique se os cálculos de crédito estão corretos
Test webhook handling
- Verifique se todos os eventos relevantes de webhook são recebidos
- Teste a verificação de assinatura do webhook
- Lide graciosamente com eventos duplicados de webhook
- Teste cenários de falha de processamento de webhook
Test error scenarios
- Teste com IDs de assinatura inválidos
- Teste com métodos de pagamento expirados
- Teste falhas de rede e tempos de espera
- Teste com fundos insuficientes
Tratamento de Erros
Trate adequadamente erros comuns de API em sua implementação:Códigos de Status HTTP
200 OK
200 OK
400 Bad Request
400 Bad Request
401 Unauthorized
401 Unauthorized
404 Not Found
404 Not Found
422 Unprocessable Entity
422 Unprocessable Entity
500 Internal Server Error
500 Internal Server Error
Formato de Resposta de Erro
Próximos Passos
- Reveja a API de Mudança de Plano
- Explore Faturamento Baseado em Crédito
- Implemente alertas para
subscription.on_hold - Confira nosso Guia de Integração de Webhooks