NikiPay Dokumentasi API

Base URL: . Semua request/response JSON. Endpoint privat memakai header x-api-key: npk_... (buat di dashboard, butuh langganan aktif). Batas 60 request/menit per key.

1. Buat QRIS dinamis

POST /api/v1/qris
curl -X POST BASE/api/v1/qris \
  -H "x-api-key: npk_xxx" -H "content-type: application/json" \
  -d '{"amount": 15000, "reference": "ORDER-123", "attributes": {"wa": "628xx"}, "callback_url": "https://bot.kamu.com/paid"}'
{
  "success": true,
  "data": {
    "qris_id": "SJMGRs5xxx",
    "trx_id": "TRX-7BAZ3625",
    "reference": "ORDER-123",
    "amount": 15000,
    "qris_code": "00020101021226...6304ABCD",      // payload EMV → render jadi QR di bot
    "qris_url": "BASE/qr/SJMGRs5xxx",              // halaman bayar siap pakai
    "qr_image_url": "BASE/qr/SJMGRs5xxx?format=raw",// redirect ke gambar PNG
    "expires_at": "2026-09-12T12:26:52.000Z",
    "expires_in_seconds": 300,
    "verification_mode": "auto"                    // "manual" kalau GoBiz belum dihubungkan
  }
}

callback_url opsional: saat lunas, NikiPay POST {event:"payment.success", qris_id, reference, amount, transaction} ke URL itu (sekali, tanpa signature). Untuk yang bertanda tangan pakai webhook.

2. Cek status (polling)

GET /api/v1/qris/:qris_id/status — publik, tanpa API key. Panggil tiap 3–5 detik selama QR aktif; gateway mengecek mutasi GoBiz saat dipanggil.
{ "success": true, "paid": false, "status": "PENDING", "reference": "ORDER-123", "amount": 15000 }
{ "success": true, "paid": true,  "status": "PAID", "transaction": { "transaction_id": "...", "amount": 15000, "payer_issuer": "GoPay", "transaction_time": "..." } }
{ "success": false, "paid": false, "status": "EXPIRED" }   // HTTP 410

3. Detail QRIS

GET /api/v1/qris/:qris_id — publik. Sama seperti respons create + formatted_amount, status, transaction.

4. Info akun

GET /api/v1/me
{ "success": true, "data": { "subscription": { "active": true, "plan": "1 Bulan", "ends_at": "...", "days_left": 21 }, "gobiz_connected": true, "qris_configured": true, "verification_mode": "auto" } }

5. Daftar transaksi

GET /api/v1/transactions?limit=20&status=PAID

6. Webhook

GET | POST | DELETE /api/v1/webhooks[/:id]
POST {"url": "https://bot.kamu.com/webhook", "secret": "rahasia"}   // URL harus balas 2xx untuk ping
Event payment.success dikirim dengan header X-Webhook-Signature: sha256=HMAC_SHA256(body, secret), X-Webhook-Event, X-Webhook-Delivery.

Kode error

401 INVALID_API_KEYKey salah / dicabut
403 SUBSCRIPTION_EXPIREDLangganan habis — perpanjang di dashboard
403 ACCOUNT_BLOCKEDAkun diblokir admin
409 STATIC_QRIS_NOT_SETQRIS statis belum dipasang di dashboard
429 RATE_LIMITEDLebih dari 60 request/menit
410 status EXPIREDQRIS kadaluarsa (5 menit)

Contoh Node.js

const BASE = 'BASE', KEY = 'npk_xxx';
const r = await fetch(BASE + '/api/v1/qris', { method: 'POST', headers: { 'x-api-key': KEY, 'content-type': 'application/json' }, body: JSON.stringify({ amount: 15000, reference: 'ORDER-123' }) });
const { data } = await r.json();
// tampilkan data.qris_code sebagai QR, lalu:
const t = setInterval(async () => {
  const s = await (await fetch(`${BASE}/api/v1/qris/${data.qris_id}/status`)).json();
  if (s.paid) { clearInterval(t); /* proses pesanan */ }
  if (s.status === 'EXPIRED') clearInterval(t);
}, 4000);