Hoppa till huvudinnehåll

Vad är en uppgradering eller nedgradering av prenumeration?

Att ändra planer låter dig flytta en kund mellan prenumerationsnivåer eller kvantiteter. Använd det för att:
  • Justera prissättning med användning eller funktioner
  • Flytta från månadsvis till årlig (eller vice versa)
  • Justera kvantitet för produktbaserade platser
Planändringar kan utlösa en omedelbar debitering beroende på den proration som du väljer.

När ska man använda planändringar

  • Uppgradera när en kund behöver fler funktioner, användning eller platser
  • Nedgradera när användningen minskar
  • Migrera användare till en ny produkt eller pris utan att avbryta deras prenumeration

Förutsättningar

Innan du implementerar ändringar av prenumerationsplaner, se till att du har:
  • Ett Dodo Payments-handelskonto med aktiva prenumerationsprodukter
  • API-referenser (API-nyckel och webhook-hemlig nyckel) från instrumentpanelen
  • En befintlig aktiv prenumeration att modifiera
  • Webhook-slutpunkt konfigurerad för att hantera prenumerationsevenemang
För detaljerade installationsinstruktioner, se vår Integrationsguide.

Steg-för-steg-implementeringsguide

Följ denna omfattande guide för att implementera ändringar av prenumerationsplaner i din applikation:
1

Förstå kraven för planändring

Innan du implementerar, bestäm:
  • Vilka prenumerationsprodukter som kan ändras till vilka andra
  • Vilken proration som passar din affärsmodell
  • Hur man hanterar misslyckade planändringar på ett smidigt sätt
  • Vilka webhook-händelser som ska spåras för tillståndshantering
Testa planändringar noggrant i testläge innan du implementerar i produktion.
2

Välj din prorationstrategi

Välj den faktureringsmetod som stämmer överens med dina affärsbehov:
Bäst för: SaaS-applikationer som vill ta betalt rättvist för oanvänd tid
  • Beräknar exakt proraterat belopp baserat på återstående cykeltid
  • Debiterar ett proraterat belopp baserat på oanvänd tid som återstår i cykeln
  • Ger transparent fakturering till kunder
3

Implementera Change Plan API

Använd Change Plan API för att modifiera prenumerationsdetaljer:
subscription_id
string
obligatorisk
ID för den aktiva prenumerationen som ska modifieras.
product_id
string
obligatorisk
Det nya produkt-ID:t som prenumerationen ska ändras till.
quantity
integer
standard:"1"
Antal enheter för den nya planen (för produktbaserade platser).
proration_billing_mode
string
obligatorisk
Hur man hanterar omedelbar fakturering: prorated_immediately, full_immediately, eller difference_immediately.
addons
array
Valfria tillägg för den nya planen. Om detta lämnas tomt tas eventuella befintliga tillägg bort.
4

Hantera webhook-händelser

Ställ in webhook-hantering för att spåra resultat av planändringar:
  • subscription.active: Planändring lyckades, prenumeration uppdaterad
  • subscription.plan_changed: Prenumerationsplan ändrad (uppgradering/nedgradering/tilläggsuppdatering)
  • subscription.on_hold: Planändringsdebitering misslyckades, prenumeration pausad
  • payment.succeeded: Omedelbar debitering för planändring lyckades
  • payment.failed: Omedelbar debitering misslyckades
Verifiera alltid webhook-signaturer och implementera idempotent händelsebearbetning.
5

Uppdatera din applikationstillstånd

Baserat på webhook-händelser, uppdatera din applikation:
  • Ge/tillbaka funktioner baserat på ny plan
  • Uppdatera kundens instrumentpanel med nya plandetaljer
  • Skicka bekräftelsemejl om planändringar
  • Logga faktureringsändringar för revisionsändamål
6

Testa och övervaka

Testa noggrant din implementation:
  • Testa alla prorationlägen med olika scenarier
  • Verifiera att webhook-hanteringen fungerar korrekt
  • Övervaka framgångsrater för planändringar
  • Ställ in aviseringar för misslyckade planändringar
Din implementation av ändringar av prenumerationsplaner är nu redo för produktionsanvändning.

Förhandsgranska planändringar

Innan du bekräftar en planändring, använd Förhandsgranska API för att visa kunder exakt vad de kommer att debiteras:
const preview = await client.subscriptions.previewChangePlan('sub_123', {
  product_id: 'prod_pro',
  quantity: 1,
  proration_billing_mode: 'prorated_immediately'
});

// Show customer the charge before confirming
console.log('Immediate charge:', preview.immediate_charge.summary);
console.log('New plan details:', preview.new_plan);
Använd förhandsgransknings-API:t för att bygga bekräftelsedialoger som visar kunder 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 modifiera produkt, kvantitet och prorationbeteende för en aktiv prenumeration.

Snabbstartsexempel

import DodoPayments from 'dodopayments';

const client = new DodoPayments({
  bearerToken: process.env.DODO_PAYMENTS_API_KEY,
  environment: 'test_mode', // defaults to 'live_mode'
});

async function changePlan() {
  const result = await client.subscriptions.changePlan('sub_123', {
    product_id: 'prod_new',
    quantity: 3,
    proration_billing_mode: 'prorated_immediately',
  });
  console.log(result.status, result.invoice_id, result.payment_id);
}

changePlan();
Success
{
  "status": "processing",
  "subscription_id": "sub_123",
  "invoice_id": "inv_789",
  "payment_id": "pay_456",
  "proration_billing_mode": "prorated_immediately"
}
Fält som invoice_id och payment_id returneras endast när en omedelbar debitering och/eller faktura skapas under planändringen. Lita alltid på webhook-händelser (t.ex. payment.succeeded, subscription.plan_changed) för att bekräfta resultat.
Om den omedelbara debiteringen misslyckas kan prenumerationen flyttas till subscription.on_hold tills betalningen lyckas.

Hantera tillägg

När du ändrar prenumerationsplaner kan du också modifiera tillägg:
// Add addons to the new plan
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_new',
  quantity: 1,
  proration_billing_mode: 'difference_immediately',
  addons: [
    { addon_id: 'addon_123', quantity: 2 }
  ]
});

// Remove all existing addons
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_new',
  quantity: 1,
  proration_billing_mode: 'difference_immediately',
  addons: [] // Empty array removes all existing addons
});
Tillägg ingår i prorationberäkningen och kommer att debiteras enligt den valda prorationen.

Prorationslägen

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

prorated_immediately

  • Debiterar för den delvisa skillnaden i den aktuella cykeln
  • Om i provperiod, debiterar omedelbart och byter till den nya planen nu
  • Nedgradering: kan generera en proraterad kredit som tillämpas på framtida förnyelser

full_immediately

  • Debiterar hela beloppet för den nya planen omedelbart
  • Ignorerar återstående tid från den gamla planen
Krediter som skapas av nedgraderingar med difference_immediately är prenumerationsspecifika och åtskilda från Kundkrediter. De tillämpas automatiskt på framtida förnyelser av samma prenumeration och är inte överförbara mellan prenumerationer.

difference_immediately

  • Uppgradering: debiterar omedelbart prisskillnaden mellan gamla och nya planer
  • Nedgradering: lägger till återstående värde som intern kredit till prenumerationen och tillämpar automatiskt vid förnyelser

Exempel på scenarier

await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_pro',
  quantity: 1,
  proration_billing_mode: 'difference_immediately'
})
// Immediate charge: $50
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_starter',
  quantity: 1,
  proration_billing_mode: 'difference_immediately'
})
// Credit added: $30 (auto-applied to future renewals for this subscription)
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_new',
  quantity: 1,
  proration_billing_mode: 'prorated_immediately'
})
// Immediate prorated charge based on remaining days in cycle
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_new',
  quantity: 1,
  proration_billing_mode: 'full_immediately'
})
// Immediate full charge for new plan; no credits calculated
Välj prorated_immediately för rättvis tidsredovisning; välj full_immediately för att återstarta faktureringen; använd difference_immediately för enkla uppgraderingar och automatisk kredit vid nedgraderingar.

