Konsep inti
Kode unik, status payment, mode uji dan live, serta idempotensi: istilah yang dipakai di semua halaman docs.
QRIS statis dan dinamis
Kamu mengunggah QRIS statis milik usahamu satu kali. Untuk setiap payment, FQris membuat QRIS dinamis dari QRIS itu: nominalnya sudah terisi, jadi pembeli tidak bisa salah ketik.
FQris tidak memegang uang. Pembeli membayar langsung ke QRIS-mu, dan FQris hanya mencatat serta mengonfirmasi pembayarannya.
Kode unik dan final_amount
Notifikasi uang masuk hanya memuat nominal. Supaya dua pembeli tidak bisa tertukar, FQris menambahkan kode unik acak (rentang bawaan 1–499) ke amount (nominal dasar). Hasilnya final_amount, nominal yang harus dibayar pembeli. Contoh: amount 20000 + unique_code 137 = final_amount 20137.
Satu final_amount hanya dipegang satu payment selama payment itu aktif, ditambah masa tenggang setelah expires_at (bawaan 30 menit). Slot tidak dilepas lebih awal, bahkan setelah paid atau cancelled. Kalau semua kode untuk nominal itu sedang terpakai, API membalas 409 NO_AVAILABLE_SLOT.
Deteksi lewat Listener
FQris Listener adalah aplikasi Android di HP yang sama dengan aplikasi QRIS-mu (tahap awal: DANA Bisnis). Ia membaca notifikasi uang masuk dan mengirimkannya ke server. Listener tidak mencocokkan pembayaran dan tidak memutuskan status.
Server yang mencocokkan. Kalau nominal notifikasi sama dengan final_amount tepat satu payment yang masih pending (atau expired dan cancelled yang masih di masa tenggang), payment itu menjadi paid. Kalau tidak ada yang cocok, notifikasi masuk antrean Rekonsiliasi di dashboard.
Owner atau Staff juga bisa menandai payment lunas secara manual dari dashboard, misalnya untuk pembayaran yang tidak terdeteksi.
Status payment
- 1pending Menunggu pembayaran, QR aktif. Berakhir di
expires_at: bawaan 15 menit (bisa diubah per project), atau atur 5–60 menit lewatexpiry_minutes. - 2paid Pembayaran terkonfirmasi.
confirmation_methodmencatat caranya:auto_listener,manual, atausandbox_simulation. - 3expired Lewat
expires_attanpa pembayaran. Masih bisa menjadipaidselama masa tenggang. - 4cancelled Dibatalkan lewat API atau dashboard, hanya dari
pending. Masih bisa menjadipaidselama masa tenggang. - 5partially_refunded, refunded Refund dicatat dari payment
paid. FQris hanya mencatat; uangnya kamu kembalikan sendiri ke pembeli.
Pembayaran terlambat dan reversal
- 1paid_late Bukan status, melainkan flag. Payment berstatus
paiddenganpaid_late: truebila dibayar setelahexpires_at. Pesananmu mungkin sudah kamu batalkan. - 2paid_after_cancel Flag untuk payment yang dibayar setelah dibatalkan. Statusnya tetap
paid. - 3payment.reversed Owner membatalkan konfirmasi manual dalam 24 jam. Status kembali ke
pendingbila belum lewatexpires_at, keexpiredbila sudah, atau kecancelledbila tadinya dibayar setelah dibatalkan atau dibuat retroaktif dari Rekonsiliasi. Tarik kembali apa pun yang sudah kamu kredit.
Mode uji dan live
Setiap project punya dua set API key. Key fq_test_… bekerja di mode uji, key fq_live_… di mode live, masing-masing diikuti 32 karakter acak. Mode ditentukan oleh key, dan data kedua mode terpisah total. Key penuh hanya ditampilkan sekali saat dibuat.
Mode uji tidak memerlukan Listener atau QRIS terverifikasi. Cara mengujinya ada di halaman Sandbox.
Idempotensi
Kirim header Idempotency-Key (maksimal 255 karakter) di setiap POST. Key disimpan 24 jam per API key. Request ulang dengan key dan body yang sama mengembalikan respons yang sama persis. Key yang sama untuk request berbeda dijawab 409 IDEMPOTENCY_KEY_REUSED.
Request yang ditolak karena validasi atau aturan bisnis membebaskan key, jadi kamu boleh mencoba lagi dengan key yang sama. Key kosong atau lebih dari 255 karakter dijawab 400 INVALID_PARAMETER.
Untuk pesananmu sendiri, pakai reference_id: unik per project dan mode. Memakainya lagi dijawab 409 DUPLICATE_REFERENCE. Bila payment lama masih pending, error.payment membawa id dan statusnya (dikirim server, belum tercatat di skema OpenAPI).