Skip to main content
Semua adapter memakai alur inti yang sama, dikendalikan PaymentService. Halaman ini menjelaskan siklus lengkap dari createPayment sampai paid/expired.

Alur inti

1

Alokasi nominal unik

AmountAllocator memilih nominal akhir unik dalam scope provider/account/merchant-store. Slot terkecil dipilih lebih dulu.
2

QRIS dinamis

staticToDynamicQris menambahkan tag nominal EMV 54, mengubah QRIS menjadi dinamis, dan menghitung ulang CRC - hanya bila static QRIS terkonfigurasi.
3

Ambil feed

Adapter provider mengambil serta menormalisasi feed menjadi rupiah utuh.
4

Cocokkan

PaymentService mencocokkan nominal, status, waktu, dan scope. Satu transaksi hanya boleh melunasi satu pembayaran.

Membuat pembayaran

createPayment mengembalikan Payment dengan uniqueAmount (nominal yang harus dibayar pembeli) dan qrString (payload QRIS dinamis, bila static QRIS terkonfigurasi). amount wajib bilangan bulat positif dalam rupiah utuh. Panggilan konkuren diserialkan: membaca himpunan aktif dan menulis pembayaran baru adalah dua await, dan tanpa serialisasi setiap pemanggil dalam burst melihat state “sebelum” yang sama lalu memilih offset yang sama.

Objek Payment

Polling background vs tick manual

start() memulai timer background dengan interval pollIntervalMs (default 3 detik). stop() menghentikannya. Timer tidak menahan event loop tetap hidup (unref). Untuk runtime tanpa timer persisten (Worker, Edge, Lambda), panggil tick() dari scheduler platform:
Satu tick() menjalankan satu putaran: menarik feed, menyelesaikan yang cocok, lalu menandai kedaluwarsa yang lewat masa berlaku. Bila sebuah tick sedang berjalan, panggilan tick lain langsung kembali kosong.

Event

PaymentService adalah event emitter dengan tiga event bertipe:
Listener yang melempar diisolasi: exception-nya disurface-kan ke channel error, tidak membatalkan accounting tick yang sudah tersimpan ke store.

Membatalkan dan membaca

cancelPayment hanya membatalkan pembayaran yang masih pending. Bila pembayaran sudah terminal (paid/expired/cancelled), state tersimpan dikembalikan apa adanya sehingga balapan dengan poller tidak dapat membatalkan pembayaran yang sudah lunas.

Aturan pencocokan

Sebuah transaksi melunasi pembayaran bila:
  • Nominal cocok: grossAmount atau realGrossAmount sama dengan uniqueAmount.
  • Status bukan gagal yang dikenal: status sukses (settlement, capture, success, paid, settled, completed) diterima; status kosong atau tidak dikenal juga diterima (fail-open); hanya status gagal yang dikenal ditolak.
  • Waktu di dalam jendela: createdAt - clockSkewMs sampai expiresAt + clockSkewMs. Timestamp yang tidak dapat diparse jatuh ke nominal dan status saja.
Nominal adalah pembeda utama; keunikan nominal antar pembayaran aktif dijamin allocator, sehingga kecocokan nominal eksak dalam jendela mengidentifikasi pembayar tanpa ambiguitas. Lihat Konsep inti.

Grace window dan expiry

Rekonsiliasi berjalan sebelum penandaan kedaluwarsa. Pembayaran baru menjadi expired setelah expiresAt + clockSkewMs, yaitu saat matcher juga berhenti menerima transaksi. Ini menahan jeda indexing feed agar uang yang dibayar tepat waktu tidak kehilangan pesanannya. Default masa berlaku adalah 5 menit. Feed dapat terlambat mengindeks, terutama bila scheduler berjalan jarang. Sesuaikan payment.defaultExpiryMs agar setidaknya mencakup interval scheduler dan keterlambatan feed yang realistis.

Opsi tuning

Diteruskan lewat payment pada config provider:

Referensi

Lihat Referensi API PaymentService untuk seluruh opsi, method, dan event.