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
preserve_on_plan_change=true, la réduction existante sera conservée (si applicable au nouveau produit).immediately(par défaut) : Appliquer le changement de plan immédiatementnext_billing_date: Programmer le changement pour la prochaine date de facturation. Le client conserve son plan actuel jusqu’à la fin de la période de facturation.
next_billing_date pour les rétrogradations afin que les clients conservent les avantages de leur plan actuel jusqu’à la fin de la période de facturation.Handle Webhook Events
subscription.active: Changement de plan réussi, abonnement mis à joursubscription.plan_changed: Plan d’abonnement changé (mise à niveau/rétrogradation/mise à jour des add-ons)subscription.on_hold: Échec du prélèvement pour changement de plan, abonnement en pausepayment.succeeded: Prélèvement immédiat pour changement de plan réussipayment.failed: Échec du prélèvement immédiat
Update Your Application State
- Accorder/révoquer des fonctionnalités en fonction du nouveau plan
- Mettre à jour le tableau de bord client avec les détails du nouveau plan
- Envoyer des e-mails de confirmation concernant les changements de plan
- Enregistrer les changements de facturation pour des raisons d’audit
Test and Monitor
- Testez tous les modes de calcul des prorata avec différents scénarios
- Vérifiez que la gestion des webhooks fonctionne correctement
- Surveillez les taux de succès des changements de plan
- Configurez des alertes pour les changements de plan échoués
Aperçu des changements de plan
Avant de s’engager dans un changement de plan, utilisez l’API Aperçu pour montrer aux clients exactement ce qui leur sera facturé :- Node.js SDK
- Python SDK
API de changement de plan
Utilisez l’API Changer de plan pour modifier le produit, la quantité et le comportement des prorata pour un abonnement actif.Exemples de démarrage rapide
- Node.js SDK
- Python SDK
- Go SDK
- HTTP
invoice_id et payment_id sont retournés uniquement lorsqu’une facturation immédiate et/ou une facture est créée lors du changement de plan. Appuyez-vous toujours sur les événements de webhook (par exemple, payment.succeeded, subscription.plan_changed) pour confirmer les résultats.Gestion des addons
Lors du changement de plans d’abonnement, vous pouvez également modifier les addons :Application de codes de réduction
Vous pouvez appliquer un code de réduction lors du changement de plans d’abonnement. Cela est utile pour offrir des tarifs promotionnels sur les mises à niveau ou les migrations.- Node.js SDK
- Python SDK
- HTTP
Comportement de la réduction lors du changement de plan
| Scénario | Comportement |
|---|---|
discount_code fourni | Valide et applique la réduction au nouveau plan. |
Aucun code fourni, réduction existante avec preserve_on_plan_change=true | La réduction existante est automatiquement conservée si applicable au nouveau produit. |
| Aucun code fourni, aucune réduction conservable | Aucune réduction appliquée au nouveau plan. |
Modes de calcul des prorata
Choisissez comment facturer le client lors du changement de plan :prorated_immediately
- Facturation de la différence partielle dans le cycle actuel
- Si en période d’essai, facturation immédiate et passage au nouveau plan maintenant
- Rétrogradation : peut générer un crédit proratisé appliqué aux futurs renouvellements
full_immediately
- Facture immédiatement le montant total du nouveau plan
- Ignore le temps restant de l’ancien plan
difference_immediately sont limités à l’abonnement et distincts des droits de facturation basée sur le crédit. Ils s’appliquent automatiquement aux futurs renouvellements du même abonnement et ne sont pas transférables entre abonnements.difference_immediately
- Mise à niveau : facturer immédiatement la différence entre les anciens et nouveaux plans
- Rétrogradation : ajouter la valeur restante en tant que crédit interne à l’abonnement et l’appliquer automatiquement lors des renouvellements
do_not_bill
- Aucune facturation ou crédit n’est calculé
- Le client passe immédiatement au nouveau plan sans aucun ajustement de facturation
- Le cycle de facturation reste inchangé
- Idéal pour les migrations de courtoisie, les changements de plan gratuits ou l’absorption des différences de coût
| Fonctionnalité | prorated_immediately | difference_immediately | full_immediately | do_not_bill |
|---|---|---|---|---|
| Frais de mise à niveau | Différence proratisée pour les jours restants | Différence de prix totale entre les plans | Prix du nouveau plan en intégralité | Aucun frais |
| Crédit de rétrogradation | Crédit proratisé pour les jours restants | Différence de prix totale en tant que crédit | Aucun crédit | Aucun crédit |
| Cycle de facturation | Inchange | Inchange | Réinitialisé à aujourd’hui | Inchange |
| Comportement d’essai | Fin de l’essai, facturation immédiate | Fin de l’essai, facturation immédiate | Fin de l’essai, facturation totale | Fin de l’essai, pas de frais |
| Idéal pour | Facturation équitable basée sur le temps | Calcul simple de mise à niveau/rétrogradation | Réinitialisation des cycles de facturation | Migrations gratuites ou changements de courtoisie |
| Complexité | Moyenne (calcul des jours) | Basse (soustraction simple) | Basse (plein montant) | Aucune |
Scénarios d’exemple
Utilisez ces nombres canoniques de manière cohérente :- Plan actuel : Basic à 30 $/mois
- Objectif de mise à niveau : Pro à 80 $/mois
- Objectif de rétrogradation (de Pro) : Starter à 20 $/mois
- Cycle de facturation : 30 jours, commencé le 1er janvier
- Changement de plan se produit le 16 janvier (15 jours restants, 15 jours utilisés)
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
Comment chaque mode traite la facturation
Gestion des échecs de paiement
Contrôlez ce qui se passe lorsqu’un paiement de changement de plan échoue en utilisant le paramètreon_payment_failure.
Modes d’échec de paiement
- prevent_change (Recommended for critical upgrades)
- apply_change (Default)
- Le changement de plan est marqué comme “en attente”
- Le client conserve l’accès à son plan actuel
- L’abonnement passe à l’état
activeuniquement après un paiement réussi - Utile lorsque vous souhaitez garantir le paiement avant de débloquer des fonctionnalités améliorées
on_payment_failure utilise votre paramètre par défaut au niveau commercial configuré dans le tableau de bord.Quand utiliser chaque mode
| Scénario | Mode recommandé | Raison |
|---|---|---|
| Mise à niveau vers des fonctionnalités premium | prevent_change | Assurer le paiement avant de donner accès |
| Augmentation de quantité (plus de sièges) | prevent_change | Prévenir l’utilisation sans paiement |
| Rétrogradation des plans | apply_change | Le client réduit sa dépense |
| Clients d’entreprise de confiance | apply_change | Risque faible de non-paiement |
| Conversion de l’essai vers payant | prevent_change | Moment critique du paiement |
Gestion des webhooks
Suivez l’état de l’abonnement via les webhooks pour confirmer les changements de plan et les paiements.Types d’événements à gérer
subscription.active: abonnement activésubscription.plan_changed: plan d’abonnement modifié (mise à niveau/rétrogradation/modifications des add-ons)subscription.on_hold: échec de prélèvement, abonnement en pausesubscription.renewed: renouvellement réussipayment.succeeded: paiement pour changement de plan ou renouvellement réussipayment.failed: échec du paiement
Vérifier les signatures et gérer les intentions
- Next.js Route Handler
- Express.js
Meilleures pratiques
Suivez ces recommandations pour des changements de plan d’abonnement fiables :Stratégie de changement de plan
- Testez rigoureusement : Testez toujours les changements de plan en mode test avant la production
- Choisissez le prorata avec soin : Sélectionnez le mode de prorata qui correspond à votre modèle économique
- Gérez les échecs avec soin : Implémentez une gestion des erreurs appropriée et une logique de nouvelle tentative
- Surveillez les taux de succès : Suivez les taux de succès/échec des changements de plan et enquêtez sur les problèmes
Implémentation du webhook
- Vérifiez les signatures : Validez toujours les signatures des webhooks pour garantir l’authenticité
- Implémentez l’idempotence : Gérez gracieusement les événements de webhook en double
- Traitez de manière asynchrone : Ne bloquez pas les réponses de webhook avec des opérations lourdes
- Enregistrez tout : Maintenez des journaux détaillés pour le débogage et l’audit
Expérience utilisateur
- Communiquez clairement : Informez les clients des changements de facturation et du calendrier
- Fournissez des confirmations : Envoyez des e-mails de confirmation pour les changements de plan réussis
- Gérez les cas particuliers : Considérez les périodes d’essai, les prorata et les paiements échoués
- Mettez à jour l’interface utilisateur immédiatement : Reflétez les changements de plan dans l’interface de votre application
Problèmes courants et solutions
Résolvez les problèmes typiques rencontrés lors des changements de plan d’abonnement :Charge created but subscription not updated
Charge created but subscription not updated
- Le traitement du webhook a échoué ou a été retardé
- L’état de l’application n’a pas été mis à jour après la réception des webhooks
- Problèmes de transaction de base de données lors de la mise à jour de l’état
- Implémentez une gestion robuste des webhooks avec une logique de nouvelle tentative
- Utilisez des opérations idempotentes pour les mises à jour d’état
- Ajoutez une surveillance pour détecter et alerter sur les événements de webhook manqués
- Vérifiez que le point de terminaison du webhook est accessible et répond correctement
Credits not applied after downgrade
Credits not applied after downgrade
- Attentes de mode de prorata : les rétrogradations créditent la différence de prix totale du plan avec
difference_immediately, tandis queprorated_immediatelycrée un crédit proratisé basé sur le temps restant dans le cycle - Les crédits sont spécifiques à l’abonnement et ne se transfèrent pas entre abonnements
- Le solde des crédits n’est pas visible dans le tableau de bord du client
- Utilisez
difference_immediatelypour les rétrogradations lorsque vous voulez des crédits automatiques - Expliquez aux clients que les crédits s’appliquent aux futurs renouvellements du même abonnement
- Mettez en œuvre un portail client pour afficher les soldes de crédits
- Vérifiez l’aperçu de la prochaine facture pour voir les crédits appliqués
Webhook signature verification fails
Webhook signature verification fails
- Clé secrète du webhook incorrecte
- Corps de la requête brute modifié avant la vérification de la signature
- Mauvais algorithme de vérification de la signature
- Vérifiez que vous utilisez le bon
DODO_WEBHOOK_SECRETdepuis le tableau de bord - Lisez le corps de la requête brute avant tout middleware d’analyse JSON
- Utilisez la bibliothèque standard de vérification des webhooks pour votre plateforme
- Testez la vérification de la signature du webhook dans l’environnement de développement
Plan change fails with 422 error
Plan change fails with 422 error
- ID d’abonnement ou ID de produit invalide
- Abonnement non à l’état actif
- Paramètres requis manquants
- Produit non disponible pour les changements de plan
- Vérifiez que l’abonnement existe et est actif
- Assurez-vous que l’ID de produit est valide et disponible
- Assurez-vous que tous les paramètres requis sont fournis
- Consultez la documentation de l’API pour les exigences en matière de paramètres
Immediate charge fails during plan change
Immediate charge fails during plan change
- Fonds insuffisants sur le moyen de paiement du client
- Moyen de paiement expiré ou invalide
- Banque a refusé la transaction
- Détection de fraude a bloqué le prélèvement
- Gérer correctement les événements de webhook
payment.failed - Notifiez le client de mettre à jour le moyen de paiement
- Implémentez une logique de nouvelle tentative pour les échecs temporaires
- Envisagez d’autoriser les changements de plan avec des prélèvements immédiats échoués
Subscription on hold after plan change
Subscription on hold after plan change
on_holdCe qui se passe :
Lorsqu’un prélèvement de changement de plan échoue, l’abonnement est automatiquement placé à l’état on_hold. L’abonnement ne se renouvellera pas automatiquement tant que le moyen de paiement n’est pas mis à jour.Solution : Mettez à jour le moyen de paiement pour réactiver l’abonnementPour réactiver un abonnement à partir de l’état on_hold après un échec de changement de plan :- Mettez à jour le moyen de paiement en utilisant l’API de mise à jour du moyen de paiement
- Création automatique de prélèvement : L’API crée automatiquement un prélèvement pour les dus restants
- Génération de facture : Une facture est générée pour le prélèvement
- Traitement du paiement : Le paiement est traité en utilisant le nouveau moyen de paiement
- Réactivation : Après un paiement réussi, l’abonnement est réactivé à l’état
active
subscription.on_hold: Abonnement mis en attente (reçu lorsque le prélèvement pour changement de plan échoue)payment.succeeded: Paiement pour les dus restants réussi (après la mise à jour du moyen de paiement)subscription.active: Abonnement réactivé après le paiement réussi
- Notifiez immédiatement les clients lorsqu’un prélèvement pour changement de plan échoue
- Fournissez des instructions claires sur la façon de mettre à jour leur moyen de paiement
- Surveillez les événements de webhook pour suivre le statut de réactivation
- Envisagez d’implémenter une logique de nouvelle tentative automatique pour les échecs de paiement temporaires
Update Payment Method API Reference
Tester votre implémentation
Suivez ces étapes pour tester rigoureusement votre implémentation de changement de plan d’abonnement :Set up test environment
- Utilisez des clés API de test et des produits de test
- Créez des abonnements de test avec différents types de plan
- Configurez un point de terminaison de webhook de test
- Configurez la surveillance et les journaux
Test different proration modes
- Testez
prorated_immediatelyavec différentes positions de cycle de facturation - Testez
difference_immediatelypour les mises à niveau et rétrogradations - Testez
full_immediatelypour réinitialiser les cycles de facturation - Testez
do_not_billpour des changements de plan sans frais/sans crédit - Vérifiez que les calculs de crédit sont corrects
Test webhook handling
- Vérifiez que tous les événements de webhook pertinents sont reçus
- Testez la vérification des signatures des webhooks
- Gérez gracieusement les événements de webhook en double
- Testez les scénarios d’échec du traitement des webhooks
Test error scenarios
- Testez avec des ID d’abonnement invalides
- Testez avec des moyens de paiement expirés
- Testez les échecs de réseau et les délais d’attente
- Testez avec des fonds insuffisants
Gestion des erreurs
Gérez gracieusement les erreurs courantes de l’API dans votre implémentation :Codes d’état 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
Format de réponse d’erreur
Prochaines étapes
- Consultez l’API de Changement de Plan
- Explorez la Facturation Basée sur le Crédit
- Implémentez des alertes pour
subscription.on_hold - Consultez notre Guide d’Intégration des Webhooks