Hoppa till huvudinnehåll

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

Full API docs for updating subscriptions.

Plan Change Preview

See charge amounts before changing plans.

Integration Guide

Step-by-step subscription setup.

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

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
For detailed setup instructions, see our Integration Guide.

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:
Best for: SaaS applications wanting to charge fairly for unused time
  • 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
3

Implement the Change Plan API

Use the Change Plan API to modify subscription details:
subscription_id
string
obligatorisk
The ID of the active subscription to modify.
product_id
string
obligatorisk
The new product ID to change the subscription to.
quantity
integer
standard:"1"
Number of units for the new plan (for seat-based products).
proration_billing_mode
string
obligatorisk
How to handle immediate billing: prorated_immediately, full_immediately, difference_immediately, or do_not_bill.
addons
array
Optional addons for the new plan. Leaving this empty removes any existing addons.
on_payment_failure
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.
discount_codes
array
Valfria stackade rabattkoder att applicera på den nya planen (max 20, tillämpas i arrayordning). Beteendet beror på vad du skickar:
  • Inte angivet / null — befintliga rabatter med preserve_on_plan_change=true behålls om de är tillämpliga på den nya produkten.
  • [] (tom array) — tar bort alla befintliga rabatter från prenumerationen.
  • ["CODE_A", "CODE_B", ...] — ersätter befintliga rabatter med denna stackade uppsättning.
discount_code
string
föråldrad
Föråldrad — föredra discount_codes för nya integrationer. Detta fält fungerar fortfarande för bakåtkompatibilitet, men kan inte kombineras med discount_codes i samma begäran.
effective_at
string
standard:"immediately"
När planändringen ska tillämpas:
  • immediately (standard): Tillämpa planändringen omedelbart
  • next_billing_date: Schemalägg ändringen till nästa faktureringsdatum. Kunden behåller sin nuvarande plan tills faktureringsperioden är slut.
Använd next_billing_date för nedgraderingar så att kunderna behåller sina nuvarande planförmåner tills faktureringsperioden är slut.
4

Handle Webhook Events

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

Update Your Application State

Baserat på webbhook-händelser, uppdatera din applikation:
  • Bevilja/revokera funktioner baserat på den nya planen
  • Uppdatera kundens instrumentpanel med nya plandetaljer
  • Skicka bekräftelsemail om planändringar
  • Logga faktureringsändringar för revisionsändamål
6

Test and Monitor

Testa din implementation noggrant:
  • Testa alla proratlägen med olika scenarier
  • Kontrollera att webhook-hanteringen fungerar korrekt
  • Övervaka framgångsfrekvensen för planändringar
  • Ställ in varningar för misslyckade planändringar
Din implementation av prenumerationsplanändringar är nu redo för produktion.

Förhandsgranska planändringar

Innan du genomför en planändring, använd Preview API för att visa kunderna 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 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 proratbeteende 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',
    on_payment_failure: 'prevent_change', // Optional: control behavior on payment failure
  });
  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 avgift 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 avgiften misslyckas kan prenumerationen gå till subscription.on_hold tills betalningen lyckas.

Hantera tillägg

När du ändrar prenumerationsplaner kan du också ändra 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 proratberäkningen och kommer att debiteras enligt det valda proratläget.

Tillämpa rabattkoder

Du kan tillämpa en eller flera staplade rabattkoder när du ändrar prenumerationsplaner (max 20, tillämpas i arrayordning). Detta är användbart för att erbjuda kampanjprissättning vid uppgraderingar eller migrationer.
// Apply stacked discount codes during plan change
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_pro',
  quantity: 1,
  proration_billing_mode: 'prorated_immediately',
  discount_codes: ['UPGRADE20']
});

Rabattbeteende vid planändring

discount_codes värdeBeteende
Inte angivet / nullBefintliga rabatter med preserve_on_plan_change=true bevaras automatiskt om tillämpligt på den nya produkten.
[] (tom array)Alla befintliga rabatter tas bort från prenumerationen.
["CODE_A", "CODE_B", ...]Ersätter befintliga rabatter med denna staplade uppsättning, validerad och tillämpad i arrayordning.
Det enkla discount_code fältet på denna slutpunkt ä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 arrayformen när det är lämpligt.
Använd Preview Plan Change API med discount_codes för att visa kunderna exakt hur mycket de kommer att spara innan de bekräftar planändringen.

Proratlägen

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

