Langsung ke konten utama

Ikhtisar

Langganan sesuai permintaan memungkinkan Anda untuk mengotorisasi metode pembayaran pelanggan sekali dan kemudian mengenakan jumlah variabel kapan pun Anda perlu, alih-alih pada jadwal tetap. Fitur ini tersedia untuk semua akun—tidak memerlukan persetujuan. Gunakan panduan ini untuk:
  • Membuat langganan sesuai permintaan (mengotorisasi mandat dengan harga awal opsional)
  • Memicu biaya berikutnya dengan jumlah kustom
  • Melacak hasil menggunakan webhook
Untuk pengaturan langganan umum, lihat Panduan Integrasi Langganan.

Prasyarat

  • Akun pedagang Dodo Payments dan kunci API
  • Rahasia webhook yang dikonfigurasi dan endpoint untuk menerima peristiwa
  • Produk langganan dalam katalog Anda
Jika Anda ingin pelanggan menyetujui mandat melalui checkout yang dihosting, atur payment_link: true dan berikan return_url.

Cara kerja sesuai permintaan

  1. Anda membuat langganan dengan objek on_demand untuk mengotorisasi metode pembayaran dan secara opsional mengumpulkan biaya awal.
  2. Kemudian, Anda membuat biaya terhadap langganan tersebut dengan jumlah kustom menggunakan endpoint biaya khusus.
  3. Anda mendengarkan webhook (misalnya, payment.succeeded, payment.failed) untuk memperbarui sistem Anda.

Buat langganan sesuai permintaan

Endpoint: POST /checkouts Bidang permintaan kunci (badan):
Silakan temukan di Buat Sesi Checkout

Buat langganan sesuai permintaan

import DodoPayments from 'dodopayments';

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

async function main() {
  const subscription = await client.checkoutSessions.create({
    product_cart: [{ product_id: 'pdt_123', quantity: 1 }],
    billing_address:  { city: 'SF', country: 'US', state: 'CA', street: '1 Market St', zipcode: '94105' },
    customer: { customer_id: 'cus_123' },
    return_url: 'https://example.com/billing/success',
    subscription_data: {
        on_demand: {
            mandate_only: true // set false to collect an initial charge
            // product_price: 1000, // optional: charge $10.00 now if mandate_only is false
            // product_currency: 'USD',
            // product_description: 'Custom initial charge',
            // adaptive_currency_fees_inclusive: false,
        }
    }
  });

  console.log(subscription.checkout_url);
}

main().catch(console.error);
Success
{
  "session_id": "cks_123",
  "checkout_url": "https://test.checkout.dodopayments.com/session/cks123"
}

Kenakan biaya langganan sesuai permintaan

Setelah mandat diotorisasi, buat biaya sesuai kebutuhan. Endpoint: POST /subscriptions/{subscription_id}/charge Bidang permintaan kunci (badan):
product_price
integer
wajib
Jumlah yang akan dikenakan biaya (dalam unit mata uang terkecil). Contoh: untuk mengenakan biaya $25.00, kirim 2500.
product_currency
string
Override mata uang opsional untuk biaya ini.
product_description
string
Override deskripsi opsional untuk biaya ini.
adaptive_currency_fees_inclusive
boolean
Jika true, termasuk biaya mata uang adaptif dalam product_price. Jika false, biaya ditambahkan di atasnya.
metadata
object
Metadata tambahan untuk pembayaran. Jika diabaikan, metadata langganan digunakan.
import DodoPayments from 'dodopayments';

const client = new DodoPayments({ bearerToken: process.env.DODO_PAYMENTS_API_KEY });

async function chargeNow(subscriptionId) {
  const res = await client.subscriptions.charge(subscriptionId, { product_price: 2500 });
  console.log(res.payment_id);
}

chargeNow('sub_123').catch(console.error);
Success
{ "payment_id": "pay_abc123" }
Mengenakan biaya langganan yang tidak sesuai permintaan mungkin gagal. Pastikan langganan memiliki on_demand: true dalam detailnya sebelum mengenakan biaya.

Pengulangan pembayaran

Sistem deteksi penipuan kami mungkin memblokir pola pengulangan yang agresif (dan dapat menandainya sebagai pengujian kartu potensial). Ikuti kebijakan pengulangan yang aman.
Pola pengulangan yang mendadak dapat ditandai sebagai penipuan atau pengujian kartu yang dicurigai oleh sistem risiko dan pemroses kami. Hindari pengulangan yang terkelompok; ikuti jadwal penundaan dan panduan penyelarasan waktu di bawah ini.

Prinsip untuk kebijakan pengulangan yang aman

  • Mekanisme penundaan: Gunakan penundaan eksponensial antara pengulangan.
  • Batas pengulangan: Batasi total pengulangan (maksimal 3–4 percobaan).
  • Penyaringan cerdas: Hanya ulangi pada kegagalan yang dapat diulang (misalnya, kesalahan jaringan/penerbit, dana tidak mencukupi); jangan pernah ulangi penolakan keras.
  • Pencegahan pengujian kartu: Jangan ulangi kegagalan seperti DO_NOT_HONOR, STOLEN_CARD, LOST_CARD, PICKUP_CARD, FRAUDULENT, AUTHENTICATION_FAILURE.
  • Variasi metadata (opsional): Jika Anda memelihara sistem pengulangan Anda sendiri, bedakan pengulangan melalui metadata (misalnya, retry_attempt).