Hantera webhooks

Spåra prenumerationstillstånd genom webhooks för att bekräfta planändringar och betalningar.

Händelsetyper att hantera

  • subscription.active: prenumeration aktiverad
  • subscription.plan_changed: prenumerationsplan ändrad (uppgradering/nedgradering/tilläggsändringar)
  • subscription.on_hold: debitering misslyckades, prenumeration pausad
  • subscription.renewed: förnyelse lyckades
  • payment.succeeded: betalning för planändring eller förnyelse lyckades
  • payment.failed: betalning misslyckades
Vi rekommenderar att driva affärslogik från prenumerationsevenemang och använda betalningsevenemang för bekräftelse och avstämning.

Verifiera signaturer och hantera avsikter

import { NextRequest, NextResponse } from 'next/server';

export async function POST(req) {
  const webhookId = req.headers.get('webhook-id');
  const webhookSignature = req.headers.get('webhook-signature');
  const webhookTimestamp = req.headers.get('webhook-timestamp');
  const secret = process.env.DODO_WEBHOOK_SECRET;

  const payload = await req.text();
  // verifySignature is a placeholder – in production, use a Standard Webhooks library
  const { valid, event } = await verifySignature(
    payload,
    { id: webhookId, signature: webhookSignature, timestamp: webhookTimestamp },
    secret
  );
  if (!valid) return NextResponse.json({ error: 'Invalid signature' }, { status: 400 });

  switch (event.type) {
    case 'subscription.active':
      // mark subscription active in your DB
      break;
    case 'subscription.plan_changed':
      // refresh entitlements and reflect the new plan in your UI
      break;
    case 'subscription.on_hold':
      // notify user to update payment method
      break;
    case 'subscription.renewed':
      // extend access window
      break;
    case 'payment.succeeded':
      // reconcile payment for plan change
      break;
    case 'payment.failed':
      // log and alert
      break;
    default:
      // ignore unknown events
      break;
  }

  return NextResponse.json({ received: true });
}
För detaljerade payload-scheman, se Prenumerations-webhook-payloads och Betalnings-webhook-payloads.

Bästa praxis

Följ dessa rekommendationer för tillförlitliga ändringar av prenumerationsplaner:

Strategi för planändring

  • Testa noggrant: Testa alltid planändringar i testläge innan produktion
  • Välj proration noggrant: Välj prorationläget som stämmer överens med din affärsmodell
  • Hantera misslyckanden smidigt: Implementera korrekt felhantering och återföringslogik
  • Övervaka framgångsrater: Spåra framgångs-/misslyckandefrekvenser för planändringar och undersök problem

Implementering av webhook

  • Verifiera signaturer: Verifiera alltid webhook-signaturer för att säkerställa äkthet
  • Implementera idempotens: Hantera dubblettwebhook-händelser smidigt
  • Bearbeta asynkront: Blockera inte webhook-svar med tunga operationer
  • Logga allt: Upprätthåll detaljerade loggar för felsökning och revisionsändamål

Användarupplevelse

  • Kommunicera tydligt: Informera kunder om faktureringsändringar och tidpunkter
  • Ge bekräftelser: Skicka e-postbekräftelser för lyckade planändringar
  • Hantera kantfall: Tänk på provperioder, prorationer och misslyckade betalningar
  • Uppdatera UI omedelbart: Återspegla planändringar i din applikationsgränssnitt

Vanliga problem och lösningar

Lös typiska problem som uppstår vid ändringar av prenumerationsplaner:
Symptom: API-anrop lyckas men prenumerationen förblir på den gamla planenVanliga orsaker:
  • Webhook-bearbetning misslyckades eller fördröjdes
  • Applikationstillståndet uppdaterades inte efter att ha mottagit webhooks
  • Databastransaktionsproblem under tillståndsuppdatering
