WebQRIS membaca mutasi QRIS langsung dari portal GoPay Merchant / GoBiz kamu. Tidak butuh HP menyala dan tidak butuh APK. Invoice tetap dibuat lewat POST /api/payments/qris/create seperti biasa — yang berbeda hanya siapa yang menandai invoice menjadi paid.
Urutannya empat langkah: (1) siapkan akun GoBiz, (2) daftarkan akun itu di halaman GoBiz Detector, (3) hubungkan merchant, (4) aktifkan polling. Kalau keempat langkah ini tercentang, akun siap dipakai.
Langkah 1 — Siapkan akun GoBiz (di portal GoBiz, bukan di WebQRIS)
Kalau belum punya akun GoFood Merchant, daftar dulu di https://portal.gofoodmerchant.co.id/auth/registration/corporate. Kamu akan diminta mengisi email dan password yang diinginkan.
Bisa juga masuk lewat nomor HP di https://portal.gofoodmerchant.co.id/auth/login. OTP akan dikirim ke nomor yang sudah terdaftar.
⚠️ Password dari halaman pendaftaran biasanya belum bisa dipakai untuk login email. Ini perilaku portal GoBiz, bukan kesalahan WebQRIS — jadi wajar kalau login email gagal di percobaan pertama.
Buka https://portal.gofoodmerchant.co.id/auth/login/email, masukkan email dulu. Sebelum mengisi password, klik RESET PASSWORD / ATUR ULANG PASSWORD yang ada di bawah kolom password.
Setelah password diatur ulang, login email baru bisa berhasil memakai password baru tersebut.
Email dan password hasil atur ulang itulah yang dipakai di menu Tambah Akun GoBiz di WebQRIS.
Ringkasnya: daftar → login email → Atur Ulang Password → baru password itu bisa dipakai. Kalau langkah atur ulang dilewatkan, WebQRIS akan melaporkan gagal login — dan itu bukan salah konfigurasi WebQRIS.
Langkah 2 — Daftarkan akun itu di WebQRIS
Buka dashboard → menu GoBiz Detector → bagian Tambah akun GoBiz. Isiannya:
Owner
Pemilik akun GoBiz. Satu akun GoBiz dimiliki satu owner dan kepemilikannya tidak bisa dipindahkan — kalau salah owner, buat source baru.
Nama akun/source
Label bebas untuk kamu sendiri, misalnya “GoBiz Toko A”.
Email GoBiz
Email akun GoBiz yang sudah melewati langkah 1. Harus alamat email lengkap, bukan username atau nomor HP.
Merchant ID GoBiz
ID merchant / NMID milik akun tersebut. Salah ID di sini membuat polling tetap jalan tetapi transaksi tidak pernah terbaca.
Password
Password hasil Atur Ulang Password. Boleh dikosongkan kalau memilih jalur OTP atau sudah meng-import token.
X-AppVersion
Diisi sistem, tidak perlu diubah. Ikut meniru versi aplikasi web GoBiz yang dipakai membaca transaksi.
Lookback (menit)
Seberapa jauh ke belakang transaksi dibaca setiap kali polling. Default 30 menit.
Tiga cara autentikasi (pilih salah satu)
Password
Paling sederhana. Isi email + password, lalu klik Test Login. Token disimpan dan diperbarui otomatis.
OTP
Pakai kalau akun tidak memakai password. Klik Kirim OTP, cek email GoBiz, lalu masukkan kode OTP pada form.
Import token browser
Opsi lanjutan. Tempel JSON token dari browser bila login biasa dan OTP sama-sama tidak bisa dipakai.
Langkah 3 — Hubungkan merchant, lalu aktifkan polling
Di kartu akun GoBiz, hubungkan minimal satu merchant WebQRIS milik owner tersebut.
Jalankan Test Transaksi sampai transaksi GoBiz terbaca. Kalau kosong, kemungkinan Merchant ID atau jendela lookback belum tepat.
Baru setelah itu set status Active. Tombol Active sengaja terkunci sampai login dan merchant siap.
Invoice baru tetap dibuat lewat API WebQRIS yang sama; detector menandai invoice paid begitu settlement GoBiz cocok.
Langkah 4 — Pastikan tandanya sudah benar
Akun yang sudah benar menampilkan badge Sehat dan active, dengan keempat langkah tercentang:
1. Konfigurasi
Email dan Merchant ID GoBiz sudah terisi.
2. Autentikasi
Login berhasil dan token tersimpan.
3. Hubungkan merchant
Minimal satu merchant WebQRIS terhubung.
4. Aktifkan polling
Polling berjalan dan tercatat “Polling berhasil terakhir …”.
Kalau akun GoBiz-mu sudah terverifikasi: tidak ada langkah tambahan di sisi GoBiz. Cukup hubungkan akun itu ke merchant milikmu di halaman GoBiz Detector, lalu aktifkan polling.
Kalau ada masalah
GoBiz HTTP 403
Akses ditolak. Biasanya password belum di-atur ulang (lihat langkah 1), atau akun belum punya akses merchant.
GoBiz HTTP 429
Terlalu sering menembak server GoBiz. Tunggu saja; WebQRIS otomatis memperlambat dirinya sendiri.
GoBiz HTTP 400
Permintaan tidak diterima. Cek kembali Merchant ID GoBiz.
Status transaksi ignored
Transaksi masuk tetapi tidak ada invoice terbuka dengan nominal sama. Kalau kamu yakin itu pembayaran pelanggan, pakai konfirmasi manual pada invoice yang bersangkutan.
Status transaksi conflict
Ada lebih dari satu invoice terbuka dengan nominal sama, jadi sistem tidak menebak. Selesaikan lewat panel rekonsiliasi.
Yang berubah saat merchant memakai GoBiz detector
payment_method
Menjadi gobiz_api saat invoice paid dari GoBiz detector.
issuer
Issuer QRIS seperti DANA, OVO, atau AIRPAY SHOPEE disimpan di data internal GoBiz dan dipakai untuk notifikasi WhatsApp, misalnya QRIS DANA.
matching
Invoice dicocokkan memakai total_amount unik dalam scope GoBiz Source, lalu divalidasi terhadap waktu transaksi agar transaksi lama tidak menempel ke QRIS baru.
APK callback
/api/webhook/payment dan /api/callback/notify akan mengembalikan ignored: true untuk merchant yang sudah memakai GoBiz detector aktif.
webhook outbound
Tetap memakai event payment.paid dan signature HMAC yang sama seperti jalur APK/callback.
Transparansi: integrasi ini membaca dashboard/portal merchant GoBiz. WebQRIS tetap bukan payment gateway dan tidak menampung dana. Untuk jalur resmi penuh berbasis order ID, merchant dapat memakai GoBiz Open API/Midtrans bila sudah memiliki akses resmi.
INFOPersiapan Integrasi — 4 nilai yang harus disiapkan
Keempat nilai ini yang menyambungkan sistem kamu dengan WebQRIS. Nilai aslinya ada di dashboard pada halaman Merchant Detail merchant yang bersangkutan: Webhook URL, Webhook Secret, dan TOKEN bisa disalin dari sana. API Endpoint selalu sama untuk semua merchant.
1. Webhook URL
URL di sistem kamu sendiri yang menerima notifikasi pembayaran. Isi di halaman Merchant Detail. Contoh: https://domain.com/webhook/qrispayment
2. Webhook Secret
Kunci untuk membuktikan notifikasi benar-benar datang dari WebQRIS, dipakai menghitung HMAC-SHA256. Bentuknya berawalan wh_. Contoh: wh_••••••••••••••••••••••••••••••••
3. API Endpoint
Alamat untuk membuat invoice QRIS. POST https://webqris.com/api/payments/qris/create
4. TOKEN
API token milik merchant, dipasang sebagai Authorization: Bearer <TOKEN>. Bentuknya {id}|{random}. Contoh: xx|••••••••••••••••••••••••••••••••••••••••
Jangan tertukar arahnya.Webhook URL dan Webhook Secret adalah milik kamu — WebQRIS yang mengirim ke sana. API Endpoint dan TOKEN adalah milik WebQRIS — kamu yang mengirim ke sana.
Alur komunikasi lewat webhook
1
Siapkan satu endpoint di sistem kamu yang menerima POST berisi JSON. Pastikan tidak butuh login/cookie, karena yang memanggil adalah server WebQRIS.
2
Isi Webhook URL dan Webhook Secret di halaman Merchant Detail. Selama Webhook URL kosong, notifikasi tidak bisa dikirim dan job-nya berakhir gagal.
3
Saat invoice berubah menjadi paid, WebQRIS mengirim POST event payment.paid ke URL itu, dengan header X-Webhook-Signature.
4
Sistem kamu menghitung HMAC-SHA256 dari body mentah memakai Webhook Secret, lalu membandingkannya dengan header tersebut. Bandingkan dengan perbandingan waktu-tetap (hash_equals / timingSafeEqual).
5
Balas 2xx kalau sudah diproses. Selain 2xx dianggap gagal dan WebQRIS mengulang otomatis — lihat kebijakan retry di bagian Webhook Outbound.
6
Pakai invoice_id sebagai kunci idempotensi, karena percobaan ulang mengirim body yang sama.
Webhook itu opsional tapi disarankan. Tanpa Webhook URL, integrasi tetap jalan — kamu hanya perlu memeriksa status invoice sendiri lewat GET /api/payments/:invoiceId/status.
Ringkasan Integrasi
Aplikasi merchant / backend Anda
Panggil POST /api/payments/qris/create dan GET /api/payments/:invoiceId/status dengan Authorization: Bearer YOUR_API_TOKEN.
Server Anda menerima notifikasi dari WebQRIS
Set Webhook URL di merchant detail. Itu adalah endpoint milik sistem Anda sendiri. WebQRIS akan POST ke sana saat pembayaran sukses.
APK / forwarder mengirim notifikasi ke WebQRIS
Pakai POST /api/webhook/payment atau POST /api/callback/notify dengan Callback Secret. Dua endpoint ini adalah endpoint milik WebQRIS.
GoBiz detector server-side
Untuk merchant GoPay Merchant / GoBiz, WebQRIS dapat membaca transaksi QRIS dari GoBiz source yang terhubung. Callback APK otomatis diabaikan pada merchant yang memakai GoBiz detector aktif agar tidak double paid.
Aturan cepat agar tidak tertukar:API Token untuk backend merchant membuat invoice, Webhook URL adalah URL tujuan di server Anda, dan Callback Secret untuk autentikasi notif masuk ke WebQRIS.
Quick Start
Buat merchant di dashboard, lalu generate minimal satu API Token.
Jika ingin sistem Anda menerima status bayar otomatis, isi Webhook URL di merchant detail.
Dari backend merchant Anda, panggil POST /api/payments/qris/create untuk membuat invoice dan tampilkan QR ke pelanggan.
Jika Anda memakai APK Notification Forwarder, arahkan APK ke POST /api/webhook/payment dan isi Callback Secret.
Jika memakai GoBiz detector, hubungkan GoBiz Source di halaman merchant. Webhook outbound ke sistem Anda tetap memakai format payment.paid yang sama.
Setelah payment sukses, WebQRIS akan mengirim webhook outbound ke Webhook URL Anda. Poll status via API hanya opsional.
Istilah Penting
API Token
Kredensial untuk backend merchant Anda saat membuat invoice QRIS dan cek status via API.
Webhook URL
URL tujuan di server Anda sendiri. WebQRIS akan mengirim notifikasi pembayaran sukses ke URL ini.
Callback Secret
Secret untuk autentikasi notif masuk ke WebQRIS dari APK atau forwarder lain.
GoBiz Source
Koneksi akun GoPay Merchant / GoBiz yang dipakai WebQRIS untuk membaca settlement QRIS secara server-side.
payment_method: gobiz_api
Status pembayaran berasal dari GoBiz detector. Nama issuer e-wallet seperti DANA, OVO, atau SHOPEEPAY disimpan dari data GoBiz dan dipakai pada notifikasi WhatsApp.
Invoice ID
ID transaksi dari WebQRIS. Dipakai untuk cek status pembayaran.
merchant_order_id
ID order dari sistem Anda sendiri. Optional, tapi disarankan agar transaksi mudah dicocokkan.
POST/api/payments/qris/create
Buat transaksi QRIS baru. Akan mengembalikan QRIS payload yang bisa di-generate menjadi QR code.
Gunakan endpoint ini dari aplikasi merchant/server untuk membuat invoice QRIS. Pakai bersama header Authorization: Bearer YOUR_API_TOKEN. Ini bukan URL untuk APK Notification Forwarder dan bukan webhook outbound ke sistem Anda.
amount kosong, nol, negatif, atau melebihi batas maksimum Rp 50.000.000.
401
Header Authorization tidak ada, bukan format Bearer …, token sudah di-revoke, atau merchant tidak aktif.
402
Saldo pemilik merchant tidak cukup untuk menutup fee transaksi (setelah kuota gratis harian habis). Isi saldo lewat menu Top-Up, atau minta admin menandai akun sebagai exempt.
404
Invoice tidak ditemukan, atau invoice itu milik merchant lain sehingga tidak terlihat oleh token yang dipakai.
503
QRIS template merchant belum diatur, atau seluruh kode unik (1–36) sedang terpakai oleh invoice yang belum selesai.
Perhatikan sebelum retry. Setiap panggilan yang berhasil selalu melahirkan invoice baru — belum ada kunci idempotensi, dan merchant_order_id tidak dijamin unik. Jadi kalau request timeout lalu kamu ulangi panggilan yang sama, akan ada dua invoice berbeda (kode uniknya pun berbeda). Simpan invoice_id dari respons, dan sebelum membuat ulang pastikan dulu lewat GET /api/payments/:invoiceId/status atau dashboard.
Catatan payment_method: nilai gobiz_api berarti pembayaran diproses oleh GoBiz detector. Untuk jalur APK lama, nilainya bisa berupa package aplikasi sumber notifikasi seperti com.dana.id atau com.gojek.gopaymerchant.
Field waktu API memakai ISO timestamp. Tampilan WIB dipakai di dashboard dan notifikasi WhatsApp.
Kalau gagal
401
Header Authorization tidak ada atau token tidak valid.
404
Invoice tidak ditemukan — bisa karena salah invoice_id, atau invoice itu milik merchant lain sehingga tidak terlihat oleh token yang dipakai.
<?php
namespace AppHttpControllers;
use IlluminateSupportFacadesHttp;
class WebqrisStatusController extends Controller
{
public function show(string $invoiceId)
{
$response = Http::withToken(config('services.webqris.token'))
->get(config('services.webqris.base_url') . '/api/payments/' . $invoiceId . '/status');
return response()->json($response->json(), $response->status());
}
}
CodeIgniter 4
<?php
namespace AppControllers;
use CodeIgniterHTTPResponseInterface;
use ConfigServices;
class WebqrisStatusController extends BaseController
{
public function show(string $invoiceId): ResponseInterface
{
$client = Services::curlrequest();
$response = $client->get(env('webqris.baseUrl') . '/api/payments/' . $invoiceId . '/status', [
'headers' => [
'Authorization' => 'Bearer ' . env('webqris.apiToken'),
],
]);
return $this->response
->setStatusCode($response->getStatusCode())
->setJSON(json_decode($response->getBody(), true));
}
}
POSTYOUR_WEBHOOK_URL
WebQRIS akan mengirim webhook ke URL yang Anda konfigurasi saat pembayaran berhasil. Ini adalah endpoint milik sistem Anda sendiri, bukan endpoint milik WebQRIS.
Headers
X-Webhook-Signature
HMAC-SHA256 signature dari body dengan webhook_secret
X-Signature
Sama dengan di atas (legacy header, untuk backward compatibility)
Webhook outbound memakai format yang sama untuk semua sumber paid: APK Notification Forwarder, callback sederhana, manual confirm, maupun GoBiz detector. Pada GoBiz detector, payment_method bernilai gobiz_api.
Retry Policy
Webhook dikirim lewat antrian permanen (webhook_jobs): job yang belum berhasil tetap tersimpan dan dicoba ulang walau server WebQRIS sempat restart. Percobaan dicatat di webhook_logs.
Satu invoice hanya menghasilkan satu job webhook, jadi kalau kamu menerima payload yang sama dua kali itu memang percobaan ulang — pakai invoice_id sebagai kunci idempotensi di sisi kamu.
Endpoint milik WebQRIS untuk menerima notifikasi e-wallet yang di-forward dari APK Notification Forwarder. Server akan mem-parse nominal dari field message, mencari payment pending dengan total_amount yang sama (per-merchant), lalu mengubah status menjadi paid dan mengirim webhook outbound ke sistem merchant (jika dikonfigurasi).
Jika merchant sudah terhubung ke GoBiz detector aktif, endpoint ini sengaja mengabaikan notifikasi APK agar satu pembayaran tidak diproses dua jalur.
Headers
Authorization
Bearer <CALLBACK_SECRET>
Required
Content-Type
application/json
Request Body (contoh)
{
"app": "com.dana.id",
"title": "DANA",
"message": "Kamu berhasil menerima Rp25.042 dari JOHN DOE",
"timestamp": "2026-03-21T10:15:23.000Z",
"device_id": "device-01",
"notif_id": "1234567890",
"event_hash": "..."
}
Parameter
message
string
Teks notifikasi. Nominal diparse dari sini, jadi bagian inilah yang harus benar.
Required
app
string
Nama paket aplikasi sumber, misalnya com.dana.id. Dipakai menyaring notifikasi yang bukan pembayaran masuk.
Optional
title
string
Judul notifikasi. Diperiksa bersama message.
Optional
channel_id
string
ID kanal notifikasi dari APK.
Optional
timestamp
string
Waktu notifikasi menurut perangkat pengirim.
Optional
device_id
string
Penanda perangkat pengirim, berguna untuk penelusuran.
Optional
notif_id
string
ID notifikasi. Dipakai mencegah notifikasi yang sama diproses dua kali.
Disarankan
event_hash
string
Penanda unik event dari APK. Nilai test dipakai untuk uji koneksi.
Optional
debug_gopay
object
Data tambahan untuk penelusuran notifikasi GoPay.
Optional
Respons
200
Berhasil diproses, atau sengaja diabaikan — perhatikan penanda ignored dan reason pada body respons.
400
Body bukan JSON yang valid, atau message tidak ada.
401
Token tidak dikenal, atau merchant tidak aktif.
422
Nominal tidak berhasil dibaca dari message.
404
Tidak ada invoice pending dengan total_amount yang sama pada merchant tersebut.
Test Koneksi
Untuk test auth & koneksi tanpa memproses pembayaran, kirim event_hash bernilai test.
Endpoint milik WebQRIS dengan format sederhana untuk menandai payment sebagai paid berdasarkan nominal amount (harus sama dengan total_amount). Cocok untuk integrasi non-APK.
Jika merchant sudah memakai GoBiz detector aktif, callback sederhana ini juga diabaikan. Sumber paid yang dipakai adalah settlement GoBiz agar tidak ada double processing.
WebSocket untuk menerima event realtime. /ws untuk dashboard dengan session login aktif, /ws/user untuk user dengan session login aktif, dan /ws/merchant untuk merchant-specific dengan API token pada query param token.
Authentication:/ws dan /ws/user menggunakan session cookie same-origin dari login WebQRIS. Koneksi tanpa session aktif ditolak dengan HTTP 401. /ws/merchant menggunakan token=API_TOKEN dan juga akan ditolak dengan 401 jika token tidak valid.
Event scope: koneksi dashboard dengan role admin atau superadmin menerima event global. Role client dan operator hanya menerima event untuk owner yang sama. /ws/user adalah channel user dan tidak diperlakukan sebagai viewer dashboard.
Event dan channel-nya
Event
Dikirim ke
Keterangan
payment_paid
/ws, /ws/merchant
Pembayaran berhasil (dari APK, callback, GoBiz detector, atau konfirmasi manual). Satu-satunya event yang juga dikirim ke /ws/merchant.
new_payment
/ws
Invoice baru dibuat.
payments_expired
/ws
Invoice melewati batas waktu (diproses berkala, setiap 60 detik).
payment_deleted
/ws
Invoice dihapus — baik dibersihkan otomatis setelah masa tenggang, maupun dihapus manual.
webhook_delivered
/ws
Webhook outbound berhasil terkirim ke sistem merchant.
merchant_changed
/ws
Data merchant berubah (dibuat, diubah, atau dihapus).
Kalau integrasi kamu hanya butuh realtime pembayaran: pakai /ws/merchant?token=API_TOKEN dan tunggu event payment_paid. Event dashboard lainnya (new_payment, payment_deleted, dan seterusnya) tidak dikirim ke channel merchant.
Kirim pesan ping → server membalas pong. Gunakan untuk keep-alive.
Callback settlement
Transisi payment menjadi paid dan settlement saldo diproses secara atomik. Callback yang dikirim bersamaan untuk invoice yang sama hanya boleh menghasilkan satu settlement dan satu rangkaian event; callback yang kalah race dapat menerima acknowledgement sukses tanpa membuat kredit atau fee kedua.
Unauthorized — token tidak valid, tidak ada, atau merchant tidak aktif.
402
Payment Required — saldo pemilik merchant tidak cukup untuk menutup fee transaksi (setelah kuota gratis harian habis). Isi saldo lewat menu Top-Up, atau minta admin menandai akun sebagai exempt.
404
Not Found — resource tidak ditemukan, atau milik merchant lain sehingga tidak terlihat oleh token yang dipakai.
422
Unprocessable — gagal memproses data (contoh: nominal tidak terdeteksi dari notifikasi).
500
Internal Server Error.
503
Service Unavailable — QRIS belum dikonfigurasi, atau seluruh kode unik (1–36) sedang terpakai.
Alur Integrasi
Register & login ke WebQRIS Dashboard
Buat Merchant dan generate API Token
Set Webhook URL untuk menerima notifikasi pembayaran
Pilih sumber deteksi pembayaran: APK Notification Forwarder, callback sederhana, atau GoBiz detector server-side.
Kirim request POST /api/payments/qris/create dari backend Anda
Tampilkan QR Code dari qris_payload ke pelanggan
Jika memakai APK / notif forwarder, kirim notifikasi masuk ke endpoint WebQRIS: POST /api/webhook/payment atau POST /api/callback/notify
Jika memakai GoBiz detector, hubungkan GoBiz Source di dashboard merchant. Untuk merchant tersebut, callback APK akan diabaikan dan settlement GoBiz menjadi sumber paid.
Poll status via GET /api/payments/:invoiceId/status (opsional)
Terima webhook outbound dari WebQRIS di Webhook URL milik sistem Anda saat status menjadi paid