Hubungkan QRISGate ke website Andadalam 30 menit
Panduan langkah demi langkah untuk menerima QRIS dan transfer bank otomatis di toko online Anda. Tidak perlu kontrak payment gateway, tidak perlu tim IT khusus.
Bagaimana alurnya?
Enam langkah dari checkout pembeli sampai pesanan Anda lunas.
Pembeli checkout
Di website Anda, pembeli klik "Bayar".
Server Anda → API
Backend memanggil POST /api/v1/transactions.
Halaman bayar
Pembeli melihat QRIS atau nomor rekening.
Pembeli bayar
Scan QRIS atau transfer nominal tepat.
Mutasi terdeteksi
Listener membaca notifikasi masuk di HP.
Lunas otomatis
Status PAID + webhook dikirim ke server Anda.
Inti sistemnya: setiap transaksi diberi 3 digit kode unik, jadi nominalnya menjadi unik (mis. Rp 150.247). Saat mutasi masuk dengan nominal itu, sistem tahu persis pesanan mana yang harus dilunasi — tanpa perlu API bank.
Daftar & ambil API Key
sekali saja · ± 2 menitBuat akun, verifikasi email, lalu buka Dashboard dan salin Live API Key. Kunci ini hanya ditampilkan sekali — simpan di server, jangan pernah di kode frontend.
Daftar sekarangTidak ingin menulis kode sendiri? Di Dashboard → Pasang di Website / Toko sudah tersedia prompt siap pakai untuk Cursor, Claude Code, Codex, atau ChatGPT. AI Anda yang akan menulis endpoint checkout, verifikasi webhook, dan halaman status pesanan.
Buka DashboardLangkah demi langkah
Empat langkah setelah persiapan. Total waktu ± 28 menit.
Pasang sumber pembayaran
± 3 menitUntuk QRIS: unggah gambar Static QRIS toko Anda di Dashboard. Untuk transfer bank: tambahkan nomor rekening di menu Rekening. Bisa keduanya sekaligus.
Buka DashboardAktifkan kanal deteksi mutasi
± 5 menitPasang aplikasi Android QRISGate Listener di HP yang menerima notifikasi mutasi, atau hubungkan Moota/Cekmutasi. Tanpa kanal ini, pembayaran tidak akan terdeteksi otomatis.
Unduh APKBuat transaksi dari server
± 10 menitPanggil POST /api/v1/transactions dari backend Anda saat pembeli checkout. Simpan checkout_url yang dikembalikan, lalu arahkan pembeli ke halaman itu.
Lihat contoh kodeTerima notifikasi pembayaran
± 10 menitSet URL webhook di Dashboard. QRISGate mengirim POST bertanda tangan HMAC saat pembayaran lunas, jadi sistem Anda tidak perlu polling.
Cara verifikasiKode integrasi
Pilih bahasa yang Anda pakai. Semua contoh membuat satu transaksi lalu mengarahkan pembeli ke halaman pembayaran.
// Node.js 18+ (fetch sudah built-in)
const res = await fetch("https://qriskan.vercel.app/api/v1/transactions", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.QRISGATE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
external_order_id: "INV-2026-001", // ID unik pesanan Anda
amount: 150000, // nominal dasar (Rp)
customer_name: "Budi Santoso",
payment_method: "QRIS", // atau "BANK_TRANSFER"
}),
});
const json = await res.json();
if (!res.ok) throw new Error(json.error);
// Simpan checkout_url, lalu arahkan pembeli ke sana
console.log(json.data.checkout_url);Parameter yang dikirim
| Field | Wajib | Keterangan |
|---|---|---|
| external_order_id | Ya | ID pesanan unik dari sistem Anda (idempoten) |
| amount | Ya | Nominal dasar dalam Rupiah, minimal Rp 5.000 |
| payment_method | Tidak | "QRIS" (default) atau "BANK_TRANSFER" |
| bank_code | Tidak | Pilih rekening tertentu untuk BANK_TRANSFER (mis. "BCA"). Kosong = rekening aktif pertama |
| customer_name | Tidak | Nama pembeli, tampil di halaman pembayaran |
| return_url | Tidak | Halaman tujuan setelah pembeli selesai membayar |
Contoh respons sukses
{
"success": true,
"data": {
"transaction_id": "trx_9f2c1a...",
"external_order_id": "INV-2026-001",
"payment_method": "QRIS",
"base_amount": 150000,
"unique_code": 247,
"total_amount": 150247,
"status": "PENDING",
"qr_string": "00020101021226...",
"qr_image_base64": "data:image/png;base64,iVBOR...",
"bank_transfer": null,
"checkout_url": "https://qriskan.vercel.app/pay/trx_9f2c1a...",
"expires_at": "2026-10-23T09:15:00.000Z"
}
}Arahkan pembeli ke checkout_url — halaman itu sudah menampilkan QRIS atau nomor rekening, countdown, dan berubah otomatis saat lunas. Anda juga bisa memakai qr_image_base64 langsung di halaman checkout Anda sendiri.
Dua metode pembayaran
Pilih per transaksi lewat field payment_method.
QRIS
DEFAULTPembeli scan satu QR dengan aplikasi apa pun — GoPay, OVO, DANA, ShopeePay, LinkAja, atau m-Banking.
- Butuh Static QRIS toko di Dashboard
- Dana masuk ke rekening QRIS Anda
- Paling cepat untuk pembeli
Transfer Bank
Pembeli transfer ke rekening bank Anda dengan nominal tepat. Cocok untuk nominal besar atau pembeli yang tidak memakai e-wallet.
- Butuh rekening terdaftar di menu Rekening
- BCA, Mandiri, BRI, BNI, dan 12 bank lain
- Nominal harus tepat, tidak boleh dibulatkan
GoPay hanya mendukung QRIS statis: nominal harus diketik manual oleh pembeli.
Aplikasi GoPay Merchant hanya mengirim notifikasi ke penjual untuk pembayaran QRIS statis. Jika QR memuat nominal (QRIS dinamis), GoPay menganggapnya sebagai transaksi yang belum diaktifkan untuk akun tersebut dan notifikasi tidak pernah muncul — pesanan akan tertahan di status Menunggu. Karena itu, untuk merchant GoPay QRISGate selalu menampilkan QRIS statis dan pembeli mengetik nominal sendiri. Nominal tersebut sudah termasuk kode unik, jadi pastikan pembeli mengetiknya persis. DANA dan kanal lain tetap memakai QRIS dinamis bernominal terkunci.
Contoh: transaksi transfer bank
{
"external_order_id": "INV-2026-002",
"amount": 500000,
"payment_method": "BANK_TRANSFER",
"bank_code": "BCA"
}Notifikasi otomatis (webhook)
Supaya sistem Anda tahu pesanan sudah lunas tanpa polling, set URL webhook di Dashboard. Setiap kiriman ditandatangani HMAC-SHA256.
X-QRISGate-Event
payment.paid | payment.expired | payment.cancelled
X-QRISGate-Timestamp
Unix timestamp pengiriman (detik)
X-QRISGate-Signature
HMAC-SHA256 dari timestamp.payload
X-QRISGate-Delivery-Id
Sama untuk setiap retry event ini — kunci idempotensi
X-QRISGate-Attempt
Percobaan pengiriman ke-berapa
Content-Type
application/json
{
"event": "payment.paid",
"transaction_id": "trx_8f2c4b1a05c67e1f7294b3d0",
"external_order_id": "INV-1042",
"base_amount": 150000,
"unique_code": 247,
"total_amount": 150247,
"customer_name": "Budi",
"paid_at": "2026-10-24T09:15:22.000Z",
"created_at": "2026-10-24T09:12:40.000Z"
}<?php
// webhook.php — terima notifikasi pembayaran dari QRISGate
$raw = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_QRISGATE_SIGNATURE'] ?? '';
$timestamp = $_SERVER['HTTP_X_QRISGATE_TIMESTAMP'] ?? '';
// 1. Tolak replay di luar 5 menit
if (abs(time() - (int) $timestamp) > 300) {
http_response_code(400);
exit('Stale timestamp');
}
// 2. Verifikasi HMAC-SHA256
$expected = hash_hmac('sha256', $timestamp . '.' . $raw, getenv('QRISGATE_WEBHOOK_SECRET'));
if (!hash_equals($expected, $signature)) {
http_response_code(401);
exit('Invalid signature');
}
// 3. Proses event — payload-nya FLAT, tidak ada wrapper `data`.
$event = json_decode($raw, true);
if ($event['event'] === 'payment.paid') {
$orderId = $event['external_order_id'];
// TODO: update pesanan Anda menjadi LUNAS
// Wajib idempoten — event yang sama bisa dikirim ulang.
// Gunakan X-QRISGate-Delivery-Id untuk membedakan pengiriman ulang.
}
http_response_code(200);
echo 'OK';Wajib idempoten. Event yang sama bisa dikirim lebih dari sekali (retry). Kunci idempotensi paling aman adalah external_order_id — jangan menambah stok atau saldo dua kali untuk ID yang sama.
Alternatif: cek status manual
Kalau belum siap menerima webhook, polling endpoint status juga bisa.
// Cek status transaksi (polling, tanpa webhook)
const res = await fetch("https://qriskan.vercel.app/api/v1/transactions/trx_abc123");
const { data } = await res.json();
if (data.status === "PAID") {
// pembayaran sudah lunas
}Checklist sebelum go-live
Pertanyaan umum
Biaya layanan sama dengan kode unik pesanan, antara Rp 100 sampai Rp 999. Kode itu sudah termasuk pada nominal yang dibayar pembeli, jadi uang yang masuk ke rekening Anda tetap sebesar harga jual. Besaran pastinya diacak di dalam rentang itu agar dua pesanan bernominal sama tidak bertabrakan. Tidak ada biaya bulanan dan tidak ada potongan persentase.
Tidak. Cukup unggah Static QRIS toko Anda sekali. QRISGate yang menyuntikkan nominal + kode unik ke payload EMVCo sehingga setiap transaksi punya QR sendiri.
Transaksi tidak akan terdeteksi otomatis karena pencocokan memakai nominal tepat termasuk 3 digit kode unik. Dana tetap masuk ke rekening Anda, dan Anda bisa menyelesaikannya manual lewat tombol konfirmasi di dashboard.
Tidak. Pembayaran QRIS maupun transfer bank masuk langsung ke rekening merchant. QRISGate hanya membaca mutasi untuk mencocokkan status pesanan.
Biasanya kanal mutasi belum aktif atau HP-nya di-freeze sistem (Samsung Freecess). Pastikan aplikasi Listener sudah punya akses notifikasi, sudah di-bypass battery optimization, dan Anda sudah masuk dengan akun yang benar di aplikasi.
Bisa. Tentukan per transaksi lewat field payment_method: "QRIS" atau "BANK_TRANSFER". Kalau tidak diisi, default-nya QRIS.
Siap menerima pembayaran?
Daftar gratis, dapat saldo awal Rp 5.000 untuk menutup biaya transaksi pertama Anda.