Skip to main content

Prasyarat

Sebelum memulai, Anda memerlukan:
  • Akun merchant Dodo Payments
  • API key dari Developer → API Keys di dashboard, disimpan di DODO_PAYMENTS_API_KEY
  • Secret webhook dari Developer → Webhooks, disimpan di DODO_PAYMENTS_WEBHOOK_KEY
  • Setidaknya satu produk subscription yang dibuat di Products
Untuk informasi selengkapnya, lihat Prasyarat Panduan Integrasi.

Integrasi API

Checkout Sessions

Buat subscription dengan membangun checkout session menggunakan produk subscription Anda. Pelanggan mengotorisasi metode pembayaran dan subscription aktif setelah mereka menyelesaikan checkout.
Anda dapat menggabungkan produk subscription dengan produk satu kali dalam sesi checkout yang sama. Ini memungkinkan biaya setup, bundel hardware dengan SaaS, dan kasus penggunaan serupa. Lihat Checkout Sessions untuk contoh.Anda juga dapat menjual dua atau lebih produk subscription dalam satu checkout. Pelanggan membayar sekali dan mendapatkan satu subscription independen untuk setiap produk, masing-masing dengan siklus penagihannya sendiri. Keranjang seperti ini tidak dapat memuat produk satu kali. Lihat Multi-Subscription Cart.

API Response

Respons mencakup checkout_url:
Arahkan pelanggan ke URL ini. Mereka mengotorisasi payment method dan subscription diaktifkan.

Webhooks

Webhooks memberi tahu server Anda ketika event subscription terjadi. Siapkan endpoint Anda di Developer → Webhooks pada dashboard. Untuk menyiapkan endpoint webhook, lihat Webhooks.

Jenis Event Subscription

Lacak event berikut untuk mengelola siklus subscription:
  1. subscription.active — Subscription diaktifkan
  2. subscription.updated — Sebuah field pada subscription berubah
  3. subscription.on_hold — Charge renewal atau perubahan plan gagal
  4. subscription.failed — Pembuatan subscription gagal (terminal; pelanggan harus melakukan subscription ulang)
  5. subscription.renewed — Charge berulang berhasil
  6. subscription.past_due — Renewal gagal dan grace period dimulai; pelanggan tetap memiliki akses hingga past_due_ends_at
  7. subscription.plan_changed — Plan di-upgrade, di-downgrade, atau diubah
  8. subscription.cancelled — Subscription dibatalkan
  9. subscription.expired — Subscription mencapai akhir masa berlakunya
Ini adalah event inti. Untuk daftar lengkap, termasuk paused, unpaused, dan update_payment_method, lihat Subscription Webhooks.
Gunakan subscription.updated untuk mendapatkan notifikasi real-time tentang perubahan subscription apa pun, sehingga status aplikasi Anda tetap sinkron tanpa melakukan polling terhadap API.

Skenario Pembayaran

Alur Pembayaran Berhasil Urutan webhook bergantung pada apakah subscription memiliki trial. Penagihan langsung (0 hari trial):
  1. subscription.active: mandate diotorisasi dan subscription diaktifkan.
  2. payment.succeeded: mengonfirmasi charge pertama. Harapkan event ini dalam 2–10 menit setelah checkout.
Dengan periode trial:
  1. Saat trial dimulai (checkout): subscription.active dipicu setelah payment method diotorisasi. Belum ada charge berulang yang dilakukan. Charge pertama yang sebenarnya ditunda hingga trial berakhir.
  2. Saat trial berakhir: jumlah berulang ditagihkan, dan Anda menerima payment.succeeded bersama dengan subscription.renewed.
Setiap renewal berikutnya:
  • subscription.renewed: dipicu pada setiap siklus penagihan saat pembayaran renewal dipotong, selalu bersama payment.succeeded. Event ini juga membawa next_billing_date yang telah diperbarui.
Setiap kali uang benar-benar dipotong untuk produk subscription, Anda mendapatkan subscription.renewed dan payment.succeeded. Gunakan subscription.renewed (bukan hanya payment.succeeded) sebagai sinyal untuk memperpanjang akses ke siklus berikutnya.
Skenario Kegagalan Pembayaran
  1. Kegagalan Subscription
  • subscription.failed - Pembuatan subscription gagal karena pembuatan mandate gagal.
  • payment.failed - Menunjukkan pembayaran gagal.
  1. Subscription Ditangguhkan
  • subscription.on_hold - Subscription ditangguhkan karena pembayaran renewal atau charge perubahan plan gagal. Jika bisnis Anda memiliki grace period, renewal yang gagal pertama-tama memindahkan subscription ke past_due (subscription.past_due), lalu memindahkannya ke on_hold (atau cancelled, bergantung pada pengaturan grace period Anda) hanya setelah grace period berakhir. Lihat Subscription States.
  • Saat subscription ditangguhkan, subscription tidak akan diperbarui secara otomatis hingga payment method diperbarui.