Jadwal pengulangan yang disarankan (langganan)

  • Percobaan ke-1: Segera setelah Anda membuat biaya
  • Percobaan ke-2: Setelah 3 hari
  • Percobaan ke-3: Setelah 7 hari lagi (total 10 hari)
  • Percobaan ke-4 (akhir): Setelah 7 hari lagi (total 17 hari)
Langkah terakhir: jika masih belum dibayar, tandai langganan sebagai tidak dibayar atau batalkan, berdasarkan kebijakan Anda. Beri tahu pelanggan selama jendela untuk memperbarui metode pembayaran mereka.

Hindari pengulangan mendadak; sesuaikan dengan waktu otorisasi

  • Jangkar pengulangan pada cap waktu otorisasi asli untuk menghindari perilaku “ledakan” di seluruh portofolio Anda.
  • Contoh: Jika pelanggan memulai percobaan atau mandat pada pukul 1:10 siang hari ini, jadwalkan pengulangan berikutnya pada pukul 1:10 siang pada hari-hari berikutnya sesuai dengan penundaan Anda (misalnya, +3 hari → 1:10 siang, +7 hari → 1:10 siang).
  • Sebagai alternatif, jika Anda menyimpan waktu pembayaran terakhir yang berhasil T, jadwalkan percobaan berikutnya pada T + X days untuk menjaga penyelarasan waktu dalam sehari.
Zona waktu dan DST: gunakan standar waktu yang konsisten untuk penjadwalan dan konversi hanya untuk tampilan untuk mempertahankan interval.

Kode penolakan yang sebaiknya tidak Anda ulangi

  • STOLEN_CARD
  • DO_NOT_HONOR
  • FRAUDULENT
  • PICKUP_CARD
  • AUTHENTICATION_FAILURE
  • LOST_CARD
Untuk daftar lengkap alasan penolakan dan apakah mereka dapat diperbaiki oleh pengguna, lihat dokumentasi Kegagalan Transaksi.
Hanya ulangi pada masalah lunak/sementara (misalnya, insufficient_funds, issuer_unavailable, processing_error, timeout jaringan). Jika penolakan yang sama terulang, jeda pengulangan lebih lanjut.

Pedoman implementasi (tanpa kode)

  • Gunakan penjadwal/antrian yang mempertahankan cap waktu yang tepat; hitung percobaan berikutnya pada offset waktu yang tepat (misalnya, T + 3 days pada HH:MM yang sama).
  • Pertahankan dan rujuk cap waktu pembayaran terakhir yang berhasil T untuk menghitung percobaan berikutnya; jangan mengelompokkan beberapa langganan pada saat yang sama.
  • Selalu evaluasi alasan penolakan terakhir; hentikan pengulangan untuk penolakan keras dalam daftar lewati di atas.
  • Batasi pengulangan bersamaan per pelanggan dan per akun untuk mencegah lonjakan yang tidak disengaja.
  • Komunikasikan secara proaktif: email/SMS pelanggan untuk memperbarui metode pembayaran mereka sebelum percobaan berikutnya yang dijadwalkan.
  • Gunakan metadata hanya untuk observabilitas (misalnya, retry_attempt); jangan pernah mencoba untuk “menghindari” sistem penipuan/risiko dengan memutar bidang yang tidak penting.

Lacak hasil dengan webhook

Implementasikan penanganan webhook untuk melacak perjalanan pelanggan. Lihat Implementasi Webhook.
  • subscription.active: Mandat diotorisasi dan langganan diaktifkan
  • subscription.failed: Pembuatan gagal (misalnya, kegagalan mandat)
  • subscription.on_hold: Langganan ditangguhkan (misalnya, status tidak dibayar)
  • payment.succeeded: Biaya berhasil
  • payment.failed: Biaya gagal
Untuk alur sesuai permintaan, fokus pada payment.succeeded dan payment.failed untuk merekonsiliasi biaya berbasis penggunaan.

Pengujian dan langkah selanjutnya

1

Buat dalam mode uji

Gunakan kunci API uji Anda untuk membuat langganan dengan payment_link: true, lalu buka tautan dan selesaikan mandat.
2

Memicu biaya

Panggil endpoint biaya dengan jumlah kecil product_price (misalnya, 100) dan verifikasi Anda menerima payment.succeeded.
3

Go live

Beralih ke kunci API langsung Anda setelah Anda memvalidasi peristiwa dan pembaruan status internal.

Pemecahan masalah

  • 422 Permintaan Tidak Valid: Pastikan on_demand.mandate_only disediakan saat pembuatan dan product_price disediakan untuk biaya.
  • Kesalahan mata uang: Jika Anda mengoverride product_currency, pastikan itu didukung untuk akun dan pelanggan Anda.
  • Tidak ada webhook yang diterima: Verifikasi URL webhook dan konfigurasi rahasia tanda tangan.