DM Champ Docs

Isi Ulang Otomatis Sub-Akun (Penyedia Pembayaran Kustom)

Jika Anda lebih memilih untuk menangani pembayaran kredit sub-akun melalui penyedia Anda sendiri alih-alih Stripe (transfer bank, gateway pembayaran lokal, sistem penagihan kustom), platform ini menyediakan pasangan webhook + API sehingga Anda dapat menjalankan seluruh siklus penagihan dan pemberian kredit sendiri. Gambaran umum non-teknis tersedia di halaman Akun Agensi; halaman ini membahas payload webhook yang tepat dan panggilan API yang Anda buat untuk memberikan kredit setelahnya.

Webhook hanyalah salah satu cara pembayaran isi ulang otomatis dilakukan. Jika Anda menghubungkan Stripe atau PayPal dalam Mode SaaS, platform akan menagih kartu atau akun PayPal yang tersimpan milik klien secara otomatis dan memberikan kredit, jadi tidak ada yang perlu Anda bangun di halaman ini. Lanjutkan membaca hanya jika Anda ingin menangani pembayaran sendiri.


Sekilas alur kerja

  1. Saldo kredit sub-akun turun di bawah ambang batas isi ulang otomatis mereka.
  2. Platform memanggil URL webhook Anda dengan detail sub-akun dan jumlah kredit yang mereka butuhkan.
  3. Server Anda menagih pelanggan melalui penyedia mana pun yang Anda gunakan.
  4. Server Anda memanggil API Pemberian Kredit untuk menambahkan kredit ke sub-akun tersebut.
  5. Server Anda merespons 200 untuk mengonfirmasi webhook.

1. Webhook: agency_sub_account_auto_recharge

Konfigurasikan URL webhook dengan mengeklik SaaS Mode di bilah sisi utama, memilih Use a Custom Payment Provider Instead (atau, setelah dikonfigurasi, membuka kartu Custom Payment Provider), dan mengisi kolom Auto-Recharge Webhook.

Kapan webhook ini dipicu

Saat saldo kredit sub-akun turun di bawah ambang batas isi ulang otomatis yang dikonfigurasi.

Payload

{
  "event": "agency_sub_account_auto_recharge",
  "sub_account_id": "<sub-account-id>",
  "sub_account_email": "customer@example.com",
  "sub_account_name": "John Doe",
  "agency_id": "<agency-id>",
  "credits_requested": 500,
  "current_balance": 42,
  "threshold": 100,
  "price_per_credit_cents": 10,
  "price_per_credit_currency": "usd",
  "total_amount_cents": 5000,
  "timestamp": "2026-04-13T12:00:00.000Z",
  "idempotency_key": "auto_recharge_abc123_1681387200000"
}
Bidang Deskripsi
event Selalu agency_sub_account_auto_recharge untuk webhook ini.
sub_account_id ID unik sub-akun yang membutuhkan kredit.
sub_account_email Alamat email sub-akun.
sub_account_name Nama tampilan sub-akun.
agency_id ID unik akun agensi Anda.
credits_requested Berapa banyak kredit yang akan diberikan. Ini adalah jumlah isi ulang yang Anda konfigurasikan, tetapi jika saldo telah turun lebih jauh di bawah ambang batas daripada jumlah tersebut, saldo akan secara otomatis dinaikkan ke jumlah yang diperlukan untuk mengembalikan saldo di atas ambang batas sekaligus. Selalu tagih (dan berikan) nilai credits_requested dari payload — jangan melakukan hard-code pada jumlah isi ulang Anda.
current_balance Saldo kredit sub-akun pada saat webhook dikirim.
threshold Ambang batas saldo yang memicu isi ulang.
price_per_credit_cents Harga per kredit yang Anda konfigurasikan, dalam sen.
price_per_credit_currency Mata uang untuk harga (misalnya, usd).
total_amount_cents Jumlah total yang akan ditagihkan, dalam sen (credits_requested × price_per_credit_cents).
timestamp Kapan webhook dikirim (format ISO 8601).
idempotency_key Kunci unik untuk permintaan isi ulang khusus ini. Gunakan ini untuk mencegah pemberian kredit dua kali jika server Anda menerima webhook yang sama lebih dari sekali.

Catatan penting

  • Cooldown 5 menit — Setelah upaya isi ulang untuk sub-akun, platform tidak akan mengirim webhook lain untuk sub-akun tersebut setidaknya selama 5 menit, meskipun saldo mereka turun lebih jauh. Mencegah penagihan ganda selama pemrosesan.
  • Gunakan kunci idempotensi — Selalu periksa idempotency_key sebelum memberikan kredit. Jika server Anda mengalami crash setelah memberikan kredit tetapi sebelum merespons, platform mungkin mengirim ulang webhook pada penurunan kredit berikutnya.
  • Kegagalan aman dan dapat pulih sendiri — Jika URL webhook Anda tidak dapat dijangkau atau mengembalikan kesalahan, tidak ada kredit yang diberikan. Platform terus mengirim ulang webhook (sekali per cooldown 5 menit) selama sub-akun tetap di bawah ambang batas — ini tidak mengharuskan saldo untuk naik kembali di atas ambang batas dan turun lagi terlebih dahulu. Satu penagihan yang terlewat tidak akan lagi membuat sub-akun tidak terisi ulang secara permanen.
  • Tetapkan jumlah isi ulang Anda pada atau di atas ambang batas — Jumlah isi ulang yang Anda konfigurasikan harus lebih besar dari atau sama dengan ambang batas isi ulang otomatis, sehingga satu isi ulang selalu mengembalikan saldo di atas ambang batas. (Jika Anda perlu memperbaiki sub-akun yang turun jauh di bawah ambang batas, platform akan menambahkannya sesuai kekurangan secara otomatis — lihat credits_requested di atas.)

2. API Pemberian Kredit

Setelah server Anda memproses pembayaran, panggil endpoint ini untuk menambahkan kredit ke sub-akun.

Permintaan

POST https://api.dmchamp.com/v1/subaccounts/credits
X-API-Key: YOUR_API_KEY
Content-Type: application/json

{
  "email": "customer@example.com",
  "amount": 500,
  "description": "Auto-recharge via webhook"
}
Bidang Wajib Deskripsi
email Ya Alamat email sub-akun (harus cocok dengan sub-akun yang ada di bawah agensi Anda).
amount Ya Jumlah kredit yang akan diberikan.
description Tidak Catatan yang menjelaskan mengapa kredit ditambahkan (ditampilkan dalam riwayat transaksi kredit).

Autentikasi: Kirim kunci API Anda di header permintaan — baik X-API-Key: YOUR_API_KEY atau Authorization: Bearer YOUR_API_KEY. Header adalah cara yang direkomendasikan, karena kunci di URL akan tersimpan dalam riwayat peramban, log proksi, dan log akses server. Parameter kueri ?apiKey=YOUR_API_KEY dan kolom apiKey dalam isi JSON juga masih berfungsi, sehingga integrasi lama tetap berjalan tanpa perubahan.

Respons

{
  "success": true,
  "sub_account_id": "abc123xyz",
  "credits_added": 500,
  "new_balance": 542
}

Tip: Simpan idempotency_key dari payload webhook dan periksa sebelum memanggil endpoint ini. Hal ini mencegah pemberian kredit dua kali secara tidak sengaja jika server Anda menerima webhook yang sama lebih dari sekali.

Apa yang terjadi pada kredit yang diberikan saat reset bulanan

Hal ini bergantung pada bagaimana sub-akun disiapkan:

  • Penjualan kembali (sub-akun membayar Anda untuk kredit): kredit yang Anda berikan di sini dicatat sebagai kredit yang dibeli dan diakumulasikan setiap bulan. Berapa pun yang belum dibelanjakan oleh sub-akun akan tetap ada di saldo.
  • Alokasi (Anda memberikan tunjangan bulanan kepada sub-akun): saldo akan diisi ulang ke tunjangan bulanan pada tanggal reset, sehingga apa pun yang tidak dibelanjakan tidak akan diakumulasikan. Ini disengaja — tunjangan diberikan baru setiap bulan.

Jika Anda ingin saldo sisa sub-akun ditambahkan ke tunjangan bulanan barunya alih-alih menggantikannya, aktifkan pengalihan kredit (credit roll-over):

PUT https://api.dmchamp.com/v1/subaccounts/{subAccountUid}/limits
X-API-Key: YOUR_API_KEY
Content-Type: application/json

{
  "usageLimits": { "roll_over_to_next_month": true }
}

Jika sub-akun — atau paket yang digunakannya — juga memiliki batas akumulasi (roll-over cap) atau masa berlaku yang ditetapkan, penyetelan ulang terjadi pada saat aturan tersebut diterapkan: jatah yang dibawa ke periode berikutnya dipangkas sesuai dengan jumlah bulan yang Anda izinkan, dan jatah yang tidak terpakai lebih lama dari periode masa berlaku akan dihapus, sebelum jatah baru ditambahkan. Kredit yang diberikan melalui endpoint ini, isi ulang otomatis, dan isi ulang mandiri klien adalah kredit satu kali dan tidak pernah dipangkas. Lihat Membatasi apa yang diakumulasikan.


Contoh menyeluruh

Handler yang umum terlihat seperti ini:

on POST /your-recharge-webhook:
  payload = request.body

  if seen(payload.idempotency_key):
    return 200  // already processed, ack and exit

  charge_result = your_payment_provider.charge(
    email = payload.sub_account_email,
    amount_cents = payload.total_amount_cents,
    currency = payload.price_per_credit_currency,
  )

  if not charge_result.ok:
    return 500  // platform will retry on next balance drop

  api.post("/v1/subaccounts/credits", {
    email = payload.sub_account_email,
    amount = payload.credits_requested,
    description = "Auto-recharge via " + your_provider_name,
  })

  mark_seen(payload.idempotency_key)
  return 200