Konsep
Halaman ini menjelaskan cara Reader berpikir: kapan tagihan lunas, kapan kedaluwarsa, apa yang terjadi bila HP mati, dan bagaimana transfer telat atau dobel ditangani. Baca halaman ini sebelum menulis kode yang memenuhi pesanan.
Satu prinsip berlaku di seluruh halaman: uang yang sudah masuk atau keluar tidak pernah digagalkan. Reader hanya memutuskan ke catatan mana uang itu ditautkan, dan setiap keputusan bisa dilihat kembali di dashboard.
Tagihan dan payout
| Tagihan (payment) | Payout | |
|---|---|---|
| Arah uang | Masuk ke rekening Anda | Keluar dari rekening Anda |
| Siapa yang mentransfer | Pembeli | Anda sendiri, dari app bank di HP Reader |
| Contoh | Pembayaran order | Pencairan dana mitra, komisi, honor, refund |
| Dibuat lewat | POST /api/v1/payments |
POST /api/v1/payouts |
| Status selesai | paid (lunas) |
sent (terkirim) |
| Webhook utama | payment.paid |
payout.sent |
| Awalan ID | pay_ |
po_ |
Keduanya punya nominal, kode unik, total, masa berlaku, dan reference_id.
Aturan waktu, telat, dobel, dan manual di halaman ini berlaku sama untuk
keduanya. Untuk payout, cukup ganti "lunas" menjadi "terkirim".
RAGH tidak memindahkan uang. Payout hanya mencatat transfer yang akan Anda lakukan, lalu membuktikannya dari notifikasi uang keluar.
Kode unik dan total unik
- Setiap tagihan dan payout mendapat kode unik 1–999 yang ditambahkan ke nominal. Nominal Rp 200.000 dengan kode 123 menjadi total Rp 200.123.
- Yang dijaga unik adalah total per rekening per arah. Dua tagihan di rekening yang sama tidak pernah punya total yang sama selama totalnya masih terkunci. Tagihan di rekening lain boleh punya total yang sama.
- Total dikunci sampai:
- tagihan pending: kedaluwarsa efektif + masa jeda 48 jam;
- tagihan lunas: waktu lunas + 48 jam;
- tagihan dibatalkan: waktu batal + 48 jam.
- Dari kode yang bebas, Reader memilih total yang paling lama tidak dipakai. Transfer yang sangat telat jadi kecil peluangnya nyasar ke tagihan baru.
- Bila semua 999 kode untuk satu nominal di satu rekening sedang terkunci,
pembuatan tagihan ditolak dengan
409 unique_code_exhausted. Kapasitas praktisnya sekitar 330 tagihan per hari untuk satu nominal dasar per rekening. Bila sering terjadi, perpendek masa berlaku tagihan, bedakan nominal, atau tambah rekening.
Untuk payout, kode unik juga ditambahkan. Penerima menerima sedikit lebih banyak (paling banyak Rp 999), tidak pernah kurang dari haknya.
Uang masuk dan uang keluar tidak pernah tercampur
- Setiap notifikasi dibaca dengan pola kalimat yang cocok persis untuk bank
itu. Pola itulah yang menentukan arah: masuk (
credit) atau keluar (debit). Arah tidak pernah ditebak dari kata kunci lepas. - Notifikasi yang tidak cocok dengan pola mana pun dicatat
parse_faileddan tidak diproses ke arah mana pun. - Uang masuk hanya dicocokkan ke tagihan. Uang keluar hanya dicocokkan ke payout. Kode unik keduanya terpisah. Uang keluar Rp 150.123 tidak mungkin melunasi tagihan Rp 150.123.
- Uang masuk yang bukan pembayaran, misalnya bunga atau pengembalian dana dari bank, tidak pernah dicocokkan ke tagihan. Pengembalian dana diperiksa terhadap payout (lihat Payout dikembalikan bank).
- Uang keluar di rekening yang payout-nya tidak aktif dianggap pengeluaran pribadi Anda. Mutasinya diabaikan dan dihapus setelah 7 hari.
Status tagihan dan payout
Tagihan (status):
| Status | Arti |
|---|---|
pending |
Menunggu transfer |
paid |
Lunas |
expired |
Kedaluwarsa. Belum final selama masa jeda 48 jam |
cancelled |
Dibatalkan oleh Anda atau oleh sistem |
Payout (status):
| Status | Arti |
|---|---|
pending |
Menunggu Anda mentransfer |
sent |
Terkirim, terbukti dari notifikasi uang keluar |
expired |
Kedaluwarsa. Belum final selama masa jeda 48 jam |
cancelled |
Dibatalkan |
reversed |
Sudah terkirim, lalu dikembalikan bank |
Tanda tambahan di data tagihan dan payout:
| Field | Arti |
|---|---|
late |
true bila lunas/terkirim setelah kedaluwarsa, dalam masa jeda |
paid_after_cancel / sent_after_cancel |
true bila uangnya datang setelah catatan dibatalkan |
confirmation_delayed |
true selama rekening tidak terpantau. Batas bayar ditahan |
match_type |
auto (dari notifikasi), manual_unverified (ditandai manual, notifikasi belum datang), manual (manual yang sudah terbukti, atau dicocokkan manual dari mutasi) |
recipient_check (payout) |
match, mismatch, atau unavailable bila notifikasi bank tidak memuat nama atau nomor penerima |
test |
true untuk data mode uji |
Rekening terpantau dan tidak terpantau
Saat internet HP mati, app bank pun tidak menerima notifikasi. Selama itu, Reader tidak bisa melihat apa pun. Karena itu setiap rekening punya status pemantauan.
Rekening tidak terpantau bila salah satu hal ini terjadi:
| Penyebab | Contoh |
|---|---|
| HP tidak mengirim kabar lebih dari 15 menit | HP mati, offline, atau app Reader dihentikan |
| Akses notifikasi Reader terputus | Izin dicabut, atau Android memutus layanan |
| App bank tidak terpasang | App bank dihapus |
| Antrean di HP belum kosong | Ada notifikasi yang belum terkirim ke server |
| Tanda tangan HP gagal diverifikasi | HP perlu login ulang |
| Format notifikasi bank berubah | Ada notifikasi bernominal yang tidak terbaca (parse_failed) |
| Tidak ada HP yang membaca rekening | HP dicabut dari akun |
Rekening dianggap pulih 15 menit setelah semua penyebab beres. Jeda 15 menit memberi waktu bagi notifikasi yang tertahan untuk menyusul.
Pemilik dan admin akun dikabari lewat email (dan WhatsApp, bila nomor HP terisi di profil) saat rekening tidak terpantau, 1 jam kemudian, 6 jam kemudian, dan saat pulih kembali.
Selama tidak terpantau:
- tagihan dan payout pending mendapat
confirmation_delayed: true; - halaman bayar menampilkan "Konfirmasi tertunda. Kalau sudah transfer, jangan transfer lagi.";
- tagihan baru tanpa
bank_codediarahkan ke rekening lain yang terpantau, bila ada.
Penahanan batas bayar
Tagihan tidak pernah kedaluwarsa selama rekeningnya tidak terpantau. Pembeli yang sudah transfer saat HP Anda mati tidak boleh melihat tagihannya kedaluwarsa.
kedaluwarsa efektif = paling akhir di antara:
- expires_at
- waktu rekening pulih + 15 menit
paling lama expires_at + 7 hari
Contoh: tagihan berlaku sampai 14.00. HP mati pukul 13.30 dan menyala lagi
pukul 16.00. Rekening pulih pukul 16.15, jadi tagihan baru bisa kedaluwarsa
setelah 16.15. Selama 13.30–16.15, status tetap pending dengan
confirmation_delayed: true.
Field expires_at di API tetap menunjukkan batas awal. Yang menentukan adalah
status.
Masa berlaku tagihan: bawaan 24 jam, bisa diatur 15 menit sampai 7 hari
(expires_in_minutes).
Transfer telat: dicatat, tidak digagalkan
| Transfer tercatat… | Hasil | match_status mutasi |
|---|---|---|
| Sebelum kedaluwarsa efektif | Lunas, late: false |
matched |
| Sesudahnya, tetapi jam transaksi di teks notifikasi ≤ kedaluwarsa | Lunas, late: false (yang telat hanya notifikasinya) |
matched |
| Dalam masa jeda 48 jam | Otomatis lunas, late: true |
matched_late |
| Setelah dibatalkan, dalam masa jeda | Lunas, late: true + paid_after_cancel: true, lalu masuk perlu tindakan |
matched_late |
| Setelah masa jeda lewat | Tidak dicocokkan otomatis. Tercatat tanpa pasangan, dengan saran tagihan lama | no_candidate |
Aturan untuk sistem Anda:
payment.expiredbelum final selama masa jeda. Jangan anggap tagihan gagal permanen, dan jangan menghapus pesanan.- Jangan membatalkan pesanan yang sudah dipenuhi karena event yang datang belakangan.
- Rekomendasi untuk
late: true: penuhi pesanannya. Pembeli sudah membayar.
Setelah masa jeda: cocokkan manual
Transfer yang datang lebih dari 48 jam setelah tagihan selesai tidak lagi
dicocokkan otomatis, karena totalnya mungkin sudah dipakai tagihan lain.
Mutasinya masuk daftar perlu tindakan sebagai "Mutasi tanpa tagihan",
lengkap dengan saran tagihan yang mungkin dimaksud. Cocokkan dari dashboard,
menu Mutasi. Setelah dicocokkan, tagihan menjadi lunas dan webhook
payment.paid terkirim seperti biasa.
Bayar lagi berarti perpanjang tagihan yang sama
Bila pembeli ingin membayar tagihan yang sudah kedaluwarsa, perpanjang tagihan yang sama, jangan buat tagihan baru. Kode dan totalnya tetap sama, sehingga transfer yang sempat terkirim tetap cocok.
- Lewat API:
POST /api/v1/payments/{id}/extend. - Lewat API juga: panggil ulang
POST /api/v1/paymentsdenganreference_iddanamountyang sama. Tagihan kedaluwarsa dalam masa jeda dibuka lagi. - Lewat halaman bayar: pembeli bisa menekan perpanjang 60 menit, bila pengaturan aplikasi Anda mengizinkan perpanjangan (menyala secara bawaan).
Perpanjangan hanya bisa untuk tagihan pending, atau expired yang masih
dalam masa jeda.
Uang dobel
| Penyebab | Yang terjadi |
|---|---|
| Pembeli mentransfer dua kali untuk tagihan yang sudah lunas (dalam 48 jam setelah lunas) | Transfer kedua dicatat sebagai uang dobel (duplicate_payment). Webhook payment.duplicate terkirim, dan kejadiannya masuk perlu tindakan |
| Anda mentransfer payout dua kali | Transfer kedua dicatat sebagai payout dobel (duplicate_payout). Webhook payout.duplicate terkirim, dan kejadiannya masuk perlu tindakan |
| Sistem Anda membuat tagihan kedua untuk order yang sama | Dicegah oleh reference_id. Memanggil ulang selalu aman (lihat API) |
| Pembeli membayar ulang karena konfirmasi tertunda | Dicegah oleh penahanan batas bayar dan halaman bayar yang menampilkan "jangan transfer lagi" |
Tagihan lunas tidak pernah berubah karena uang dobel. Refund atau penagihan kembali adalah tanggung jawab Anda.
Bila satu tagihan untuk sebuah reference_id lunas, tagihan lain yang masih
pending untuk reference_id yang sama otomatis dibatalkan.
Lunas manual dan verifikasi
Kadang Anda perlu menandai tagihan lunas sebelum notifikasinya datang, misalnya karena pembeli mengirim bukti transfer.
- Tandai lunas dari dashboard (menu Transaksi). Aksi ini tidak tersedia lewat API, dan tercatat siapa yang melakukannya.
- Tagihan menjadi
paiddenganmatch_type: manual_unverified. Webhookpayment.paidterkirim denganmutation: null. - Bila notifikasi transfernya datang kemudian, tagihan menjadi
terverifikasi (
match_type: manual) dan webhookpayment.verifiedterkirim. Notifikasi itu tidak dihitung sebagai uang dobel. - Bila dalam 24 jam notifikasinya tidak pernah datang, tagihan masuk perlu tindakan: "Selesai manual belum terverifikasi". Cek mutasi bank Anda. Bukti transfer bisa dipalsukan, notifikasi bank tidak.
Hal yang sama berlaku untuk payout (payout.verified).
Payout: aturan khusus
- Satu payout = satu transfer. Transfer massal (bulk) tidak didukung.
- Transfer dari app bank rekening sumber, di HP yang dibaca Reader.
- Reader membaca nominal pokok, bukan pokok + biaya transfer antarbank.
- Cek penerima. Bila notifikasi bank memuat nama atau potongan nomor
penerima, keduanya dibandingkan dengan
recipient. Bila berbeda, payout tetapsent(uangnya memang sudah keluar), tetapirecipient_check: "mismatch"dan kejadiannya masuk perlu tindakan.
Payout dikembalikan bank
Bila bank mengembalikan transfer (misalnya rekening tujuan tutup), notifikasi
pengembalian dana dengan total yang sama dalam masa jeda membuat payout menjadi
reversed. Webhook payout.reversed terkirim, dan kejadiannya masuk perlu
tindakan. Untuk mentransfer ulang, buat payout baru dengan reference_id yang
sama.
Perlu tindakan
Kejadian yang butuh keputusan Anda dikumpulkan di menu Perlu tindakan di dashboard. Setiap butir diselesaikan dengan memilih salah satu penyelesaian.
| Jenis | Kapan muncul | Pilihan penyelesaian |
|---|---|---|
| Lunas setelah dibatalkan | Uang masuk untuk tagihan yang sudah dibatalkan (atau uang keluar untuk payout yang dibatalkan) | Pesanan dipenuhi / Sudah direfund |
| Uang masuk dobel | Transfer kedua untuk tagihan lunas | Sudah direfund / Dijadikan pembayaran lain / Abaikan |
| Payout dobel | Transfer kedua untuk payout terkirim | Sudah diminta kembali / Dianggap pembayaran berikutnya / Abaikan |
| Payout: penerima tidak cocok | recipient_check: mismatch |
Sudah dicek, benar / Salah transfer, sedang ditangani |
| Payout dikembalikan bank | Payout menjadi reversed |
Sudah ditransfer ulang / Dibatalkan |
| Selesai manual belum terverifikasi | 24 jam setelah ditandai manual, notifikasi belum datang | Sudah dicek di mutasi bank / Batalkan pelunasan |
| Mutasi tanpa tagihan | Uang masuk tanpa pasangan; atau uang keluar yang mirip payout pending | Sudah dicocokkan manual / Abaikan |
| Webhook ditolak aplikasi | Sistem Anda membalas ack rejected |
Sudah diperbaiki, dikirim ulang / Abaikan |
| Notifikasi tidak terbaca | Notifikasi bernominal gagal dibaca, atau bank merangkum beberapa transaksi dalam satu notifikasi | Sudah diproses ulang / Abaikan |
Nomor transaksi berprefix
Setiap tagihan dan payout mendapat nomor transaksi (tx_number) dengan
format:
<PREFIX>-<YYMMDD>-<urutan> contoh: TKO-260928-0042
PREFIXdipilih per aplikasi saat membuat aplikasi, 3–4 huruf, unik di akun Anda. Dengan prefix, Anda langsung tahu transaksi itu dari produk mana.YYMMDDadalah tanggal dibuat (WIB).urutan4 digit, dimulai dari 0001 setiap hari, dan dipakai bersama oleh tagihan dan payout aplikasi yang sama.- Nomor transaksi tampil di dashboard, webhook, dan halaman bayar, dan bisa dicari di kotak pencarian dashboard.
Kode unik tidak dibagi per produk. Semua aplikasi Anda berbagi kode unik di rekening yang sama. Pembedanya adalah nomor transaksi.
Mode uji dan rekening UJI
| Mode uji | Mode live | |
|---|---|---|
| Kunci API | rk_test_… |
rk_live_… |
| Data yang dibuat | test: true |
test: false |
| Cocok dengan transfer sungguhan | Tidak pernah | Ya |
| Ditagih | Tidak | Ya |
| Butuh KYC | Tidak | Ya |
| Simulasi dana masuk/keluar | Ya, POST /api/v1/test/simulate |
Tidak |
- Kode unik data uji dan data live terpisah, jadi transfer sungguhan tidak pernah melunasi tagihan uji.
- Bila akun belum punya rekening terverifikasi, atau Anda mengirim
"bank_code": "UJI", tagihan uji memakai rekening UJI virtual: kode bankUJI, nomor0000000000, atas nama "(UJI)". Rekening UJI selalu terpantau dan payout-nya aktif. - Bila akun sudah punya rekening terverifikasi dan Anda tidak mengirim
bank_code: "UJI", tagihan uji memakai rekening sungguhan Anda sebagai tujuan, tetapi tetap berstatus data uji. - Webhook untuk data uji dikirim ke
callback_urlyang sama, dengan"test": true. Jangan memenuhi pesanan sungguhan dari event uji.
Status mutasi
Setiap notifikasi yang diterima server menjadi satu mutasi. Kolom
match_status menjelaskan apa yang terjadi:
match_status |
Arti |
|---|---|
matched |
Cocok dengan tagihan atau payout, tepat waktu (atau verifikasi pelunasan manual) |
matched_late |
Cocok, tetapi setelah kedaluwarsa atau setelah dibatalkan, dalam masa jeda |
manual_matched |
Dicocokkan manual dari dashboard |
duplicate_payment |
Uang masuk untuk tagihan yang sudah lunas |
duplicate_payout |
Uang keluar untuk payout yang sudah terkirim |
duplicate_notification |
Notifikasi kedua untuk transaksi yang sama (bank mengirim dua notifikasi). Tidak dihitung dua kali |
reversal |
Pengembalian dana untuk payout yang sudah terkirim |
no_candidate |
Tidak ada tagihan atau payout yang cocok |
ambiguous |
Cocok dengan lebih dari satu catatan. Seharusnya tidak pernah terjadi, dan tim kami diberi alarm |
parse_failed |
Kalimat notifikasi tidak dikenali |
ignored |
Bukan transaksi yang relevan: promo, pembelian, bunga, uang keluar tanpa payout aktif, atau transaksi rekening lain di app bank yang sama. Tidak tampil di API |
is_match bernilai true bila mutasi tertaut ke tagihan atau payout.