Praktik Terbaik: Untuk menyederhanakan implementasi, kami menyarankan agar Anda terutama melacak event subscription untuk mengelola siklus subscription.
Untuk panduan lengkap tentang membaca error_code/error_message, menentukan kapan harus melakukan retry, dan menampilkan kegagalan kepada pelanggan, lihat Handle Payment Failures.

subscription.failed vs. subscription.on_hold

Kedua event ini mudah tertukar, tetapi memerlukan penanganan yang sangat berbeda:
subscription.failed bersifat terminal. Subscription tidak dapat diaktifkan kembali. Pelanggan harus membuat subscription baru. Jangan pernah memberikan entitlement saat event ini dipicu.

Menangani Subscription yang Ditangguhkan

Saat subscription memasuki status on_hold, Anda perlu memperbarui payment method untuk mengaktifkannya kembali. Bagian ini menjelaskan kapan subscription ditangguhkan dan cara menanganinya.

Kapan Subscription Ditangguhkan

Subscription ditangguhkan ketika:
  • Pembayaran renewal gagal: Charge renewal otomatis gagal karena dana tidak mencukupi, kartu kedaluwarsa, atau penolakan bank
  • Charge perubahan plan gagal: Charge langsung selama upgrade/downgrade plan gagal
  • Otorisasi payment method gagal: Payment method tidak dapat diotorisasi untuk charge berulang
Subscription dalam status on_hold tidak akan diperbarui secara otomatis. Anda harus memperbarui payment method untuk mengaktifkan kembali subscription.

Mengaktifkan Kembali Subscription yang Ditangguhkan

Untuk mengaktifkan kembali subscription dari status on_hold, gunakan Update Payment Method API. API ini secara otomatis:
  1. Membuat charge untuk saldo terutang
  2. Membuat invoice untuk charge tersebut
  3. Memproses pembayaran menggunakan payment method baru
  4. Mengaktifkan kembali subscription ke status active setelah pembayaran berhasil
1

Handle subscription.on_hold webhook

Saat menerima webhook subscription.on_hold, perbarui status aplikasi Anda dan beri tahu pelanggan:
2

Update payment method

Saat pelanggan siap memperbarui payment method, panggil Update Payment Method API:
Anda juga dapat menggunakan payment method ID yang sudah ada jika pelanggan memiliki payment method tersimpan:
3

Monitor webhook events

Setelah memperbarui payment method, pantau event webhook berikut:
  1. payment.succeeded - Charge untuk saldo terutang berhasil
  2. subscription.active - Subscription telah diaktifkan kembali

Contoh Payload Event Subscription


Mengubah Plan Subscription

Anda dapat meng-upgrade atau men-downgrade plan subscription menggunakan endpoint change plan API. Ini memungkinkan Anda mengubah produk, kuantitas, dan menangani proration subscription.

Change Plan API Reference

Untuk informasi mendetail tentang perubahan plan subscription, silakan lihat dokumentasi Change Plan API kami.

Opsi Proration

Saat mengubah plan subscription, Anda memiliki empat opsi untuk menangani charge langsung:

1. prorated_immediately

  • Memberikan kredit untuk bagian yang tidak terpakai dari siklus penagihan saat ini, diprorata berdasarkan waktu yang tersisa. Kredit mencakup base plan, kuantitas, dan add-on apa pun
  • Kemudian menagihkan siklus penuh pada plan, kuantitas, dan add-on baru. Charge itu sendiri tidak pernah diprorata
  • Charge langsung bersih = (siklus baru penuh) dikurangi (fraksi tersisa x siklus lama penuh). Jika kredit lebih besar, selisihnya disimpan sebagai kredit yang berlaku untuk subscription untuk renewal berikutnya
  • Selama periode trial, opsi ini langsung mengalihkan pengguna ke plan baru dan langsung menagih pelanggan

2. full_immediately

  • Menagih pelanggan sejumlah penuh subscription untuk plan baru tanpa kredit untuk siklus sebelumnya
  • Baik saat upgrade maupun downgrade, pelanggan membayar seluruh harga plan baru dari awal
  • Berguna ketika Anda ingin menagih jumlah penuh tanpa memedulikan berapa banyak waktu yang tersisa pada plan lama

