PENGEMBANG / REFERENSI API
Gateway deteksi pembayaran PayBridge
REST API untuk membuat invoice, halaman pembayaran, QRIS nominal dinamis, deteksi notifikasi Android, dan webhook bertanda tangan HMAC.
Terima QRIS untuk merchant tanpa API resmi provider.
Merchant membuat invoice, PayBridge menghasilkan QRIS nominal dinamis dengan kode unik, pelanggan membayar, Reader membaca notifikasi aplikasi merchant, lalu webhook HMAC dikirim ke backend merchant.
payment_detected- Notifikasi pembayaran cocok dengan invoice. Status ini bukan bukti settlement bank.
paid_confirmed- Konfirmasi internal merchant, bukan konfirmasi resmi dari provider.
Autentikasi
REST API menerima Bearer token qrk_live_* atau header x-api-key. Prefix qrk_live_ dipertahankan sebagai format kontrak API.
curl -H "Authorization: Bearer qrk_live_xxx" \
-H "Content-Type: application/json" \
https://paybridge.my.id/api/v1/invoices
# atau dengan header x-api-key
curl -H "x-api-key: qrk_live_xxx"- Buat key di
/api-keyssebagai owner atau admin - Simpan di vault; nilai lengkap hanya ditampilkan sekali
- Cabut key kapan pun melalui dashboard
- Batas pembuatan invoice: 120 permintaan per jam per API key
POST /api/v1/invoices
201Buat invoice melalui kanal QRIS aktif. PayBridge mengalokasikan kode unik secara otomatis.
Request
{
"external_id": "ORDER-123",
"amount": 15000,
"expires_in_minutes": 15,
"description": "Langganan Pro",
"metadata": { "user_id": "42" },
"callback_url": "https://toko.example/success"
}Response 201
{
"data": {
"id": "uuid",
"external_id": "ORDER-123",
"amount": 15000,
"payable_amount": 15001,
"unique_code": 1,
"currency": "IDR",
"status": "pending",
"expires_at": "...",
"payment_link": "https://paybridge.my.id/pay/uuid?t=hex64",
"qr_image_url": "https://paybridge.my.id/api/invoices/uuid/qris.png?t=hex64"
}
}Idempotency
curl -X POST ... -H "idempotency-key: order-123" -d '{...}'
# replay -> 200 { ..., "idempotent_replay": true }
# concurrent -> hanya satu yang 201, lain 409Cek status
200Merchant cek status kapan saja via API key — tanpa token public.
# by ID
GET /api/v1/invoices/{id}
# by external_id
GET /api/v1/invoices?external_id=ORDER-123
# response hasil termasuk
# payment_link (decrypted dari encrypted store)
# qr_image_url
# transaction { provider, amount, match_status, reference_number } atau nullBatalkan invoice
200 / 409Batalkan invoice sebelum pembayaran terdeteksi.
POST /api/v1/invoices/{id}/cancel
# 200 -> status: "cancelled"
# 409 -> kalau sudah payment_detected/paid_confirmed/cancelled/expiredInvoice berstatus pending dapat dibatalkan. Status setelah deteksi tidak dapat dibatalkan melalui endpoint ini.
Payment page
public t=tokenHalaman pembayaran publik untuk pelanggan memindai QRIS dari aplikasi pembayaran.
GET https://paybridge.my.id/pay/{invoice_id}?t={64hex}
# Perilaku:
# - QRIS 264px, kode unik, hitung mundur kedaluwarsa
# - pemeriksaan status setiap 3 detik
# - payment_detected/paid_confirmed -> tombol "Kembali ke merchant" jika ada callback_url
# - payment_detected = notifikasi cocok, bukan bukti settlement bank
# - expired -> halaman expired
# - bad token -> 404Token publik berupa 64 karakter heksadesimal acak. Token wajib diperlakukan sebagai secret dan tidak boleh dicatat di log.
Gambar QR
PNGAlternatif tanpa redirect: tampilkan gambar QR dari URL bertoken.
<img src="https://paybridge.my.id/api/invoices/{id}/qris.png?t={64hex}"
width="264" height="264" />Cocok untuk modal di toko, in-app, atau kasir offline.
Webhooks
HMAC-SHA256Event dikirim setelah deteksi dan pemrosesan selesai. invoice.payment_detected menandakan notifikasi cocok; invoice.payment_confirmed dikirim setelah konfirmasi internal merchant.
POST {webhook_url}
Headers:
paybridge-event-id: uuid
paybridge-timestamp: Unix timestamp (detik)
paybridge-signature-version: v1
paybridge-signature: hmac_sha256(timestamp.body, secret)
# legacy qrisbridge-* aliases also sent during migration
Body envelope:
{
"id": "delivery-uuid",
"type": "invoice.payment_detected",
"api_version": "2026-08-02",
"created_at": "2026-08-11T10:00:00Z",
"organization_id": "organization-uuid",
"data": { "invoice": { "id": "..." }, "transaction": { "id": "..." } }
}Persyaratan penerima
- Hitung HMAC-SHA256 dari
timestamp + "." + rawBody, lalu bandingkan secara constant-time - Tolak timestamp yang berumur lebih dari 5 menit
- Deduplicate berdasarkan header
paybridge-event-idatau fieldid - Kembalikan 2xx untuk sukses; 4xx menjadi gagal permanen kecuali 408, 409, 425, dan 429
Kode error
400— payload invalid, zod detail:Invalid invoice payload (path: message)401— key hilang/revoked/expired403— origin tidak diizinkan / role tidak cukup404— not found di organisasi ini409— channel belum aktif / QRIS belum di-upload / cancel ilegal / callback constraint429— rate limit, header `retry-after` detik500— server error, retry dengan idempotency header
payment_detected bukan bukti settlement bank. Merchant menentukan kebijakan fulfillment berdasarkan risiko bisnis. PayBridge tidak menahan atau memindahkan dana.
payment_detected = sistem confident atas detection, bukan settlement bank. Merchant menentukan policy sendiri berdasarkan profil bisnis:
| Profil risiko | Contoh produk | Policy fulfillment |
|---|---|---|
| Rendah | Lisensi, voucher, top-up | Fulfill langsung dari payment_detected; reversal cost kecil. |
| Sedang | F&B, tiket, langganan | Fulfill dari payment_detected; simpan audit trail 30 hari; punya SOP reversal. |
| Tinggi | Barang fisik mahal, withdrawal | Tunggu paid_confirmed + verifikasi manual dari aplikasi merchant. |
| Kritis | Treasury, payout besar | Tambah verifikasi eksternal (telepon, statement bank) sebelum fulfillment. |
Untuk risiko tinggi/kritis, payment_detected saja tidak cukup — merchant wajib cek aplikasi merchant sendiri. Batas produk: PayBridge tidak punya visibility ke settlement bank.
Siap menguji integrasi?
Masuk ke workspace beta untuk menyiapkan kanal, API key, dan Reader.