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.

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.
Plan changes can trigger an immediate charge depending on the proration mode you choose.

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
Detaljerade konfigurationsinstruktioner finns i integrationsguiden.

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:
Bäst för: SaaS-applikationer som vill kreditera oanvänd tid på den gamla planen.
  • 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)
3

Implement the Change Plan API

Use the Change Plan API to modify subscription details:
string
obligatorisk
The ID of the active subscription to modify.
string
obligatorisk
The new product ID to change the subscription to.
integer
obligatorisk
Number of units for the new plan (for seat-based products).
string
obligatorisk
How to handle immediate billing: prorated_immediately, full_immediately, difference_immediately, or do_not_bill.
array
Valfria tillägg för den nya planen. Om du utelämnar detta fält, skickar null eller skickar en tom array tas alla befintliga tillägg bort, så inkludera befintliga tillägg för att behålla dem.
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.
Samla in beloppet för planändringen med en betalningslänk i stället för att debitera prenumerationens sparade betalningsmetod. Kunden betalar på en hostad checkout-sida.Kräver företagets 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.
array
Valfria staplade rabattkoder som ska tillämpas på den nya planen (högst 20, tillämpas i arrayordning). Beteendet beror på vad du skickar:
  • Inte angivet / null – befintliga rabatter med preserve_on_plan_change=true bevaras 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.
string
föråldrad
Föråldrat – använd hellre discount_codes för nya integrationer. Fältet fungerar fortfarande för bakåtkompatibilitet, men kan inte kombineras med discount_codes i samma begäran.
string
standard:"immediately"
När planändringen ska tillämpas:
  • immediately (standard): Tillämpa planändringen direkt
  • next_billing_date: Schemalägg ändringen till nästa debiteringsdatum. Kunden behåller sin aktuella plan tills debiteringsperioden slutar. Använd detta för nedgraderingar så att kunderna behåller förmånerna från sin aktuella plan fram till debiteringsperiodens slut.
4

Handle Webhook Events

Konfigurera webhook-hantering för att spåra resultatet av planändringar:
  • subscription.active: Planändringen lyckades, prenumerationen uppdaterades
  • subscription.plan_changed: Prenumerationsplanen ändrades (uppgradering/nedgradering/tilläggsuppdatering)
  • subscription.on_hold: Debiteringen för planändringen misslyckades, förnyelser stoppades
  • payment.succeeded: Den omedelbara debiteringen för planändringen lyckades
  • payment.failed: Den omedelbara debiteringen misslyckades
Verifiera alltid webhook-signaturer och implementera idempotent händelsehantering.
5

Update Your Application State

Uppdatera applikationen baserat på webhook-händelser:
  • Bevilja/återkalla funktioner baserat på den nya planen
  • Uppdatera kundens dashboard med information om den nya planen
  • Skicka bekräftelsemeddelanden om planändringar
  • Logga debiteringsändringar för granskningsändamål
6

Test and Monitor

Testa implementationen noggrant:
  • Testa alla proportioneringslägen med olika scenarier
  • Kontrollera att webhook-hanteringen fungerar korrekt
  • Övervaka hur ofta planändringar lyckas
  • Konfigurera aviseringar för misslyckade planändringar
Din implementation av planändringar för prenumerationer är nu klar att användas i produktion.

Förhandsgranska 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:
Använd preview API för att bygga bekräftelsedialoger som visar kunderna det exakta beloppet de kommer att debiteras innan de bekräftar en planändring.

Change Plan API

Använd Change Plan API för att ändra produkt, kvantitet och proportioneringsbeteende för en aktiv prenumeration.

Snabbstartsexempel

En lyckad planändring returnerar 200 OK omedelbart – innan någon debitering faktiskt har slutförts. Vad body (ChangePlanResponse) innehåller beror på hur ändringen samlades in:
Detta svar bekräftar att begäran accepterades, inte att en debitering lyckades. Vid en vanlig omedelbar debitering fastställs resultatet off-session direkt efter anropet. För en begäran med collect_via_payment_link ligger prenumerationen kvar på 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 What Happens While the Link Is Unpaid för fallet med betalningslänk.
Om den omedelbara debiteringen misslyckas kan prenumerationen flyttas till tillståndet subscription.on_hold tills betalningen lyckas.

Samla in betalning via en checkout-länk

