Produk · Untuk developer

API QRIS untuk developer: satu endpoint, webhook bertanda tangan, mode tes gratis

Kasera Pay API adalah cara menerima pembayaran QRIS dan Virtual Account dari aplikasi sendiri tanpa membangun sistem verifikasi manual. Satu panggilan membuat permintaan pembayaran, pembeli membayar dari aplikasi banknya, dan server menerima webhook bertanda tangan saat uangnya masuk. Halaman ini menjelaskan apa yang didapat, apa biayanya, dan apa yang perlu disiapkan. Urutan pemasangannya langkah demi langkah ada di panduan integrasi QRIS di website, dan urutan yang berbeda untuk software kasir ada di panduan integrasi QRIS di POS.

Satu endpoint, dua cara menampilkan pembayaran

Semua metode berjalan lewat POST /v1/transactions. Responsnya membawa keduanya sekaligus: checkout_url ke halaman pembayaran yang dihosting Kasera Pay, dan objek payment untuk yang ingin menggambar sendiri. Untuk QRIS, payment.qr_string adalah payload EMV mentah yang bisa diubah menjadi gambar oleh pustaka QR mana pun. Untuk Virtual Account, bentuknya nomor pembayaran.

curl https://pay.kasera.id/v1/transactions \
  -H "Authorization: Bearer kp_test_..." \
  -H "Idempotency-Key: order-1234" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 150000,
    "description": "Kaos komunitas",
    "external_id": "ORD-1234",
    "payment_methods": ["qris"],
    "return_url": "https://toko.example/selesai"
  }'

Respons 201:

{
  "id": "payreq_9b2f...",
  "status": "pending",
  "amount": 150000,
  "checkout_url": "https://pay.kasera.id/p/xK3f...",
  "payment_method": "qris",
  "payment": {
    "type": "qr",
    "qr_string": "00020101021226670016COM.KASERA.WWW...6304A1B2"
  },
  "expires_at": "2026-09-07T13:00:00+07:00"
}

Header Idempotency-Key adalah satu-satunya hal yang mencegah permintaan yang terkirim dua kali menjadi dua tagihan. Nilainya dibuat sebelum percobaan pertama dan dipakai ulang pada setiap retry. Nominal ditulis dalam rupiah utuh, dan identitas amount = fee + net selalu berlaku pada responsnya.

Webhook yang bisa dipercaya tanpa panggilan balik

Saat pembayaran terkonfirmasi, Kasera Pay mengirim event payment.paid ke setiap endpoint webhook yang aktif, sampai lima per mode. Setiap pengiriman membawa tanda tangan bertimestamp di header Kasera-Signature-V1, HMAC-SHA256 atas t + "." + rawBody, dan id event di Kasera-Event-Id untuk dedupe. Pengiriman diulang dengan exponential backoff sampai tujuh percobaan dalam rentang sekitar 33 jam bila endpoint tidak menjawab 2xx.

POST https://toko.example/webhook
Kasera-Signature-V1: t=1757222700,v1=5f4d...
Kasera-Event-Id: evt_...

{
  "id": "evt_...",
  "type": "payment.paid",
  "livemode": false,
  "data": {
    "payment_request_id": "payreq_9b2f...",
    "external_id": "ORD-1234",
    "amount": 150000,
    "paid_at": "2026-09-07T12:04:58+07:00"
  }
}

Contoh verifikasi dalam Node.js, aturan timestamp lima menit, dan masa tenggang rotasi secret ada di dokumentasi webhook.

Metode yang aktif hari ini

MetodeKodeBentuk paymentTarif default
QRISqrisqr, payload EMV0,7% + Rp 250 per transaksi berhasil
Virtual Account BRI, BNI, Mandiri, Permata, CIMB Niaga, Danamon, Maybankva_bri dan seterusnyapayment_code, nomor pembayaranRp 5.000 tetap per transaksi
Pembayaran di atas Rp 1.000.000qris dan va_*Sama seperti di atas1% dari seluruh nominal