prorated_immediately

  • Debiterar för den partiella skillnaden i den aktuella cykeln
  • Om i provperioden, 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 omedelbart det fulla beloppet för den nya planen
  • Ignorerar återstående tid från den gamla planen
Krediter som skapas av nedgraderingar med difference_immediately är prenumerationsbegränsade och skiljer sig från kreditbaserade fakturering rättigheter. 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ämpas automatiskt på förnyelser

do_not_bill

  • Inga avgifter eller krediter beräknas
  • Kunden byter till den nya planen omedelbart utan någon faktureringsjustering
  • Faktureringscykeln förblir oförändrad
  • Bäst för artighetsmigrationer, gratis planswitchar eller absorberande kostnadsskillnader
Funktionprorated_immediatelydifference_immediatelyfull_immediatelydo_not_bill
UppgraderingsavgiftProraterad skillnad för återstående dagarFull prisskillnad mellan planerFullt nytt planprisIngen avgift
NedgraderingskreditProraterad kredit för återstående dagarFull prisskillnad som kreditIngen kreditIngen kredit
FaktureringscykelOförändradOförändradÅterställs till idagOförändrad
ProvperiodsbeteendeAvslutar provperiod, debiterar omedelbartAvslutar provperiod, debiterar omedelbartAvslutar provperiod, debiterar fullt beloppAvslutar provperiod, ingen avgift
Bäst förRättvis tidsbaserad faktureringEnkelt uppgraderings-/nedgraderingsmatteÅterställning av faktureringscyklerGratis migrationer eller artighetsswitchar
KomplexitetMedium (dagberäkning)Låg (enkel subtraktion)Låg (full laddning)Ingen

Exempelscenarier

Använd dessa kanoniska nummer konsekvent:
  • Nuvarande plan: Basic$30/månad
  • Uppgraderingsmål: Pro$80/månad
  • Nedgraderingsmål (från Pro): Starter$20/månad
  • Faktureringscykel: 30 dagar, började den 1 januari
  • Planändring sker den 16 januari (15 dagar kvar, 15 dagar använda)
Step 1: Calculate unused credit from current plan
  Unused days = 15 out of 30 days
  Credit = $30 × (15/30) = $15.00

Step 2: Calculate prorated cost of new plan
  Remaining days = 15 out of 30 days
  New plan cost = $80 × (15/30) = $40.00

Step 3: Calculate immediate charge
  Charge = New plan cost − Credit
  Charge = $40.00 − $15.00 = $25.00

→ Customer pays $25.00 now
→ Next renewal (Feb 1): $80.00/month
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_pro',
  quantity: 1,
  proration_billing_mode: 'prorated_immediately'
})
Step 1: Calculate unused credit from current plan
  Unused days = 15 out of 30 days
  Credit = $80 × (15/30) = $40.00

Step 2: Calculate prorated cost of new plan
  Remaining days = 15 out of 30 days
  New plan cost = $20 × (15/30) = $10.00

Step 3: Calculate credit balance
  Credit = $40.00 − $10.00 = $30.00

→ No charge — $30.00 credit added to subscription
→ Credit auto-applies to future renewals
→ Next renewal (Feb 1): $20.00 − $30.00 credit = $0.00
→ Following renewal (Mar 1): $20.00 − $10.00 remaining credit = $10.00
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_starter',
  quantity: 1,
  proration_billing_mode: 'prorated_immediately'
})
Immediate charge = New plan price − Old plan price
                 = $80 − $30
                 = $50.00

→ Customer pays $50.00 now (regardless of cycle position)
→ Next renewal (Feb 1): $80.00/month
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_pro',
  quantity: 1,
  proration_billing_mode: 'difference_immediately'
})
Credit = Old plan price − New plan price
       = $80 − $20
       = $60.00

→ No charge — $60.00 credit added to subscription
→ Credit auto-applies to future renewals
→ Next renewal: $20.00 − $20.00 (from credit) = $0.00
→ Following renewal: $20.00 − $20.00 (from credit) = $0.00
→ Third renewal: $20.00 − $20.00 (from remaining credit) = $0.00
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_starter',
  quantity: 1,
  proration_billing_mode: 'difference_immediately'
})
Immediate charge = Full new plan price = $80.00

