ping!
Ke aplikasi
Developer · API internal

Lifecycle & settlement

Bedakan status database dari DTO client, lalu pahami kapan dana ditahan, dibebankan, dilepas, dan kapan sebuah order benar-benar selesai.

Unduh OpenAPI 3.1
Di halaman ini

Database dan API memakai status berbeda

mapOrder di lib/ping/mappers.ts menyederhanakan status domain menjadi status untuk UI. Jangan membandingkan Order.status dengan ACTIVE atau CODE_RECEIVED: nilai itu hanya ada di domain/database.

Database dan API memakai status berbeda
Status domainOrder.statusSinyal yang dipakai client
CREATED / PURCHASINGwaitingisPreparing = true; phone masih berupa teks status.
ACTIVEwaitingNomor terbit; canCancel mengikuti cooldown server.
CODE_RECEIVEDwaitingcode tersedia, canComplete = true, canCancel = false.
COMPLETEDcompletedPembebanan selesai; berhenti polling.
CANCELLEDcancelledPembatalan telah dikonfirmasi; berhenti polling.
EXPIREDexpiredKedaluwarsa terkonfirmasi; berhenti polling.
FAILED_UPSTREAMfailedPembelian gagal definitif; dana hold dilepas.
SMS masuk belum sama dengan completed

CODE_RECEIVED masih menjadi waiting pada DTO. Tawarkan penyelesaian jika canComplete true, dan tampilkan code bila tersedia. Jangan menunggu status completed untuk menampilkan SMS.

Jalur uang

  1. Hold saat order dibuat

    Saldo tersedia berkurang karena sebagian saldo ditahan. Ini belum pembebanan final. Ledger dan order dibuat secara terkoordinasi.

  2. Capture setelah penyelesaian

    Saat order diselesaikan, dana yang ditahan ditangkap menjadi pembayaran. Settlement menggunakan kunci tetap per order untuk mencegah pembebanan ganda.

  3. Release setelah gagal atau batal terkonfirmasi

    Kegagalan pembelian yang definitif, pembatalan, atau kedaluwarsa terkonfirmasi melepas dana. Respons ambigu tidak membenarkan release.

  4. Revalidasi, jangan menebak saldo

    Sesudah mutasi, baca ulang akun, detail order, daftar order, dan ledger. Jangan mengurangi/menambah saldo sendiri di komponen.

Cooldown dan pembatalan

Pembatalan paling awal tersedia 2 menit setelah respons pembelian selesai, dengan fallback timestamp dari server. Hanya ACTIVE sebelum SMS yang memenuhi syarat. Gunakan canCancel dan cancelAvailableAt untuk UI; server tetap memeriksa ulang saat aksi dilakukan.

Saat timer kedaluwarsa, server harus mengamati provider lalu membatalkan jika masih menunggu. Browser tidak boleh menetapkan EXPIRED, menghapus order, atau melepas saldo berdasarkan jam lokal. Jika SMS datang bersamaan dengan pembatalan, baca respons terkini dan ikuti status yang diputuskan server.

Polling tanpa request bertumpuk

  • GET detail order berjalan tiap 5 detik selama DTO berstatus waiting. Hook useOrder berhenti saat tab tersembunyi/offline dan pada status terminal.
  • Jangan gunakan loop setInterval yang membuat request tumpang tindih. Gunakan SWR/useOrder dengan interval dan aturan retry yang sudah ada.
  • GET daftar order tidak memeriksa provider. Membaca daftar saja tidak cukup untuk menerima status/SMS terbaru.
  • Provider budget, per-order lease, dan backoff ada di server. Satu request browser tidak menjamin satu panggilan upstream atau data upstream yang langsung baru.

Lifecycle top-up berbeda

Lifecycle top-up berbeda
Status PaymentPerilaku client
CREATINGHasil pembuatan masih dikonfirmasi. Materi QR bisa null. Jangan membuat pembayaran baru.
PENDINGTampilkan materi pembayaran yang tersedia; pengguna membayar totalAmount.
PAIDServer telah memverifikasi dan mengkreditkan requestedAmount sekali. Revalidasi dompet.
EXPIRED / FAILEDBerhenti polling. Materi QR tidak ditampilkan lagi; baca message bila ada.
expiresAt pembayaran bukan ISO UTC

Provider dapat mengirim timestamp tanpa zona waktu. Simpan/tampilkan dengan benar, jangan menambahkan Z atau menyimpulkan status PAID/EXPIRED dari jam browser. Hanya konfirmasi provider mengubah status pembayaran.

Ping! · Panduan yang tumbuh bersama produknya.Bantuan