Konek QR

Referensi API Konek QR

Referensi REST API v1 dari OpenAPI 3.1.

Referensi API ditulis dalam bahasa Inggris, sama seperti berkas openapi.yaml. Panduan langkah demi langkah ada di Mulai cepat.

Dynamic QRIS invoices on your own static QRIS, confirmed by the Konek QR Listener.

The public REST API of Konek QR (/v1) for your servers, plus the webhooks Konek QR sends.

  • Base URL: https://api.konekqr.web.id. JSON in, JSON out. Money is whole rupiah (integers). Times are RFC 3339 in UTC (2026-11-04T09:30:00Z).
  • Authentication: Authorization: Bearer kq_live_… or kq_test_…. Create keys in the dashboard (app.konekqr.web.id → API). A key is shown once. A test key only ever sees and creates test-mode objects, a live key only live ones. Scopes: payments:read, payments:write, events:read.
  • Server-to-server only: a request with an Origin header (a browser) is refused with 403 browser_not_allowed, so keys never live in web pages. There is no CORS.
  • Rate limit: 120 requests per minute per key, and 120 invoice creations per minute per account (429 rate_limited with Retry-After in seconds). An account under anti-abuse review is held to 10 live invoices an hour, answered the same way.
  • Errors: RFC 9457 application/problem+json with a stable code to switch on. detail and field messages are Indonesian unless Accept-Language prefers English (en).
  • Test mode: test invoices have a QR that no payer app accepts (ID.KONEKQR.TEST, KONEK QR TEST). Mark one paid with POST /v1/payments/{id}/simulate.
  • Events: every change you can be told about is an Event, delivered by webhooks and readable (with replay up to 30 days) through GET /v1/events.

Full OpenAPI 3.1.0 description: https://api.konekqr.web.id/openapi.yaml

Endpoints

  • POST /v1/payments (createPayment, scope payments:write): Create an invoice. Creates an invoice of amount plus (or minus, per QRIS) a unique code of Rp1–499 (never 100, 200, 300 or 400), so the total identifies the payment. The response holds qrString (the dynamic QRIS to show the buyer) and payUrl (a hosted payment page).
  • GET /v1/payments (listPayments, scope payments:read): List invoices. Invoices of the key's mode, newest first. qrString is always null in lists; get one invoice for it. Page with before (the id of the last invoice you got).
  • GET /v1/payments/{id} (getPayment, scope payments:read): Get an invoice. One invoice of the key's mode, with qrString while it is pending.
  • POST /v1/payments/{id}/cancel (cancelPayment, scope payments:write): Cancel an invoice. Cancels a pending invoice (also one past its expiry) and emits payment.cancelled. A buyer who pays it anyway lands in the dashboard's unmatched box. No request body.
  • POST /v1/payments/{id}/simulate (simulatePayment, scope payments:write): Simulate a payment (test mode). Marks a pending test invoice paid as the Listener would (paidVia: "simulation", paidLate when past its expiry) and emits payment.paid, so your webhook handler and event consumer see what a real payment looks like. Test keys only: a live key gets 403 test_mode_only. No request body.
  • GET /v1/qris (listQris, scope payments:read): List usable QRIS. The QRIS invoices of the key's mode can use, oldest first: active ones for a live key, every QRIS of the account for a test key.
  • GET /v1/events (listEvents, scope events:read): Read account events. Events of the key's mode after the cursor after, oldest first, at most 100. Without after it starts at the oldest event kept (30 days). Store next and send it as after on the next call: nothing is skipped or repeated. With wait (seconds) the request waits until an event arrives or the time is up (long-polling); use a client timeout of at least wait + 10 seconds. At most 5 requests of an account wait at once; more answer at once.
  • GET /v1/devices (listDevices, scope payments:read): List Listener phones. The account's paired Konek QR Listener phones, oldest first. online means the phone was heard from in the last 7 minutes.

Webhook events

Signed with Standard Webhooks (webhook-id, webhook-timestamp, webhook-signature); the body is the Event object.

  • payment.paid: An invoice became paid: detected by the Listener (paidVia: listener), marked paid by hand in the dashboard or on the phone (manual), or simulated in test mode (simulation). Check paidLate: a payment up to 24 hours after expiry is still matched, as late.
  • payment.expired: A pending invoice passed expiresAt (reported once, at most about a minute late).
  • payment.cancelled: An invoice was cancelled (API or dashboard).
  • payment.unmatched: The Listener read a payment that matched no invoice, such as a buyer paying the static QR directly or paying a cancelled invoice. Always livemode: true. The notification text is never included.
  • device.offline: A Listener phone sent nothing for 7 minutes (once per outage). Always livemode: true.
  • device.online: The first signed request of a phone after device.offline. Always livemode: true.
  • topup.paid: A top-up of your Konek QR fee balance (made in the dashboard) was paid. Always livemode: true. Fees are taken from this balance; it cannot be withdrawn or transferred.
  • webhook.test: Sent by "Kirim event uji" in the dashboard, signed like any other event. Webhooks only: it is not an account event and never appears in GET /v1/events.

Referensi interaktif butuh JavaScript. Tanpa itu, baca openapi.yaml langsung.