→ Customer pays $80.00 now
→ No credit for unused time on old plan
→ Billing cycle resets to today (January 16)
→ Next renewal: February 16 at $80.00/month
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_pro',
  quantity: 1,
  proration_billing_mode: 'full_immediately'
})
Current: Basic plan ($30/month), no add-ons
New: Pro plan ($80/month) + Extra Seats add-on ($10/seat × 3 seats = $30/month)
Change on day 16 of 30 (15 days remaining)

Step 1: Credit from current plan
  Credit = $30 × (15/30) = $15.00

Step 2: Prorated cost of new plan + add-ons
  New plan = $80 × (15/30) = $40.00
  Add-ons = $30 × (15/30) = $15.00
  Total new = $55.00

Step 3: Immediate charge
  Charge = $55.00 − $15.00 = $40.00

→ Customer pays $40.00 now
→ Next renewal: $80.00 + $30.00 = $110.00/month
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_pro',
  quantity: 1,
  proration_billing_mode: 'prorated_immediately',
  addons: [
    { addon_id: 'addon_seats', quantity: 3 }
  ]
})

Hur varje läge hanterar fakturering

Välj prorated_immediately för rättvis tidsbokföring; välj full_immediately för att starta om faktureringen; använd difference_immediately för enkla uppgraderingar och automatisk kredit vid nedgraderingar; eller använd do_not_bill för att byta planer utan någon faktureringsjustering.

Hantering av betalningsfel

Kontrollera vad som händer när en betalning vid planändring misslyckas med hjälp av parametern on_payment_failure.

Betalningsfellägen

Om inte specificerat använder parametern on_payment_failure din affärsnivåstandardkonfiguration i instrumentpanelen.

När man ska använda varje läge

ScenarioRekommenderat lägeAnledning
Uppgradering till premiumfunktionerprevent_changeSäkerställ betalning innan tillträde beviljas
Kvantitetsökning (fler platser)prevent_changeFörhindra användning utan betalning
Nedgradering av planerapply_changeKunden minskar utgifter
Tillförlitliga företagskunderapply_changeLägre risk för utebliven betalning
Konvertering från provperiod till betaldprevent_changeKritisk betalningsögonblick

Hantera webbhooks

Spåra prenumerationstillstånd genom webbhooks 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: avgift 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 prenumerationshändelser och att använda betalningshändelser 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 nyttolastscheman, se Prenumerations-webhook nyttolaster och Betalnings-webhook nyttolaster.

Bästa praxis

Följ dessa rekommendationer för pålitliga prenumerationsplanändringar:

Planändringsstrategi

  • Testa noggrant: Testa alltid planändringar i testläge innan produktionen
  • Välj prorat noggrant: Välj det proratläge som stämmer överens med din affärsmodell
  • Hantera fel elegant: Implementera korrekt felhantering och återförsökslogik
  • Övervaka framgångsrater: Spåra lyckandefel frekvenser för planändringar och undersök problem

Webhook-implementering

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

Användarupplevelse

  • Kommunicera tydligt: Informera kunder om faktureringsändringar och tidsramar
  • Ge bekräftelser: Skicka e-postbekräftelser för lyckade planändringar
  • Hantera undantagsfall: Överväg 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 under prenumerationsplanändringar:
Symtom: API-anropet lyckas men prenumerationen förblir på den gamla planenVanliga orsaker:
  • Webhook-behandling misslyckades eller försenades
  • Applikationstillståndet uppdaterades inte efter att webbhooks mottagits
  • Databastransaktionsproblem under tillståndsändringen
Lösningar:
  • Implementera robust webhook-hantering med återförsökslogik
  • Använd idempotenta operationer för tillståndsändringar
  • Lägg till övervakning för att upptäcka och varna om missade webhook-händelser
  • Kontrollera att webhook-slutpunkten är tillgänglig och svarar korrekt
Symtom: Kunden nedgraderar men ser inte kreditbalansenVanliga orsaker:
  • Förväntningar om proratläge: nedgraderingar krediterar hela plannivåskillnaden 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
  • Kreditbalans visas inte 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 fakturaförhandsgranskning för att se tillämpade krediter
Symtom: Webhook-händelser avvisades på grund av ogiltig signaturVanliga orsaker:
  • Felaktig webhook-hemlig nyckel
  • Obearbetad begäran kropp ändrad innan signaturverifiering
  • Fel verifieringsalgoritm för signatur
Lösningar:
  • Kontrollera att du använder korrekt DODO_WEBHOOK_SECRET från instrumentpanelen
  • Läs obearbetad begäran kropp innan någon JSON-parsing middleware
  • Använd standard webhook-verifieringsbiblioteket för din plattform
  • Testa webhook-signaturverifiering i utvecklingsmiljö
Symtom: API returnerar 422 Unprocessable Entity-felVanliga orsaker:
  • Ogiltigt prenumerations-ID eller produkt-ID
  • Prenumerationen är inte i aktivt tillstånd
  • Saknade nödvändiga parametrar
  • Produkten är inte tillgänglig för planändringar
Lösningar:
  • Kontrollera att prenumerationen existerar och är aktiv
  • Kontrollera att produkt-ID är giltigt och tillgängligt
  • Säkerställ att alla nödvändiga parametrar är med
  • Granska API-dokumentationen för parameterkrav
Symtom: Planändring initierad men omedelbar avgift misslyckasVanliga orsaker:
  • Otillräckliga medel på kundens betalningsmetod
  • Betalningsmetoden har gått ut eller är ogiltig
  • Banken avvisade transaktionen
  • Bedrägeridetektion blockerade avgiften
Lösningar:
  • Hantera payment.failed webhook-händelser på lämpligt sätt
  • Meddela kunden att uppdatera betalningsmetoden
  • Implementera återförsökslogik för tillfälliga fel
  • Överväg att tillåta planändringar med misslyckade omedelbara avgifter
Symtom: Planändringsavgiften misslyckas och prenumerationen flyttas till on_hold tillståndVad som händer: När en planändringsavgift 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 avgifts skapande: API:n skapar automatiskt en avgift för återstående skulder
  3. Fakturagenerering: En faktura genereras för avgiften
  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 i vänteläge (mottagen när planändringsavgift misslyckas)
  • payment.succeeded: Betalning för återstående skulder lyckades (efter uppdatering av betalningsmetoden)
  • subscription.active: Prenumeration återaktiverad efter lyckad betalning
Bästa praxis:
  • Informera kunder omedelbart när en planändringsavgift misslyckas
  • Ge tydliga instruktioner om hur de ska uppdatera sin betalningsmetod
  • Övervaka webhook-händelser för att spåra återaktiveringens status
  • Överväg att implementera automatisk återförsökslogik vid tillfälliga betalningsfel

Update Payment Method API Reference

Visa hela API-dokumentationen för att uppdatera betalningsmetoder och återaktivera prenumerationer.

Testa din implementation

Följ dessa steg för att noggrant testa din prenumerationsplanändringsimplementering:
1

Set up test environment

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

Test different proration modes

  • Testa prorated_immediately med olika faktureringscykelpositioner
  • Testa difference_immediately för uppgraderingar och nedgraderingar
  • Testa full_immediately för att återställa faktureringscykler
  • Testa do_not_bill för inga avgifter/inga krediter vid planswitchar
  • Kontrollera att kreditberäkningarna är korrekta
3

Test webhook handling

  • Kontrollera att alla relevanta webhook-händelser tas emot
  • Testa webhook-signaturverifiering
  • Hantera dubbletter av webhook-händelser elegant
  • Testa felscenarier vid webhook-behandling
4

Test error scenarios

  • Testa med ogiltiga prenumerations-ID
  • Testa med utgångna betalningsmetoder
  • Testa nätverksfel och timeout-fel
  • Testa med otillräckliga medel
5

Monitor in production

  • Ställ in varningar för misslyckade planändringar
  • Övervaka bearbetningstider för webhook
  • Spåra framgångsraten för planändringar
  • Granska kundsupportärenden för planändringsproblem

Felhantering

Hantera vanliga API-fel elegant i din implementation:

HTTP Statuskoder

Planändringsbegäran bearbetades framgångsrikt. Prenumerationen uppdateras och betalningsbearbetningen har påbörjats.
Ogiltiga begärdata. Kontrollera att alla obligatoriska fält är ifyllda och korrekt formaterade.
Ogiltig eller saknad API-nyckel. Kontrollera att din DODO_PAYMENTS_API_KEY är korrekt och har rätt behörigheter.
Prenumerations-ID hittades inte eller tillhör inte ditt konto.
Prenumerationen kan inte ändras (t.ex. redan avbruten, produkt ej tillgänglig, etc.).
Ett serverfel inträffade. Försök begäran igen efter en kort fördröjning.

Felresponsformat

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

Nästa steg

Last modified on May 22, 2026