3. difference_immediately

  • Pelanggan hanya membayar selisih antara harga plan lama dan harga plan baru
  • Jumlahnya tidak bergantung pada kapan perubahan dilakukan dalam siklus. Upgrade yang sama memiliki biaya yang sama pada hari ke-1 maupun hari ke-29
  • Saat upgrade, pelanggan langsung ditagih sejumlah selisihnya. Contoh, $30/bulan → $80/bulan = $50 ditagihkan secara langsung
  • Saat downgrade, selisih harga disimpan sebagai kredit yang berlaku untuk subscription dan diterapkan secara otomatis pada renewal berikutnya. Contoh, $50/bulan → $20/bulan = $30 disimpan sebagai kredit

4. do_not_bill

  • Menerapkan perubahan plan secara langsung tetapi tidak menagih apa pun saat perubahan dilakukan. Plan, kuantitas, dan add-on baru dapat langsung digunakan
  • Karena tidak ada tagihan saat ini, upgrade memberikan plan yang lebih tinggi secara gratis kepada pelanggan selama sisa siklus saat ini. Downgrade berlaku langsung tanpa kredit untuk bagian siklus yang belum digunakan dan telah dibayar
  • Add-on yang diberikan melalui do_not_bill tidak dikreditkan pada perubahan plan berikutnya karena add-on tersebut tidak pernah ditagihkan. Perubahan berikutnya menagihkan kuantitas add-on baru secara penuh
  • Plan yang diperbarui (beserta kuantitas/add-on) ditagihkan pada renewal terjadwal berikutnya, dan tanggal penagihan awal tetap dipertahankan
Ketiga mode “charge now” mengatur ulang siklus penagihan. prorated_immediately, difference_immediately, dan full_immediately memindahkan next_billing_date subscription ke tanggal perubahan. Hanya do_not_bill yang mempertahankan tanggal renewal awal, tetapi opsi ini tidak melakukan charge langsung.

Perilaku

  • Saat Anda memanggil API ini, Dodo Payments langsung memulai charge berdasarkan opsi proration yang dipilih
  • Dengan prorated_immediately, kredit untuk bagian siklus saat ini yang tidak terpakai dihitung pada setiap perubahan, baik upgrade maupun downgrade. Jika kredit tersebut melebihi charge siklus baru, sisa kredit ditambahkan ke saldo kredit subscription. Kredit ini khusus untuk subscription tersebut dan hanya digunakan untuk mengimbangi pembayaran berulang di masa mendatang pada subscription yang sama
  • Dengan difference_immediately, nilai bersih selalu sama persis dengan selisih harga. Untuk downgrade, kelebihannya disimpan sebagai kredit yang berlaku untuk subscription, sama seperti prorated_immediately
  • Opsi full_immediately mengabaikan perhitungan kredit dan menagihkan jumlah penuh plan baru
  • Opsi do_not_bill menerapkan perubahan secara langsung tetapi menunda penagihan hingga tanggal renewal berikutnya, yang tetap dipertahankan
Memilih mode proration:
  • difference_immediately — pelanggan membayar selisih harga. Opsi yang paling mudah diprediksi; charge sama, terlepas dari kapan perubahan dilakukan dalam siklus.
  • prorated_immediately — pelanggan hanya menerima kredit untuk waktu yang tidak terpakai pada siklus saat ini. Charge bervariasi bergantung pada kapan perubahan dilakukan dalam siklus.
  • full_immediately — pelanggan membayar jumlah penuh plan baru. Tidak ada kredit untuk siklus sebelumnya.
  • do_not_bill — tidak ada charge sekarang. Plan baru ditagihkan pada renewal berikutnya. Satu-satunya mode yang mempertahankan tanggal penagihan awal.

Pemrosesan Charge

  • Charge langsung yang dimulai saat perubahan plan biasanya selesai diproses dalam waktu kurang dari 2 menit
  • Jika charge langsung ini gagal karena alasan apa pun, subscription secara otomatis ditangguhkan hingga masalah teratasi

Subscription On-Demand