Lösningar:
  • Implementera robust webhook-hantering med återföringslogik
  • Använd idempotenta operationer för tillståndsuppdateringar
  • Lägg till övervakning för att upptäcka och varna om missade webhook-händelser
  • Verifiera att webhook-slutpunkten är tillgänglig och svarar korrekt
Symptom: Kunden nedgraderar men ser inte kreditbalansenVanliga orsaker:
  • Förväntningar på prorationläge: nedgraderingar krediterar hela planprisskillnaden med difference_immediately, medan prorated_immediately skapar en proraterad kredit baserat på återstående tid i cykeln
  • Krediter är prenumerationsspecifika och överförs inte mellan prenumerationer
  • Kreditbalansen är inte synlig i kundens instrumentpanel
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 kundportal för att visa kreditbalanser
  • Kontrollera nästa fakturaprevia för att se tillämpade krediter
Symptom: Webhook-händelser avvisas på grund av ogiltig signaturVanliga orsaker:
  • Felaktig webhook-hemlig nyckel
  • Rå begärningskropp modifierad före signaturverifiering
  • Fel signaturverifieringsalgoritm
Lösningar:
  • Verifiera att du använder den korrekta DODO_WEBHOOK_SECRET från instrumentpanelen
  • Läs den råa begärningskroppen innan någon JSON-parsing-mellanprogram
  • Använd det standardiserade webhook-verifieringsbiblioteket för din plattform
  • Testa webhook-signaturverifiering i utvecklingsmiljö
Symptom: API returnerar 422 Unprocessable Entity-felVanliga orsaker:
  • Ogiltigt prenumerations-ID eller produkt-ID
  • Prenumerationen är inte i aktivt tillstånd
  • Saknas obligatoriska parametrar
  • Produkten är inte tillgänglig för planändringar
Lösningar:
  • Verifiera att prenumerationen finns och är aktiv
  • Kontrollera att produkt-ID:t är giltigt och tillgängligt
  • Se till att alla obligatoriska parametrar tillhandahålls
  • Granska API-dokumentationen för parameterkrav
Symptom: Planändring initierad men omedelbar debitering misslyckasVanliga orsaker:
  • Otillräckliga medel på kundens betalningsmetod
  • Betalningsmetoden har gått ut eller är ogiltig
  • Banken avslog transaktionen
  • Bedrägeridetektering blockerade debiteringen
Lösningar:
  • Hantera payment.failed webhook-händelser på lämpligt sätt
  • Meddela kunden att uppdatera betalningsmetoden
  • Implementera återföringslogik för tillfälliga misslyckanden
  • Överväg att tillåta planändringar med misslyckade omedelbara debiteringar
Symptom: Planändringsdebitering misslyckas och prenumerationen flyttas till on_hold tillståndVad händer: När en planändringsdebitering misslyckas placeras prenumerationen automatiskt i on_hold tillstånd. Prenumerationen kommer inte att förnyas automatiskt förrän betalningsmetoden uppdateras.Lösning: Uppdatera betalningsmetoden för att återaktivera prenumerationenFör att återaktivera en prenumeration från on_hold tillstånd efter en misslyckad planändring:
  1. Uppdatera betalningsmetoden med hjälp av Update Payment Method API
  2. Automatisk debiteringsskapelse: API:t skapar automatiskt en debitering för utestående belopp
  3. Fakturagenerering: En faktura genereras för debiteringen
  4. Betalningsbearbetning: Betalningen behandlas med den nya betalningsmetoden
  5. Återaktivering: Vid lyckad betalning återaktiveras prenumerationen till active tillstånd
