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:
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:
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:
grossAmountataurealGrossAmountsama denganuniqueAmount. - 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 - clockSkewMssampaiexpiresAt + clockSkewMs. Timestamp yang tidak dapat diparse jatuh ke nominal dan status saja.
Grace window dan expiry
Rekonsiliasi berjalan sebelum penandaan kedaluwarsa. Pembayaran baru menjadi expired setelahexpiresAt + 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 lewatpayment pada config provider: