Change Plan API
Plan Change Preview
Integration Guide
Vad är en uppgradering eller nedgradering av en prenumeration?
Ändra kundens prenumerationsplan för att flytta dem mellan nivåer, justera kvantiteten för sätesbaserade produkter eller migrera till en ny produkt. API:t beräknar automatiskt proportionella belopp och debiteringar baserat på det valda debiteringsläget.När ska planändringar användas?
- 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
- Krediterar den oanvända delen av den aktuella cykeln, proportionellt efter återstående tid
- Debiterar sedan en hel cykel för den nya planen – priset för den nya planen proportioneras aldrig
- Nettodebitering = hel ny cykel − (återstående andel × hel gammal cykel)
Implement the Change Plan API
prorated_immediately, full_immediately, difference_immediately eller do_not_bill.null eller skickar en tom array tas alla befintliga tillägg bort, så inkludera befintliga tillägg för att behålla dem.prevent_change: Behåll prenumerationen på den aktuella planen tills betalningen lyckasapply_change(standard): Tillämpa planändringen omedelbart oavsett betalningsresultat
allow_plan_change_via_payment_link-funktion (Settings → Subscriptions → Collect Plan Change Payments by Payment Link), effective_at: immediately och on_payment_failure: prevent_change. Se Collecting Payment via a Checkout Link. Ignoreras av förhandsgranskningsrutten.subscription_id, payment_id och status. Kräver collect_via_payment_link: true; annars misslyckas begäran med 422. Se Omdirigera kunden efter betalning.409. Se Ersätta en väntande betalningslänk. Ignoreras av preview-routen.- Inte angivet /
null— befintliga rabatter medpreserve_on_plan_change=truebevaras om de gäller för den nya produkten. [](tom array) — tar bort alla befintliga rabatter från prenumerationen.["CODE_A", "CODE_B", ...]— ersätter alla befintliga rabatter med denna staplade uppsättning.
discount_codes för nya integrationer. Fältet fungerar fortfarande av bakåtkompatibilitetsskäl, men kan inte kombineras med discount_codes i samma begäran.immediately(standard): Tillämpa planändringen omedelbartnext_billing_date: Schemalägg ändringen till nästa faktureringsdatum. Kunden behåller sin aktuella plan tills faktureringsperioden är slut. Använd detta för nedgraderingar så att kunderna behåller fördelarna med sin aktuella plan fram till faktureringsperiodens slut.
Handle Webhook Events
subscription.active: Planändringen lyckades, prenumerationen uppdateradessubscription.plan_changed: Prenumerationsplanen ändrades (uppgradering/nedgradering/uppdatering av tillägg)subscription.on_hold: Debiteringen för planändringen misslyckades, förnyelser stoppadespayment.succeeded: Den omedelbara debiteringen för planändringen lyckadespayment.failed: Den omedelbara debiteringen misslyckades
Update Your Application State
- Ge eller återkalla funktioner baserat på den nya planen
- Uppdatera kundpanelen med information om den nya planen
- Skicka bekräftelsemejl om planändringar
- Logga faktureringsändringar för granskningsändamål
Test and Monitor
- Testa alla prorateringslägen med olika scenarier
- Kontrollera att webhook-hanteringen fungerar korrekt
- Övervaka hur ofta planändringar lyckas
- Konfigurera aviseringar för misslyckade planändringar
Förhandsvisa planändringar
Innan du genomför en planändring kan du använda Preview API för att visa kunderna exakt vad de kommer att debiteras:- Node.js SDK
- Python SDK
immediate_charge.summary är customer_credits nett förändringen av kundens kreditsaldo, i den valuta som anges av customer_credits_currency. Detta är valutan för kundens kreditplånbok, vilket är prenumerationens valuta. Den kan skilja sig från sammanfattningens currency, som gäller för total_amount och tax. En kund som till exempel betalar i INR för en prenumeration i USD ser krediter i USD.Change Plan API
Använd Change Plan API för att ändra produkt, kvantitet och prorateringsbeteende för en aktiv prenumeration.Snabbstartsexempel
- Node.js SDK
- Python SDK
- Go SDK
- HTTP
200 OK omedelbart — innan någon debitering faktiskt har genomförts. Vad body (ChangePlanResponse) innehåller beror på hur ändringen samlades in:
collect_via_payment_link behåller prenumerationen sin aktuella plan tills kunden slutför betalningen.Bekräfta resultatet via webhook (payment.succeeded, payment.failed, subscription.plan_changed) eller genom att läsa prenumerationen igen med GET /subscriptions/{subscription_id} — se Vad händer medan länken är obetald för fallet med betalningslänk.Samla in betalning via en kassalänk
Som standard debiterar en omedelbar planändring prenumerationens sparade betalningsmetod direkt. Angecollect_via_payment_link: true för att i stället skicka kunden till en hostad kassasida — användbart när ingen betalningsmetod har sparats eller när du vill att kunden aktivt ska bekräfta det nya priset.
Krav
collect_via_payment_link: true lyckas endast när alla följande villkor är uppfyllda — annars misslyckas begäran med 422:
- Företaget har funktionen
allow_plan_change_via_payment_linkaktiverad (Settings → Subscriptions → Collect Plan Change Payments by Payment Link). effective_atärimmediately(standard). En schemalagd ändring (next_billing_date) behöver aldrig en kassasida.- Begäran anger
on_payment_failure: prevent_change. Ett uttryckligtapply_changemisslyckas med422.
collect_via_payment_link gäller för alla omedelbara ändringar som leder till en debitering, inklusive nedgraderingar, så länge kraven ovan är uppfyllda.payment_link och de andra checkout-fälten returneras som null, och ändringen tillämpas omedelbart. Detta är inte ett 422. Anropa Preview Plan Change först för att kontrollera beloppet innan du begär en länk.
- Node.js SDK
- Python SDK
- HTTP
Vad händer medan länken är obetald
- Prenumerationen stannar på sin aktuella plan —
product_id,recurring_pre_tax_amountochnext_billing_dateförblir oförändrade tills länken har betalats. - En ytterligare begäran med
change-planavvisas med409 PendingPlanChangeExistsmedan länken väntar. Skicka den nya begäran medcancel_older_payment_link: trueför att ersätta den väntande ändringen. Se Ersätta en väntande betalningslänk. - Försök igen efter en nekad betalning genom att anropa
change-planigen för att få en ny länk. - Om länken aldrig betalas slutar den att fungera efter
expires_on— prenumerationen blir automatiskt tillgänglig för en ny begäran om planändring kort därefter. - Om en schemalagd ändring redan fanns och du ersätter den med
cancel_scheduled_change_plan: trueligger det ursprungliga schemat kvar medan länken är obetald och avbryts först när länken har betalats — i samma transaktion som tillämpar den nya planen.
Omdirigera kunden efter betalning
Angereturn_url för att skicka kunden tillbaka till din webbplats efter att länken har betalats:
return_url med följande query-parametrar:
return_url kräver collect_via_payment_link: true. Utan detta misslyckas begäran med 422.
Ersätta en väntande betalningslänk
Om kunden lämnar checkout utan att betala anger ducancel_older_payment_link: true i nästa begäran med change-plan. Dodo Payments avbryter den obetalda länken och den nya planändringen ersätter den väntande. Den avbrutna länken accepterar inte längre någon betalning, inte ens på en checkout-sida som redan är öppen.
change-plan utfärdar en egen faktura. Den ersatta planändringen och dess faktura avbryts. Om ingen planändring väntar har cancel_older_payment_link ingen effekt.
Hantera tillägg
När du ändrar prenumerationsplaner kan du även ändra tillägg:Tillämpa rabattkoder
Tillämpa en eller flera staplade rabattkoder när du ändrar prenumerationsplaner (max 20, tillämpas i arrayordning):- Node.js SDK
- Python SDK
- HTTP
Rabattbeteende vid planändring
discount_code på denna endpoint är föråldrat, men fungerar fortfarande av bakåtkompatibilitetsskäl — befintliga integrationer behöver inte ändras omedelbart. Det kan inte kombineras med discount_codes i samma begäran. Migrera till arrayformen när det passar.Prorateringslägen
Välj hur kunden ska debiteras när planer ändras:prorated_immediately
- Krediterar den outnyttjade delen av den aktuella cykeln — basplan, kvantitet och tillägg — proraterat efter återstående tid
- Debiterar sedan en hel cykel för den nya planen, kvantiteten och tilläggen. Själva debiteringen prorateras aldrig
- Omedelbar nettodebitering = (hel ny cykel) − (återstående andel × hel gammal cykel)
- Om krediten överstiger debiteringen för den nya cykeln (vanligt vid nedgraderingar) hålls mellanskillnaden som prenumerationsspecifik kredit för framtida förnyelser
- Under en provperiod debiteras kunden omedelbart och byter till den nya planen nu
full_immediately
- Debiterar hela beloppet för den nya planen omedelbart
- Ignorerar återstående tid på den gamla planen — ingen kredit för den aktuella cykeln
prorated_immediately och av nedgraderingar med difference_immediately är prenumerationsspecifika och skiljer sig från förmåner i Credit-Based Billing. De tillämpas automatiskt på framtida förnyelser av samma prenumeration och kan inte överföras mellan prenumerationer.difference_immediately
- Uppgradering: debiterar omedelbart prisskillnaden mellan de gamla och nya planerna
- Nedgradering: lägger till återstående värde som intern kredit på prenumerationen och tillämpar den automatiskt vid förnyelser
do_not_bill
- Inga debiteringar eller krediter beräknas
- Kunden byter omedelbart till den nya planen utan någon faktureringsjustering
- Faktureringscykeln förblir oförändrad
- Passar bäst för kostnadsfria migreringar, byte till kostnadsfria planer eller när kostnadsskillnader absorberas
Exempelscenarier
Använd dessa standardiserade siffror konsekvent:- Aktuell plan: Basic på $30/månad
- Målplan för uppgradering: Pro på $80/månad
- Målplan för nedgradering (från Pro): Starter på $20/månad
- Faktureringscykel: 30 dagar, startade 1 januari
- Planändringen sker 16 januari (15 dagar återstår, 15 dagar har förflutit)
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
Så behandlar varje läge faktureringen
Hantera betalningsfel
Styr vad som händer när en betalning för en planändring misslyckas med parameternon_payment_failure.
Lägen för betalningsfel
- prevent_change (Recommended for critical upgrades)
- apply_change (Default)
- Planändringen markeras som “pending”
- Kunden behåller åtkomsten till sin aktuella plan
- Prenumerationen övergår till tillståndet
activeförst efter en lyckad betalning - Användbart när du vill säkerställa betalning innan uppgraderade funktioner beviljas
on_payment_failure den standardinställning på företagsnivå som konfigurerats i dashboarden.När varje läge ska användas
Företags- och insamlingsstandarder
Ange standardbeteende för uppgraderingar och nedgraderingar på företagsnivå under Settings → Subscriptions. Dessa standardvärden gäller för alla planändringar i kundportalen och kan åsidosättas per produktsamling. Separata standardvärden finns för uppgraderingar och nedgraderingar:Prioritetsordning
För en viss planändring löses varje inställning i följande ordning:Hantera webhooks
Följ prenumerationens tillstånd via webhooks för att bekräfta planändringar och betalningar.Händelsetyper att hantera
subscription.active: prenumerationen aktiveradsubscription.plan_changed: prenumerationsplanen ändrad (uppgradering/nedgradering/ändringar av tillägg)subscription.on_hold: debiteringen misslyckades, förnyelser stoppadesubscription.renewed: förnyelsen lyckadespayment.succeeded: betalningen för planändringen eller förnyelsen lyckadespayment.failed: betalningen misslyckades
Verifiera signaturer och hantera avsikter
- Next.js Route Handler
- Express.js
Bästa praxis
Strategi för planändringar
- Testa noggrant: Testa alltid planändringar i testläge före produktion
- Välj proratering med omsorg: Välj det prorateringsläge som passar din affärsmodell
- Hantera fel på ett robust sätt: Implementera korrekt felhantering och logik för nya försök
- Övervaka lyckade ändringar: Följ hur ofta planändringar lyckas eller misslyckas och undersök problem
Webhook-implementation
- Verifiera signaturer: Validera alltid webhook-signaturer för att säkerställa äkthet
- Implementera idempotens: Hantera duplicerade webhook-händelser på ett robust sätt
- Bearbeta asynkront: Blockera inte webhook-svar med tunga operationer
- Logga allt: För detaljerade loggar för felsökning och granskningsändamål
Användarupplevelse
- Kommunicera tydligt: Informera kunderna om faktureringsändringar och tidpunkter
- Ge bekräftelser: Skicka bekräftelsemejl för lyckade planändringar
- Hantera specialfall: Ta hänsyn till provperioder, proratering och misslyckade betalningar
- Uppdatera gränssnittet omedelbart: Återspegla planändringar i applikationens gränssnitt
Vanliga problem och lösningar
Lös typiska problem som uppstår vid ändringar av prenumerationsplaner:Charge created but subscription not updated
Charge created but subscription not updated
- Webhook-bearbetningen misslyckades eller fördröjdes
- Applikationens tillstånd uppdaterades inte efter mottagna webhooks
- Problem med databastransaktioner under tillståndsuppdateringen
- Implementera webhook-hantering med logik för nya försök
- Använd idempotenta operationer för tillståndsuppdateringar
- Lägg till övervakning för att upptäcka och avisera om missade webhook-händelser
- Kontrollera att webhook-endpointen är åtkomlig och svarar korrekt
Credits not applied after downgrade
Credits not applied after downgrade
- Förväntningar på prorateringsläget: nedgraderingar krediterar hela prisskillnaden mellan planerna med
difference_immediately, medanprorated_immediatelykrediterar den outnyttjade tiden i den gamla cykeln och sedan debiterar en hel cykel för den nya planen — ett kreditsaldo blir därför bara kvar när krediten överstiger priset för den nya planen - Krediter är prenumerationsspecifika och överförs inte mellan prenumerationer
- Kreditsaldot visas inte i kundpanelen
- Använd
difference_immediatelyför nedgraderingar när du vill ha automatiska krediter - Förklara för kunderna att krediter tillämpas på framtida förnyelser av samma prenumeration
- Implementera kundportalen så att kreditsaldon visas
- Kontrollera nästa fakturaförhandsvisning för att se tillämpade krediter
Webhook signature verification fails
Webhook signature verification fails
- Felaktig webhook-hemlighet
- Rå request body ändrades före signaturverifieringen
- Fel algoritm för signaturverifiering
- Kontrollera att du använder korrekt
DODO_PAYMENTS_WEBHOOK_KEYfrån dashboarden - Läs den råa request body innan någon JSON-parsning sker
- Använd standardbiblioteket för webhook-verifiering för din plattform
- Testa webhook-signaturverifieringen i utvecklingsmiljön
Plan change fails with 422 error
Plan change fails with 422 error
- Ogiltigt prenumerations-ID eller produkt-ID
- Prenumerationen är inte i aktivt tillstånd
- Obligatoriska parametrar saknas
- Produkten är inte tillgänglig för planändringar
- Kontrollera att prenumerationen finns och är aktiv
- Kontrollera att produkt-ID:t är giltigt och tillgängligt
- Säkerställ att alla obligatoriska parametrar anges
- Läs API-dokumentationen för parameterkrav
Immediate charge fails during plan change
Immediate charge fails during plan change
- Otillräckliga medel på kundens betalningsmetod
- Betalningsmetoden har löpt ut eller är ogiltig
- Banken nekade transaktionen
- Bedrägeridetektering blockerade debiteringen
- Hantera webhook-händelser med
payment.failedpå lämpligt sätt - Meddela kunden att betalningsmetoden behöver uppdateras
- Implementera logik för nya försök vid tillfälliga fel
- Överväg att tillåta planändringar när omedelbara debiteringar misslyckas
Subscription on hold after plan change
Subscription on hold after plan change
on_holdVad händer:
När en debitering för en planändring misslyckas placeras prenumerationen automatiskt i tillståndet on_hold. Prenumerationen förnyas inte automatiskt förrän betalningsmetoden har uppdaterats.Lösning: Uppdatera betalningsmetoden för att återaktivera prenumerationenSå här återaktiverar du en prenumeration från tillståndet on_hold efter en misslyckad planändring:- Uppdatera betalningsmetoden med Update Payment Method API
- Automatisk skapelse av debitering: API:t skapar automatiskt en debitering för återstående skulder
- Fakturagenerering: En faktura genereras för debiteringen
- Betalningshantering: Betalningen behandlas med den nya betalningsmetoden
- Återaktivering: När betalningen lyckas återaktiveras prenumerationen till tillståndet
active
subscription.on_hold: Prenumerationen sattes på paus (mottas när debiteringen för planändringen misslyckas)payment.succeeded: Betalningen för återstående skulder lyckades (efter uppdatering av betalningsmetoden)subscription.active: Prenumerationen återaktiverades efter lyckad betalning
- Meddela kunderna omedelbart när en debitering för en planändring misslyckas
- Ge tydliga instruktioner om hur betalningsmetoden uppdateras
- Övervaka webhook-händelser för att följa återaktiveringsstatus
- Överväg att implementera automatisk logik för nya försök vid tillfälliga betalningsfel
Update Payment Method API Reference
Testa din implementation
Testa din implementation av planändringar för prenumerationer noggrant:Set up test environment
- Använd test-API-nycklar och testprodukter
- Skapa testprenumerationer med olika plantyper
- Konfigurera en test-endpoint för webhooks
- Konfigurera övervakning och loggning
Test different proration modes
- Testa
prorated_immediatelymed olika positioner i faktureringscykeln - Testa
difference_immediatelyför uppgraderingar och nedgraderingar - Testa
full_immediatelyför att återställa faktureringscykler - Testa
do_not_billför planbyten utan debitering eller kredit - Kontrollera att krediterna beräknas korrekt
Test webhook handling
- Kontrollera att alla relevanta webhook-händelser tas emot
- Testa webhook-signaturverifieringen
- Hantera duplicerade webhook-händelser på ett robust sätt
- Testa scenarier där webhook-bearbetningen misslyckas
Test error scenarios
- Testa med ogiltiga prenumerations-ID:n
- Testa med utgångna betalningsmetoder
- Testa nätverksfel och tidsgränser
- Testa med otillräckliga medel
Monitor in production
- Konfigurera aviseringar för misslyckade planändringar
- Övervaka webhook-bearbetningstider
- Följ hur ofta planändringar lyckas
- Granska kundsupportärenden om problem med planändringar
Felhantering
Hantera vanliga API-fel på ett robust sätt i din implementation:HTTP-statuskoder
200 OK
200 OK
ChangePlanResponse med payment_id, payment_link, client_secret och expires_on. Alla fyra kan vara null, så kroppen serialiseras som {} för en vanlig off-session-ändring; de är ifyllda för en lyckad begäran med collect_via_payment_link, som returnerar checkout-referenser — se Samla in betalning via en kassalänk. Om on_payment_failure=prevent_change förblir planändringen väntande tills betalningen lyckas.400 Bad Request
400 Bad Request
409 Conflict
409 Conflict
PendingPlanChangeExists). För en schemalagd ändring avbryter du den med DELETE /subscriptions/{subscription_id}/change-plan/scheduled innan du skickar en ny. För en väntande ändring via betalningslänk skickar du den nya begäran med cancel_older_payment_link: true för att ersätta den. Se Ersätta en väntande betalningslänk.Med cancel_older_payment_link: true betyder 409 att kunden betalar den föregående länken just nu (PLAN_CHANGE_PAYMENT_IN_PROGRESS) eller redan har betalat den (PLAN_CHANGE_PAYMENT_ALREADY_COMPLETED).422 Unprocessable Entity
422 Unprocessable Entity
collect_via_payment_link — företaget har inte funktionen aktiverad, effective_at är inte immediately eller on_payment_failure är inte prevent_change. Se Krav. Ett prenumerations-ID som inte finns eller inte tillhör ditt konto returnerar 404 med koden NOT_FOUND.500 Internal Server Error
500 Internal Server Error
Format för felsvar
Fel returnerar en JSON-kropp med encode och en läsbar message:
Nästa steg
- Läs igenom Change Plan API
- Utforska Credit-Based Billing
- Implementera aviseringar för
subscription.on_hold - Läs guiden för webhook-integration