E-wallet belum aktif, dan paylater baru dibuka untuk akun tertentu; bentuk integrasi keduanya sudah diterbitkan di dokumentasi supaya bisa disiapkan lebih dulu. Tarif di atas adalah tarif default yang diterbitkan, tanpa biaya bulanan dan tanpa biaya pendaftaran. Daftar metode yang aktif untuk sebuah akun, lengkap dengan tarif dan rentang nominalnya, dibaca dari GET /v1/payment_methods, jadi kode metode dan tarifnya tidak perlu ditulis permanen di kode. Rinciannya ada di dokumentasi metode pembayaran.

Kalau Virtual Account yang lebih dulu dibutuhkan, termasuk nomor yang terbit saat permintaan dibuat dan apa bedanya dengan mendaftar ke setiap bank sendiri, ada halaman API Virtual Account tujuh bank.

Mode tes sebelum mode live

Kunci dibuat di dashboard pada menu Developer. Kunci tes berawalan kp_test_, kunci live berawalan kp_live_, dan keduanya dikirim sebagai Authorization: Bearer. Create dengan kunci tes menghasilkan permintaan pembayaran mode tes yang dituntaskan lewat endpoint simulasi dengan hasil succeeded atau expired. Mode live dan mode tes adalah dua endpoint webhook terpisah dengan signing secret masing-masing, jadi secret tes tidak pernah memverifikasi payload live. Panduannya ada di dokumentasi mode tes.

Batas default yang berlaku saat pembuatan

Nilainya dapat berbeda per akun dan kode error penolakannya ada di dokumentasi batas dan laju. Pencairan saldo ke rekening bank dikenakan Rp 3.000 per pencairan, bukan per transaksi, dan berjalan setelah pembayaran selesai diproses bank pada hari kerja berikutnya, dengan pengiriman ke bank Senin sampai Sabtu pukul 13.00–14.00 WIB; jadwal dan penahannya dibahas di panduan pencairan dana.

Yang perlu disiapkan

Kalau yang dibutuhkan hanya menagih beberapa pembeli sehari tanpa menulis kode, tautan pembayaran dari dashboard sudah cukup dan tarifnya sama; lihat halaman payment link. Titik saat tautan manual berhenti sepadan dan integrasi mulai masuk akal dibahas di panduan dari tautan manual ke integrasi API.

Buat akun dan API key

Pertanyaan yang sering muncul

Apakah perorangan tanpa PT bisa memakai API ini?

Bisa. Pendaftaran terbuka untuk perorangan maupun badan usaha. Yang diperiksa adalah identitas dan rekening bank tujuan, bukan bentuk badan hukum. Syarat sebenarnya, dokumen yang dipakai, dan batas yang berlaku untuk akun perorangan dibahas di panduan payment gateway tanpa PT.

Apakah harus membangun halaman pembayaran sendiri?

Tidak. Respons create membawa checkout_url ke halaman pembayaran yang dihosting Kasera Pay, lengkap dengan pemilih metode, instruksi cara bayar, dan hitung mundur. Direct API, yaitu menggambar QR atau menampilkan nomor Virtual Account di halaman sendiri, adalah pilihan, bukan keharusan, dan keduanya memakai endpoint create yang sama.

Bagaimana memastikan pembayaran benar-benar masuk?

Dari webhook payment.paid yang tanda tangannya terverifikasi, atau dari GET /v1/transactions/:id yang dipanggil dari server sendiri. Kembalinya pembeli ke return_url hanya navigasi dan bukan bukti pembayaran. Status permintaan pembayaran bernilai pending, succeeded, expired, canceled, atau failed; daftar lengkapnya ada di referensi ambil permintaan.

Apa yang tersedia di mode tes?

Semua yang ada di mode live, dengan kunci berawalan kp_test_ dan tanpa uang sungguhan. Pembayaran tes dituntaskan lewat endpoint simulasi, dan webhook mode tes dikirim ke endpoint tes dengan signing secret tersendiri, jadi seluruh alur dari create sampai handler bisa diuji sebelum ada pembeli pertama.

Untuk implementasi lengkap di satu framework, termasuk verifikasi tanda tangan dan feature test-nya, ada panduan integrasi payment gateway di Laravel 13.