Som standard debiterar en omedelbar planändring prenumerationens sparade betalningsmetod direkt. Ange collect_via_payment_link: true för att i stället skicka kunden till en hostad checkout-sida – användbart när det saknas en sparad betalningsmetod eller när du vill att kunden aktivt ska bekräfta det nya priset.
Detta styr växlingsalternativet Collect Plan Change Payments by Payment Link i Settings → Subscriptions, som dirigerar planändringsflödet i Customer Portal genom checkout.

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_link aktiverad (Settings → Subscriptions → Collect Plan Change Payments by Payment Link).
  • effective_at är immediately (standardvärdet). En schemalagd ändring (next_billing_date) behöver aldrig en checkout-sida.
  • Det effektiva värdet för on_payment_failure blir prevent_change. Du behöver inte skicka det uttryckligen – om standardvärdet på företagsnivå redan är prevent_change räcker det att utelämna fältet. Ett uttryckligt apply_change misslyckas med 422.
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.
Om ändringen blir noll eller en kredit utfärdas ingen betalningslänk: 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.
En lyckad begäran returnerar checkout-handtagen:

Vad händer medan länken är obetald?

  • Prenumerationen ligger kvar på sin aktuella plan – product_id, recurring_pre_tax_amount och next_billing_date påverkas inte förrän länken är betald.
  • En ytterligare begäran med change-plan avvisas med 409 PendingPlanChangeExists medan länken väntar. Avbryt en schemalagd ändring med DELETE /subscriptions/{subscription_id}/change-plan/scheduled vid behov, men den endpointen avbryter inte en väntande ändring via betalningslänk – endast en lyckad betalning eller att länken löper ut gör det.
  • Kunden kan försöka igen med ett kort i samma checkout-session efter ett avslag; ett nytt anrop med change-plan är inte rätt väg för ett nytt försök.
  • 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: true ligger det ursprungliga schemat kvar medan länken är obetald och avbryts först när länken betalas – i samma transaktion som tillämpar den nya planen.
När en omedelbar ändring via betalningslänk har utfärdats blockeras alla ytterligare begäranden om planändring för prenumerationen – inklusive den förhandsgranskning som inte har några sidoeffekter – tills länken har lösts. Utfärda inte en länk som du inte avser att kunden ska betala omedelbart.

Hantera tillägg

När du ändrar prenumerationsplaner kan du även ändra tillägg:
Tillägg inkluderas i den proportionella beräkningen och debiteras enligt det valda proportioneringsläget.

Tillämpa rabattkoder

Tillämpa en eller flera staplade rabattkoder när du ändrar prenumerationsplaner (högst 20, tillämpas i arrayordning):

Rabattbeteende vid planändring

Det enskilda fältet discount_code på denna endpoint är föråldrat men fungerar fortfarande för bakåtkompatibilitet – befintliga integrationer behöver inte ändras omedelbart. Det kan inte kombineras med discount_codes i samma begäran. Migrera till arrayformatet när det passar.
Använd Preview Plan Change API med discount_codes för att visa kunderna exakt hur mycket de sparar innan de bekräftar planändringen.

Proportioneringslägen

Välj hur kunden ska debiteras när du ändrar planer:

prorated_immediately

  • Krediterar den oanvända delen av den aktuella cykeln – basplan, kvantitet och tillägg – proportionellt efter återstående tid
  • Debiterar sedan en hel cykel för den nya planen, kvantiteten och tilläggen. Själva debiteringen proportioneras aldrig
  • Omedelbar nettodebitering = (hel ny cykel) − (återstående andel × hel gammal cykel)
  • Om krediten överstiger debiteringen för den nya cykeln (vanligt vid nedgraderingar) sparas skillnaden som prenumerationsspecifik kredit för framtida förnyelser
  • Under en provperiod debiteras kunden omedelbart och byter till den nya planen nu

full_immediately

  • Debiterar det fulla beloppet för den nya planen omedelbart
  • Bortser från återstående tid på den gamla planen – ingen kredit för den aktuella cykeln
Krediter som skapas av 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 den gamla och den nya planen
  • 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 debiteringsjustering
  • Debiteringscykeln förblir oförändrad
  • Bäst för servicebyten, kostnadsfria planbyten eller när du absorberar kostnadsskillnader

Exempelscenarier

Använd konsekvent dessa standardtal:
  • Aktuell plan: Basic på $30/månad
  • Uppgraderingsmål: Pro på $80/månad
  • Nedgraderingsmål (från Pro): Starter på $20/månad
  • Debiteringscykel: 30 dagar, startade 1 januari
  • Planändringen sker 16 januari (15 dagar återstår, 15 dagar har använts)

Så bearbetar varje läge debiteringen

Välj prorated_immediately för att kreditera oanvänd tid på den gamla planen samtidigt som en hel cykel av den nya debiteras; välj full_immediately för att starta om debiteringen; använd difference_immediately för enkla uppgraderingar och automatisk kredit vid nedgraderingar; eller använd do_not_bill för att byta plan utan någon debiteringsjustering.

Hantera betalningsfel

Styr vad som händer när en betalning för en planändring misslyckas med parametern on_payment_failure.

Lägen för betalningsfel

Om inget anges använder parametern on_payment_failure standardinställningen på företagsnivå som konfigurerats i dashboarden.