Subscription on-demand memungkinkan Anda menagih pelanggan secara fleksibel, bukan hanya berdasarkan jadwal tetap. Fitur ini tersedia untuk semua akun.
Untuk membuat subscription on-demand: Untuk membuat subscription on-demand, gunakan endpoint API POST /checkouts dan sertakan field subscription_data.on_demand dalam request body Anda. Ini memungkinkan Anda mengotorisasi payment method tanpa charge langsung, atau menetapkan harga awal khusus.
POST /subscriptions sudah deprecated. Fitur ini masih berfungsi untuk integrasi yang sudah ada, tetapi integrasi baru harus membuat subscription on-demand melalui Checkout Session (POST /checkouts) dengan subscription_data.on_demand. Lihat On-Demand Subscriptions Guide untuk alur terbaru.
Untuk menagih subscription on-demand: Untuk charge berikutnya, gunakan endpoint POST /subscriptions//charge dan tentukan jumlah yang akan ditagihkan kepada pelanggan untuk transaksi tersebut.
Untuk panduan lengkap langkah demi langkah (termasuk contoh request/response, kebijakan retry yang aman, dan penanganan webhook), lihat On-Demand Subscriptions Guide.

Hal Penting yang Perlu Diketahui tentang Penagihan Subscription

Tetapkan periode subscription lebih panjang daripada frekuensi pembayaran. Jika periode subscription sama dengan frekuensi pembayaran (misalnya period = 1 bulan, frequency = 1 bulan), subscription berlaku selama satu siklus saja lalu berpindah ke expired, bukan melakukan renewal. Untuk plan bulanan yang berkelanjutan, tetapkan periode subscription yang panjang (misalnya 20 tahun) dengan frekuensi pembayaran bulanan.
Currency terkunci pada charge pertama yang berhasil. Selalu kirimkan billing_currency dan billing_address.country secara eksplisit saat membuat checkout. Jika tidak disertakan, keduanya dideteksi dari IP pelanggan (Adaptive Currency), dan setelah subscription menerima charge pertamanya, currency ditetapkan untuk seluruh masa berlakunya. Pelanggan yang kemudian bepergian tidak dapat menggantinya.
Trial melakukan otorisasi $0, bukan charge. Saat subscription memiliki trial, dimulainya trial membuat otorisasi mandate $0 untuk menyimpan kartu; charge pertama yang sebenarnya dilakukan saat trial berakhir. Dalam daftar pembayaran, subscription dalam free trial menampilkan tepat satu pembayaran dengan total_amount sebesar 0. Paid trial menagihkan trial_amount di muka.
Siklus subscription: past_due = renewal gagal dan grace period sedang berlangsung (pelanggan tetap memiliki akses). on_hold = renewal gagal (dapat dipulihkan: minta pelanggan memperbarui payment method; retry dunning berlaku). expired = masa berlaku berakhir tanpa renewal dan tidak dapat diaktifkan kembali. Pelanggan harus melakukan subscription ulang. cancelled = diakhiri oleh pelanggan atau merchant. Sebagian besar kegagalan renewal adalah penolakan dari pihak issuer (dana tidak mencukupi, kartu ditolak), bukan error Dodo.
Kartu India menggunakan RBI e-mandate. Charge off-session (renewal dan charge perubahan plan) dapat memerlukan waktu hingga sekitar 48 jam untuk diselesaikan, dan auto-debit berulang di atas ₹15.000 memerlukan autentikasi pelanggan baru (sehingga upgrade yang melewati batas tersebut tidak dapat menggunakan mandate yang sudah ada). Saat satu charge masih berstatus processing, charge kedua pada subscription yang sama akan gagal dengan “Cannot create new charge as previous payment is not successful yet.” Kartu non-India dikonfirmasi hampir secara instan.
Subscription memiliki minimum $1,00 dalam USD. Checkout menolak total yang lebih rendah dengan TOTAL_PAYMENT_AMOUNT_BELOW_MINIMUM_AMOUNT. Currency selain USD, EUR, dan GBP juga harus bernilai setidaknya $1,00; lihat Minimum Amounts. Charge on-demand product_price di bawah 100 dalam unit currency terkecil ditolak dengan product_price: value out of range. Produk subscription dengan harga tepat $0 diperbolehkan; lihat Card-Optional at Zero Price. Untuk mengotorisasi kartu tanpa menagihnya, gunakan setup on-demand mandate_only.

Referensi API Terkait

Create Subscription (Deprecated)

API lama untuk membuat subscription secara langsung. Gunakan Checkout Sessions untuk integrasi baru

Change Subscription Plan

Referensi API untuk meng-upgrade, men-downgrade, atau mengubah plan subscription dengan opsi proration

Update Payment Method

Referensi API untuk memperbarui payment method dan mengaktifkan kembali subscription yang ditangguhkan

Patch Subscription

Referensi API untuk memperbarui detail dan konfigurasi subscription
Terakhir diubah pada 26 September 2026