Skip to content

Introduction

qris-gateway is a multi-tenant QRIS dynamic payment gateway: generate a dynamic QRIS with a fixed amount, track its payment status, and get notified when it’s paid — without depending on any single payment app’s official API.

Every tenant (merchant) has its own live and sandbox API key; the key resolves both the tenant and the mode for every request, and every response is scoped to that tenant (see Authentication).

  • Register a merchant’s static QRIS (image or raw string) and generate a dynamic, fixed-amount QRIS from it — see QRIS Codes and Transactions.
  • Track a transaction’s status (unpaidpaid/expired) and get a signed webhook the moment it’s paid — see Webhooks.
  • Exercise the full paid flow in sandbox without a real payment, via simulate-payment.

This gateway does not call a payment provider’s API to confirm payment. Confirmation comes from a device-side app listener — a client that reads payment app notifications (DANA, GoPay Merchant, etc.) on the merchant’s phone and forwards the parsed amount to this gateway’s inbound webhook. See App Listener for how that client is set up, and Webhooks for the inbound contract it calls.

Payment app notification (DANA, GoPay Merchant, ...)
│ read by the app listener
POST /v1/webhook/payment-status (X-User-ID + X-Webhook-Secret)
│ match against pending transactions by amount + mode
transaction.payment_status = 'paid'
Signed webhook to the merchant's own webhook_url (payment.success)

See also: Known limitations for what “expiry” does and does not guarantee about a generated QR code.

Continue to Authentication