När ska varje läge användas?

Standardinställningar för företag och insamling

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. Det finns separata standardvärden för uppgraderingar och nedgraderingar: Konfigurera företagsstandarder under Settings → Subscriptions och åsidosättningar för samlingar i varje produktsamling. Varje fält för samlingen är oberoende – lämna det tomt för att ärva företagets standardvärde eller ange ett värde för att åsidosätta det.

Prioritetsordning

För en viss planändring fastställs varje inställning i följande ordning:
Ett värde som uttryckligen skickas till Change Plan API har alltid företräde. Företagets standardvärden och samlingsstandardvärden börjar gälla endast när inget uttryckligt värde har angetts – vilket gäller för alla planändringar som initieras från kundportalen.
En vanlig konfiguration är att behålla uppgraderingar på immediately + difference_immediately så att kunderna betalar skillnaden och får åtkomst direkt, och att behålla nedgraderingar på next_billing_date så att kunderna behåller sin aktuella plan tills cykeln slutar.

Hantera webhooks

Spåra prenumerationens tillstånd via webhooks för att bekräfta planändringar och betalningar.

Händelsetyper som ska hanteras

  • subscription.active: prenumerationen aktiverades
  • subscription.plan_changed: prenumerationsplanen ändrades (uppgradering/nedgradering/tilläggsändringar)
  • subscription.on_hold: debiteringen misslyckades, förnyelser stoppades
  • subscription.renewed: förnyelsen lyckades
  • payment.succeeded: betalningen för planändringen eller förnyelsen lyckades
  • payment.failed: betalningen misslyckades
Låt prenumerationshändelser styra affärslogiken och använd betalningshändelser för bekräftelse och avstämning.

Verifiera signaturer och hantera avsikter

Detaljerade payload-scheman finns i Subscription webhook payloads och Payment webhook payloads.

Bästa praxis

Strategi för planändringar

  • Testa noggrant: Testa alltid planändringar i testläge före produktion
  • Välj proportionering med omsorg: Välj det proportioneringsläge som passar din affärsmodell
  • Hantera fel smidigt: Implementera korrekt felhantering och logik för nya försök
  • Övervaka lyckade ändringar: Följ upp hur ofta planändringar lyckas/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 smidigt sätt
  • Bearbeta asynkront: Blockera inte webhook-svar med tunga operationer
  • Logga allt: Upprätthåll detaljerade loggar för felsökning och granskning

Användarupplevelse

  • Kommunicera tydligt: Informera kunderna om debiteringsändringar och tidpunkter
  • Ge bekräftelser: Skicka e-postbekräftelser för lyckade planändringar
  • Hantera specialfall: Ta hänsyn till provperioder, proportionering och misslyckade betalningar
  • Uppdatera gränssnittet direkt: Visa planändringar omedelbart i applikationens gränssnitt

Vanliga problem och lösningar

Lös typiska problem som uppstår under planändringar för prenumerationer:
Symptom: API-anropet lyckas men prenumerationen ligger kvar på den gamla planenVanliga orsaker:
  • Webhook-bearbetningen misslyckades eller fördröjdes
  • Applikationens tillstånd uppdaterades inte efter mottagna webhooks
  • Problem med databastransaktioner under tillståndsuppdateringen
Lösningar:
  • 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 varna om missade webhook-händelser
  • Kontrollera att webhook-endpointen är åtkomlig och svarar korrekt
Symptom: Kunden nedgraderar men ser inget kreditsaldoVanliga orsaker:
  • Förväntningar på proportioneringsläget: nedgraderingar krediterar hela prisskillnaden mellan planerna med difference_immediately, medan prorated_immediately krediterar oanvänd tid i den gamla cykeln och sedan debiterar en hel cykel för den nya planen – ett kreditsaldo finns därför endast kvar när krediten överstiger priset för den nya planen
  • Krediter är prenumerationsspecifika och överförs inte mellan prenumerationer
  • Kreditsaldot visas inte i kundens dashboard
Lösningar:
  • Använd difference_immediately fö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 förhandsgranskningen av nästa faktura för att se tillämpade krediter
Symptom: Webhook-händelser avvisas på grund av ogiltig signaturVanliga orsaker:
  • Felaktig hemlig webhook-nyckel
  • Den råa request body ändrades före signaturverifieringen
  • Fel algoritm för signaturverifiering
Lösningar:
  • Kontrollera att du använder rätt DODO_PAYMENTS_WEBHOOK_KEY från dashboarden
  • Läs den råa request body innan någon JSON-parsningsmiddleware körs
  • Använd standardbiblioteket för webhook-verifiering för din plattform
  • Testa webhook-signaturverifieringen i utvecklingsmiljön
