Integrasi Mobile•QRIS
Bayar QRIS dari Native
Native memindai QR, melakukan inquiry, dan menentukan nominal sendiri. WebView /payment/qris hanya meminta PIN lalu mengeksekusi pembayaran. Ada dua cara membayar QRIS; pilih sesuai kebutuhan.
1. Pilih Cara Pembayaran
| Cara | Rute WebView | Siapa yang inquiry & nominal |
|---|---|---|
| A. Scan di native, inquiry di WebView | /qris?qrString=<QR> | WebView melakukan inquiry baru setiap dibuka (tidak memakai cache inquiry lama), menampilkan merchant dan kolom nominal (bila QR statis), lalu PIN. |
| B. Native inquiry & nominal sendiri (halaman ini) | /payment/qris | Native memakai GETINQUIRYQRIS, menentukan nominal, lalu WebView hanya PIN. |
| C. Scanner di dalam WebView | /qoincash/qris | WebView memindai dengan kamera (butuh izin kamera, lihat Izin Perangkat). |
Rute QRIS yang dipindahkan
Layar scanner dan pembayaran QRIS di WebView kini berada di
/qoincash/qris (sebelumnya /payment/qris). Rute /payment/qris sekarang dipakai untuk cara B di bawah.2. Alur Cara B
- Native memindai QR, lalu memanggil
GETINQUIRYQRISdi/native/messagedan menerima data inquiry. - Native menentukan nominal akhir:
Amountdari QR dinamis, atau yang diisi user untuk QR statis. - Native membuka WebView (terlihat) ke
{BASE_URL}/payment/qris. - Native mengirim data lewat
postMessage(kirim ulang tiap ±500 ms, maksimal ±15 detik) dalam format di bawah. - WebView menampilkan layar PIN dengan nama merchant dan nominal. User mengetik PIN di dalam WebView.
- WebView mengeksekusi pembayaran dan mengirim hasilnya ke native.
Pesan ke /payment/qris (tanpa type, bukan query URL)
window.postMessage(JSON.stringify({
PaymentId: "PAY000000014102",
ReferenceNumber: "310100000005639",
AccountName: "Buket Speak Up You Wish,",
Amount: "1000", // nominal akhir (rupiah)
TipAmount: "0", // opsional, default 0
TerminalId: "G055035934",
TicketId: "253b8a1a-5a0f-4ba8-b785-c65f36518461",
inquiryToken: "<token>" // dari data.inquiryToken GETINQUIRYQRIS, teruskan apa adanya
}), "*");Kamus Parameter Pesan
| Parameter | Tipe Data | Status | Deskripsi & Contoh |
|---|---|---|---|
| PaymentId | string | Wajib | Dari hasil GETINQUIRYQRIS. 1–64 karakter: huruf, angka, titik, garis bawah, atau tanda hubung. |
| ReferenceNumber | string | Wajib | Dari hasil GETINQUIRYQRIS. Aturan karakter sama seperti PaymentId. |
| Amount | string | number | Wajib | Nominal akhir, bilangan bulat rupiah dari 1 sampai 100.000.000. Contoh: "1000" |
| AccountName | string | Opsional | Nama merchant untuk ditampilkan di layar PIN. Maksimal 100 karakter. |
| TipAmount | string | number | Opsional | Tip, bilangan bulat ≥ 0. Default 0. Layar PIN menampilkan tip dan total bila > 0. |
| TerminalId | string | Opsional | Dari hasil GETINQUIRYQRIS. Default "123" bila kosong. |
| TicketId | string | Opsional | Dari hasil GETINQUIRYQRIS. Boleh kosong. |
| inquiryToken | string | Opsional | Dari data.inquiryToken GETINQUIRYQRIS, diteruskan apa adanya. Server memakai token ini untuk memastikan PaymentId/ReferenceNumber/merchant sesuai inquiry dan, untuk QR dinamis, nominal tidak bisa diubah. Saat ini opsional; akan menjadi WAJIB (pembayaran tanpa token ditolak) setelah diumumkan. |
Aturan penerimaan pesan
Pesan lain (misalnya
{Signature, Palette}) diabaikan. Pesan pembayaran dipakai sekali; pesan berikutnya diabaikan. Data yang tidak valid atau tidak datang dalam ±15 detik menampilkan layar Transaksi Gagal.3. Hasil yang Diterima Native
Event dari WebView
| Parameter | Tipe Data | Status | Deskripsi & Contoh |
|---|---|---|---|
| { STATUS: "TRUE", FOR: "QRIS" } | object | Opsional | Pembayaran berhasil (layar sukses tampil). Lalu { close: true, STATUS: "TRUE", FOR: "QRIS" } saat user menekan Selesai. |
| { STATUS: "FALSE", FOR: "QRIS", MESSAGE } | object | Opsional | Gagal, termasuk data tidak valid, tidak diterima, atau inquiry kedaluwarsa. Lalu { close: true, STATUS: "FALSE", FOR: "QRIS" } saat user menekan Tutup. |
| { close: true, FOR: "QRIS" } | object | Opsional | Tanpa STATUS: user menekan tombol kembali di layar PIN (dibatalkan), atau hasil masih diproses. Jangan dicatat sebagai sukses atau gagal. |
- Sesi habis saat membayar: WebView meminta PIN login lebih dulu. Setelah kembali, data pesan tidak ada lagi, jadi native perlu mengirim ulang.
- Inquiry kedaluwarsa: pembayaran ditolak dan layar gagal menampilkan pesannya. Lakukan scan dan inquiry ulang.
- Hasil diproses/tidak pasti: jangan mengulang pembayaran. Cek riwayat transaksi sebelum mencoba lagi.
PIN tidak pernah lewat postMessage
PIN hanya diketik di dalam WebView dan dikirim langsung ke server QoinCash. Native tidak pernah menerima atau mengirim PIN.