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
Plan Change Preview
Integration Guide
What is a subscription upgrade or downgrade?
Changing plans lets you move a customer between subscription tiers or quantities. Use it to:- Align pricing with usage or features
- Move from monthly to annual (or vice versa)
- Adjust quantity for seat-based products
When to use plan changes
- Upgrade when a customer needs more features, usage, or seats
- Downgrade when usage decreases
- Migrate users to a new product or price without cancelling their subscription
Plan Change Flow
Prerequisites
Before implementing subscription plan changes, ensure you have:- A Dodo Payments merchant account with active subscription products
- API credentials (API key and webhook secret key) from the dashboard
- An existing active subscription to modify
- Webhook endpoint configured to handle subscription events
Step-by-Step Implementation Guide
Follow this comprehensive guide to implement subscription plan changes in your application:Understand Plan Change Requirements
- Which subscription products can be changed to which others
- What proration mode fits your business model
- How to handle failed plan changes gracefully
- Which webhook events to track for state management
Choose Your Proration Strategy
- prorated_immediately
- difference_immediately
- full_immediately
- do_not_bill
- Calculates exact prorated amount based on remaining cycle time
- Charges a prorated amount based on unused time remaining in the cycle
- Provides transparent billing to customers
Implement the Change Plan API
prorated_immediately, full_immediately, difference_immediately, or do_not_bill.prevent_change: Keep subscription on current plan until payment succeedsapply_change(default): Apply plan change immediately regardless of payment outcome
- Tidak disediakan /
null— diskon yang ada denganpreserve_on_plan_change=truedipertahankan jika berlaku untuk produk baru. [](array kosong) — menghapus semua diskon yang ada dari langganan.["CODE_A", "CODE_B", ...]— menggantikan diskon yang ada dengan set baru ini.
discount_codes untuk integrasi baru. Bidang ini masih berfungsi untuk kompatibilitas ke belakang, tetapi tidak dapat digabungkan dengan discount_codes dalam permintaan yang sama.immediately(default): Terapkan segera perubahan paketnext_billing_date: Jadwalkan perubahan untuk tanggal penagihan berikutnya. Pelanggan mempertahankan paket mereka saat ini hingga periode penagihan berakhir.
next_billing_date untuk penurunan versi sehingga pelanggan tetap mendapatkan manfaat paket mereka saat ini hingga akhir periode penagihan.Handle Webhook Events
subscription.active: Perubahan paket berhasil, langganan diperbaruisubscription.plan_changed: Paket langganan berubah (peningkatan/penurunan versi/pembaruan addon)subscription.on_hold: Biaya perubahan paket gagal, langganan dijedapayment.succeeded: Biaya langsung untuk perubahan paket berhasilpayment.failed: Biaya langsung gagal
Update Your Application State
- Berikan/cabut fitur berdasarkan paket baru
- Perbarui dasbor pelanggan dengan detail paket baru
- Kirim email konfirmasi tentang perubahan paket
- Catat perubahan penagihan untuk tujuan audit
Test and Monitor
- Uji semua mode proratasi dengan berbeda skenario
- Verifikasi penanganan webhook berfungsi dengan benar
- Monitor tingkat keberhasilan perubahan paket
- Siapkan peringatan untuk perubahan paket yang gagal
Pratinjau Perubahan Paket
Sebelum melakukan perubahan paket, gunakan Preview API untuk menunjukkan kepada pelanggan berapa tepatnya yang akan mereka bayar:- Node.js SDK
- Python SDK
API Perubahan Paket
Gunakan API Perubahan Paket untuk memodifikasi produk, kuantitas, dan perilaku proratasi untuk langganan aktif.Contoh cepat memulai
- Node.js SDK
- Python SDK
- Go SDK
- HTTP
invoice_id dan payment_id hanya dikembalikan ketika biaya langsung dan/atau faktur dibuat selama perubahan paket. Selalu andalkan acara webhook (misalnya, payment.succeeded, subscription.plan_changed) untuk mengonfirmasi hasil.Mengelola Addon
Saat mengubah paket langganan, Anda juga dapat memodifikasi addon:Menerapkan Kode Diskon
Anda dapat menerapkan satu atau lebih kode diskon tambahan saat mengubah paket langganan (maks 20, diterapkan dalam urutan array). Ini berguna untuk menawarkan harga promosi pada peningkatan atau migrasi.- Node.js SDK
- Python SDK
- HTTP
Perilaku diskon pada perubahan paket
Nilai discount_codes | Perilaku |
|---|---|
Tidak disediakan / null | Diskon yang ada dengan preserve_on_plan_change=true secara otomatis dipertahankan jika berlaku untuk produk baru. |
[] (array kosong) | Semua diskon yang ada dihapus dari langganan. |
["CODE_A", "CODE_B", ...] | Menggantikan diskon yang ada dengan set tambahan ini, divalidasi dan diterapkan dalam urutan array. |
discount_code di endpoint ini dihapus tetapi masih berfungsi untuk kompatibilitas ke belakang — integrasi yang ada tidak perlu mengubah segera. Tidak dapat digabungkan dengan discount_codes dalam permintaan yang sama. Migrasikan ke bentuk array saat nyaman.Mode Prorasi
Pilih cara untuk menagih pelanggan saat mengubah paket:prorated_immediately
- Menagih perbedaan parsial dalam siklus saat ini
- Jika dalam percobaan, langsung menagih dan beralih ke paket baru sekarang
- Penurunan versi: dapat menghasilkan kredit prorated yang diterapkan ke pembaruan mendatang
full_immediately
- Menagih jumlah penuh dari paket baru secara langsung
- Mengabaikan waktu yang tersisa dari paket lama
difference_immediately diterapkan pada ruang lingkup langganan dan berbeda dari hak Penagihan Berbasis Kredit. Mereka secara otomatis diaplikasikan pada pembaruan di masa mendatang dari langganan yang sama dan tidak dapat dipindahtangankan antara langganan.difference_immediately
- Peningkatan: langsung menagih perbedaan harga antara paket lama dan baru
- Penurunan versi: tambahkan nilai yang tersisa sebagai kredit internal pada langganan dan terapkan secara otomatis saat pembaruan
do_not_bill
- Tidak ada biaya atau kredit yang dihitung
- Pelanggan beralih ke paket baru segera tanpa penyesuaian penagihan
- Siklus penagihan tetap tidak berubah
- Terbaik untuk migrasi sopan santun, perpindahan paket gratis, atau menyerap perbedaan biaya
| Fitur | prorated_immediately | difference_immediately | full_immediately | do_not_bill |
|---|---|---|---|---|
| Biaya Peningkatan | Perbedaan yang sesuai untuk hari yang tersisa | Harga penuh beda antara paket | Harga penuh paket baru | Tidak ada biaya |
| Kredit Penurunan versi | Kredit prorated untuk hari yang tersisa | Perbedaan harga penuh sebagai kredit | Tidak ada kredit | Tidak ada kredit |
| Siklus Penagihan | Tidak berubah | Tidak berubah | Diatur ulang ke hari ini | Tidak berubah |
| Perilaku Percobaan | Mengakhiri percobaan, menagih segera | Mengakhiri percobaan, menagih segera | Mengakhiri percobaan, menagih jumlah penuh | Mengakhiri percobaan, tidak ada biaya |
| Terbaik untuk | Penagihan berbasis waktu yang adil | Matematika peningkatan/penurunan versi sederhana | Mengatur ulang siklus penagihan | Migrasi gratis atau perubahan sopan santun |
| Kompleksitas | Sedang (perhitungan hari) | Rendah (pengurangan sederhana) | Rendah (biaya penuh) | Tidak ada |
Contoh skenario
Gunakan angka kanonik ini secara konsisten:- Paket saat ini: Basic di $30/bulan
- Target peningkatan: Pro di $80/bulan
- Target penurunan (dari Pro): Starter di $20/bulan
- Siklus penagihan: 30 hari, dimulai pada 1 Januari
- Perubahan paket terjadi pada 16 Januari (15 hari tersisa, 15 hari digunakan)
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
Bagaimana setiap mode memproses penagihan
Penanganan Kegagalan Pembayaran
Kontrol apa yang terjadi ketika pembayaran perubahan paket gagal menggunakan parameteron_payment_failure.
Mode Kegagalan Pembayaran
- prevent_change (Recommended for critical upgrades)
- apply_change (Default)
- Perubahan paket ditandai sebagai “pending”
- Pelanggan mempertahankan akses ke paket mereka saat ini
- Langganan berpindah ke status
activehanya setelah pembayaran berhasil - Berguna ketika Anda ingin memastikan pembayaran sebelum memberikan fitur peningkatan
on_payment_failure menggunakan pengaturan default tingkat bisnis Anda yang dikonfigurasi di dasbor.Kapan Menggunakan Setiap Mode
| Skenario | Mode yang Direkomendasikan | Alasan |
|---|---|---|
| Meningkatkan ke fitur premium | prevent_change | Pastikan pembayaran sebelum memberikan akses |
| Peningkatan jumlah (lebih banyak kursi) | prevent_change | Mencegah penggunaan tanpa pembayaran |
| Menurunkan paket | apply_change | Pelanggan mengurangi pengeluaran |
| Pelanggan perusahaan terpercaya | apply_change | Risiko lebih rendah dari ketidakpembayaran |
| Konversi percobaan ke berbayar | prevent_change | Momen pembayaran kritis |
Penanganan webhooks
Melacak status langganan melalui webhook untuk mengonfirmasi perubahan paket dan pembayaran.Jenis acara yang ditangani
subscription.active: langganan diaktifkansubscription.plan_changed: paket langganan berubah (peningkatan/penurunan versi/perubahan addon)subscription.on_hold: biaya gagal, langganan dijedasubscription.renewed: pembaruan berhasilpayment.succeeded: pembayaran untuk perubahan paket atau pembaruan berhasilpayment.failed: pembayaran gagal
Memverifikasi tanda tangan dan menangani niat
- Next.js Route Handler
- Express.js
Praktik Terbaik
Ikuti rekomendasi ini untuk perubahan paket langganan yang andal:Strategi Perubahan Paket
- Uji secara menyeluruh: Selalu uji perubahan paket dalam modus percobaan sebelum produksi
- Pilih proratasi dengan hati-hati: Pilih mode proratasi yang sesuai dengan model bisnis Anda
- Tangani kegagalan dengan anggun: Terapkan penanganan kesalahan yang tepat dan logika pengulangan
- Monitor tingkat keberhasilan: Lacak tingkat keberhasilan/kegagalan perubahan paket dan teliti masalah
Implementasi Webhook
- Verifikasi tanda tangan: Selalu validasi tanda tangan webhook untuk memastikan keaslian
- Terapkan idempoten: Tangani acara webhook duplikat dengan anggun
- Proses secara asynchronous: Jangan memblokir tanggapan webhook dengan operasi berat
- Catat semuanya: Pertahankan catatan rinci untuk debugging dan tujuan audit
Pengalaman Pengguna
- Komunikasikan dengan jelas: Informasikan pelanggan tentang perubahan penagihan dan waktu
- Berikan konfirmasi: Kirim email konfirmasi untuk perubahan paket yang berhasil
- Tangani kasus tepi: Pertimbangkan periode percobaan, prorasi, dan pembayaran yang gagal
- Perbarui antarmuka pengguna segera: Cerminkan perubahan paket dalam antarmuka aplikasi Anda
Masalah Umum dan Solusi
Selesaikan masalah umum yang ditemui selama perubahan paket langganan:Charge created but subscription not updated
Charge created but subscription not updated
- Pemrosesan webhook gagal atau tertunda
- Status aplikasi tidak diperbarui setelah menerima webhook
- Masalah transaksi database selama pembaruan status
- Terapkan penanganan webhook yang kuat dengan logika pengulangan
- Gunakan operasi idempoten untuk pembaruan status
- Tambahkan pemantauan untuk mendeteksi dan memberi peringatan tentang acara webhook yang terlewat
- Verifikasi endpoint webhook dapat diakses dan merespons dengan benar
Credits not applied after downgrade
Credits not applied after downgrade
- Ekspektasi mode proratasi: penurunan kredit harga penuh paket dengan
difference_immediately, sementaraprorated_immediatelymenciptakan kredit prorated berdasarkan waktu yang tersisa dalam siklus - Kredit bersifat spesifik untuk langganan dan tidak berlaku untuk langganan lain
- Saldo kredit tidak terlihat di dasbor pelanggan
- Gunakan
difference_immediatelyuntuk penurunan jika Anda menginginkan kredit otomatis - Jelaskan kepada pelanggan bahwa kredit berlaku untuk pembaruan masa depan dari langganan yang sama
- Terapkan portal pelanggan untuk menampilkan saldo kredit
- Periksa pratinjau faktur berikutnya untuk melihat kredit yang diterapkan
Webhook signature verification fails
Webhook signature verification fails
- Kunci rahasia webhook yang salah
- Tubuh permintaan mentah dimodifikasi sebelum verifikasi tanda tangan
- Algoritma verifikasi tanda tangan yang salah
- Verifikasi bahwa Anda menggunakan
DODO_WEBHOOK_SECRETyang benar dari dasbor - Baca tubuh permintaan mentah sebelum middleware parsing JSON
- Gunakan perpustakaan verifikasi webhook standar untuk platform Anda
- Uji verifikasi tanda tangan webhook di lingkungan pengembangan
Plan change fails with 422 error
Plan change fails with 422 error
- ID langganan tidak valid atau ID produk
- Langganan tidak dalam status aktif
- Parameter yang dibutuhkan hilang
- Produk tidak tersedia untuk perubahan paket
- Verifikasi bahwa langganan ada dan aktif
- Periksa ID produk valid dan tersedia
- Pastikan semua parameter yang dibutuhkan diberikan
- Tinjau dokumentasi API untuk persyaratan parameter
Immediate charge fails during plan change
Immediate charge fails during plan change
- Dana tidak mencukupi pada metode pembayaran pelanggan
- Metode pembayaran kadaluarsa atau tidak valid
- Bank menolak transaksi
- Deteksi penipuan memblokir biaya
- Tangani acara webhook
payment.faileddengan tepat - Notifikasi pelanggan untuk memperbarui metode pembayaran
- Terapkan logika pengulangan untuk kegagalan sementara
- Pertimbangkan untuk mengizinkan perubahan paket dengan biaya langsung yang gagal
Subscription on hold after plan change
Subscription on hold after plan change
on_holdApa yang terjadi:
Ketika biaya perubahan paket gagal, langganan secara otomatis ditempatkan dalam status on_hold. Langganan tidak akan diperpanjang secara otomatis hingga metode pembayaran diperbarui.Solusi: Perbarui metode pembayaran untuk mengaktifkan kembali langgananUntuk mengaktifkan kembali langganan dari status on_hold setelah perubahan paket gagal:- Perbarui metode pembayaran menggunakan Update Payment Method API
- Pembuatan biaya otomatis: API secara otomatis membuat biaya untuk jumlah yang belum dibayar
- Pembuatan faktur: Faktur dibuat untuk biaya
- Pemrosesan pembayaran: Pembayaran diproses menggunakan metode pembayaran baru
- Reaktivasi: Setelah pembayaran berhasil, langganan diaktifkan kembali ke status
active
subscription.on_hold: Langganan di tempat tahan (diterima ketika biaya perubahan paket gagal)payment.succeeded: Pembayaran untuk jumlah yang tertunda berhasil (setelah memperbarui metode pembayaran)subscription.active: Langganan diaktifkan kembali setelah pembayaran berhasil
- Notifikasi pelanggan segera ketika biaya perubahan paket gagal
- Berikan instruksi yang jelas tentang cara memperbarui metode pembayaran mereka
- Pantau acara webhook untuk melacak status reaktivasi
- Pertimbangkan untuk menerapkan logika pengulangan otomatis untuk kegagalan pembayaran sementara
Update Payment Method API Reference
Menguji Implementasi Anda
Ikuti langkah-langkah ini untuk menguji implementasi perubahan paket langganan Anda secara menyeluruh:Set up test environment
- Gunakan kunci API uji dan produk uji
- Buat langganan uji dengan berbagai jenis paket
- Konfigurasi endpoint webhook uji
- Siapkan pemantauan dan pencatatan
Test different proration modes
- Uji
prorated_immediatelydengan berbagai posisi siklus penagihan - Uji
difference_immediatelyuntuk peningkatan dan penurunan versi - Uji
full_immediatelyuntuk mengatur ulang siklus penagihan - Uji
do_not_billuntuk perubahan paket tanpa biaya/kredit - Verifikasi perhitungan kredit benar
Test webhook handling
- Verifikasi semua acara webhook yang relevan diterima
- Uji verifikasi tanda tangan webhook
- Tangani acara webhook duplikat dengan anggun
- Uji skenario kegagalan pemrosesan webhook
Test error scenarios
- Uji dengan ID langganan yang tidak valid
- Uji dengan metode pembayaran yang kedaluwarsa
- Uji kegagalan jaringan dan waktu tunggu
- Uji dengan dana tidak mencukupi
Penanganan Kesalahan
Tangani kesalahan API umum dengan baik dalam implementasi Anda:Kode Status HTTP
200 OK
200 OK
400 Bad Request
400 Bad Request
401 Unauthorized
401 Unauthorized
404 Not Found
404 Not Found
422 Unprocessable Entity
422 Unprocessable Entity
500 Internal Server Error
500 Internal Server Error
Format Tanggapan Kesalahan
Langkah selanjutnya
- Tinjau API Perubahan Paket
- Jelajahi Penagihan Berbasis Kredit
- Terapkan peringatan untuk
subscription.on_hold - Lihat panduan kami Panduan Integrasi Webhook