Symptom: API:t returnerar felet 422 Unprocessable EntityVanliga orsaker:
  • 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
Lösningar:
  • Kontrollera att prenumerationen finns och är aktiv
  • Kontrollera att produkt-ID:t är giltigt och tillgängligt
  • Säkerställ att alla obligatoriska parametrar har angetts
  • Läs API-dokumentationen för krav på parametrar
Symptom: Planändringen initierades men den omedelbara debiteringen misslyckadesVanliga orsaker:
  • Otillräckliga medel på kundens betalningsmetod
  • Betalningsmetoden har löpt ut eller är ogiltig
  • Banken avvisade transaktionen
  • Bedrägeridetektering blockerade debiteringen
Lösningar:
  • Hantera webhook-händelser med payment.failed på lämpligt sätt
  • Meddela kunden att betalningsmetoden måste uppdateras
  • Implementera logik för nya försök vid tillfälliga fel
  • Överväg att tillåta planändringar även när omedelbara debiteringar misslyckas
Symptom: Debiteringen för planändringen misslyckas och prenumerationen flyttas till tillståndet 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:
  1. Uppdatera betalningsmetoden med Update Payment Method API
  2. Skapa debitering automatiskt: API:t skapar automatiskt en debitering för återstående skulder
  3. Skapa faktura: En faktura skapas för debiteringen
  4. Bearbeta betalningen: Betalningen behandlas med den nya betalningsmetoden
  5. Återaktivering: När betalningen lyckas återaktiveras prenumerationen till tillståndet active
Webhook-händelser att övervaka:
  • subscription.on_hold: Prenumerationen pausades (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
Bästa praxis:
  • 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

Visa den fullständiga API-dokumentationen för uppdatering av betalningsmetoder och återaktivering av prenumerationer.

Testa din implementation

Testa din implementation av planändringar för prenumerationer noggrant:
1

Set up test environment

  • Använd test-API-nycklar och testprodukter
  • Skapa testprenumerationer med olika plantyper
  • Konfigurera en testendpoint för webhooks
  • Konfigurera övervakning och loggning
2

Test different proration modes

  • Testa prorated_immediately med olika positioner i debiteringscykeln
  • Testa difference_immediately för uppgraderingar och nedgraderingar
  • Testa full_immediately för att återställa debiteringscykler
  • Testa do_not_bill för planbyten utan debitering eller kredit
  • Kontrollera att kreditberäkningarna är korrekta
3

Test webhook handling

  • Kontrollera att alla relevanta webhook-händelser tas emot
  • Testa verifiering av webhook-signaturer
  • Hantera duplicerade webhook-händelser på ett smidigt sätt
  • Testa scenarier där webhook-bearbetningen misslyckas
4

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
5

Monitor in production

  • Konfigurera aviseringar för misslyckade planändringar
  • Övervaka webhook-bearbetningstider
  • Följ upp hur ofta planändringar lyckas
  • Granska kundsupportärenden om problem med planändringar

Felhantering

Hantera vanliga API-fel på ett smidigt sätt i din implementation:

HTTP-statuskoder

Begäran om planändring behandlades utan problem. Svarskroppen är en ChangePlanResponse med payment_id, payment_link, client_secret och expires_on. Alla fyra kan vara null, så kroppen serialiseras som {} vid en vanlig off-session-ändring; de fylls i vid en lyckad begäran med collect_via_payment_link, som returnerar checkout-handtag – se Collecting Payment via a Checkout Link. Om on_payment_failure=prevent_change förblir planändringen väntande tills betalningen lyckas.
Ogiltiga parametrar i begäran. Kontrollera att alla obligatoriska fält har angetts och formaterats korrekt.
Ogiltig eller saknad API-nyckel. Kontrollera att din DODO_PAYMENTS_API_KEY är korrekt och har rätt behörigheter.
En väntande planändring finns redan för denna prenumeration (PendingPlanChangeExists). För en schemalagd ändring ska du avbryta den med DELETE /subscriptions/{subscription_id}/change-plan/scheduled innan du skickar en ny. För en väntande ändring via betalningslänk finns ingen endpoint för avbrytning – prenumerationen accepterar en ny begäran om planändring när kunden betalar eller länken löper ut.
Prenumerationen är inaktiv eller on-demand, eller så är begäran inte berättigad till collect_via_payment_link – företaget har inte funktionen aktiverad, effective_at är inte immediately eller on_payment_failure är inte prevent_change. Se Requirements. Ett prenumerations-ID som inte finns eller inte tillhör ditt konto returnerar 404 med koden NOT_FOUND.
Ett serverfel inträffade. Försök igen efter en kort fördröjning.

Format för felsvar

Fel returnerar en JSON-body med en code och ett människoläsbart message:
Se Error Codes för hela listan.

Nästa steg

Senast ändrad 26 september 2026