// Reactivate subscription from on_hold after failed plan change
async function reactivateAfterFailedPlanChange(subscriptionId) {
  // Update payment method - automatically creates charge for remaining dues
  const response = await client.subscriptions.updatePaymentMethod(subscriptionId, {
    type: 'new',
    return_url: 'https://example.com/return'
  });
  
  if (response.payment_id) {
    console.log('Charge created for remaining dues:', response.payment_id);
    console.log('Payment link:', response.payment_link);
    
    // Redirect customer to payment_link to complete payment
    // Monitor webhooks for:
    // 1. payment.succeeded - charge succeeded
    // 2. subscription.active - subscription reactivated
  }
  
  return response;
}

// Or use existing payment method if available
async function reactivateWithExistingPaymentMethod(subscriptionId, paymentMethodId) {
  const response = await client.subscriptions.updatePaymentMethod(subscriptionId, {
    type: 'existing',
    payment_method_id: paymentMethodId
  });
  
  // Monitor webhooks for payment.succeeded and subscription.active
  return response;
}
Webhook-händelser att övervaka:
  • subscription.on_hold: Prenumeration placerad på paus (mottagen när planändringsdebiteringen misslyckas)
  • payment.succeeded: Betalning för utestående belopp lyckades (efter att betalningsmetoden uppdaterats)
  • subscription.active: Prenumeration återaktiverad efter lyckad betalning
Bästa praxis:
  • Meddela kunder omedelbart när en planändringsdebitering misslyckas
  • Ge tydliga instruktioner om hur de ska uppdatera sin betalningsmetod
  • Övervaka webhook-händelser för att spåra återaktiveringsstatus
  • Överväg att implementera automatisk återföringslogik för tillfälliga betalningsmisslyckanden

API-referens för uppdatering av betalningsmetod

Se den kompletta API-dokumentationen för att uppdatera betalningsmetoder och återaktivera prenumerationer.

Testa din implementation

Följ dessa steg för att noggrant testa din implementation av ändringar av prenumerationsplaner:
1

Ställ in testmiljö

  • Använd test-API-nycklar och testprodukter
  • Skapa testprenumerationer med olika planformer
  • Konfigurera test-webhook-slutpunkt
  • Ställ in övervakning och loggning
2

Testa olika prorationlägen

  • Testa prorated_immediately med olika faktureringscykelpositioner
  • Testa difference_immediately för uppgraderingar och nedgraderingar
  • Testa full_immediately för att återställa faktureringscykler
  • Verifiera att kreditberäkningarna är korrekta
3

Testa webhook-hantering

  • Verifiera att alla relevanta webhook-händelser mottas
  • Testa webhook-signaturverifiering
  • Hantera dubblettwebhook-händelser smidigt
  • Testa scenarier för misslyckande av webhook-bearbetning
4

Testa fel-scenarier

  • Testa med ogiltiga prenumerations-ID:n
  • Testa med utgångna betalningsmetoder
  • Testa nätverksfel och tidsgränser
  • Testa med otillräckliga medel
5

Övervaka i produktion

  • Ställ in aviseringar för misslyckade planändringar
  • Övervaka webhook-bearbetningstider
  • Spåra framgångsrater för planändringar
  • Granska kundsupportärenden för problem med planändringar

Felhantering

Hantera vanliga API-fel smidigt i din implementation:

HTTP-statuskoder

Planändringsförfrågan har bearbetats framgångsrikt. Prenumerationen uppdateras och betalningsbearbetning har påbörjats.
Ogiltiga begärningsparametrar. Kontrollera att alla obligatoriska fält tillhandahålls och är korrekt formaterade.
Ogiltig eller saknad API-nyckel. Verifiera att din DODO_PAYMENTS_API_KEY är korrekt och har rätt behörigheter.
Prenumerations-ID:t hittades inte eller tillhör inte ditt konto.
Prenumerationen kan inte ändras (t.ex. redan avbruten, produkt inte tillgänglig, etc.).
Ett serverfel inträffade. Försök att göra begäran igen efter en kort paus.

Felresponsformat

{
  "error": {
    "code": "subscription_not_found",
    "message": "The subscription with ID 'sub_123' was not found",
    "details": {
      "subscription_id": "sub_123"
    }
  }
}

Nästa steg