qris-gatepay
v1.2.0
Published
SDK resmi QRIS GatePay (Node.js, zero-dependency) — buat transaksi QRIS, cek status, batalkan, verifikasi webhook HMAC.
Maintainers
Readme
qris-gatepay
SDK resmi QRIS GatePay untuk Node.js — buat transaksi QRIS, cek status, batalkan, dan verifikasi webhook (HMAC-SHA256). Zero-dependency (pakai fetch bawaan Node 18+ & modul crypto).
📖 Dokumentasi lengkap: https://gatepay.biz.id/gpa/docs
Instalasi
npm install qris-gatepayInisialisasi
const GatePay = require('qris-gatepay');
const gp = new GatePay({
apiKey: 'gpk_live_xxxxxxxx', // gpk_live_… (produksi) / gpk_test_… (sandbox)
webhookSecret: 'whsec_xxxx', // opsional, buat verifyWebhook
});Mode live vs sandbox ditentukan oleh prefix API key (
gpk_live_/gpk_test_) — bukan setelan terpisah. Simpan key live di produksi, key test di staging.
Buat Transaksi
const tx = await gp.createPayment({
amount: 10000, // wajib, minimal 500
orderId: 'INV-123', // opsional — ID pesananmu, dibalikin di webhook & status
note: 'Order #123', // opsional (keterangan bebas)
expiryMinutes: 15, // opsional (1–1440, default 5)
adminMode: 'merchant', // opsional: 'merchant' (default) / 'customer'
});
// tx.order_id ada di respons; webhook & getPayment juga membawanya → lookup order gampang
console.log(tx.reference); // PAY-...
console.log(tx.total_pay); // nominal yang harus dibayar customer
console.log(tx.payment_link); // halaman checkout siap pakai → redirect customer ke sini
console.log(tx.qr_string); // atau render QR sendiri dari string iniCek Status
const status = await gp.getPayment(tx.reference);
console.log(status.status); // pending | paid | expired | cancelledBatalkan (hanya saat pending)
await gp.cancelPayment(tx.reference, { reason: 'Dibatalkan pembeli' });Tunggu Pembayaran (polling built-in)
Nggak mau setup webhook? Pakai polling bawaan — otomatis cek status sampai selesai.
const ac = new AbortController(); // ac.abort() untuk stop polling
const final = await gp.watchPayment(tx.reference, {
interval: 5000, // cek tiap 5 detik (default)
timeout: 5 * 60 * 1000, // menyerah setelah 5 menit (default)
signal: ac.signal,
onStatusChange: (p) => console.log('berubah:', p.status),
onTimeout: () => console.log('waktu habis, masih pending'),
onError: (e) => console.warn('poll error (lanjut):', e.message),
});
if (final.status === 'paid') console.log('Lunas!');Verifikasi Webhook (Express)
Gunakan raw body — jangan di-JSON.parse sebelum verifikasi.
const express = require('express');
const app = express();
app.post('/webhook/gatepay',
express.raw({ type: 'application/json' }), // penting: raw body
(req, res) => {
const rawBody = req.body.toString('utf8');
const ok = gp.verifyWebhook({
rawBody,
timestamp: req.header('X-Gatepay-Timestamp'),
signature: req.header('X-Gatepay-Signature'),
});
if (!ok) return res.status(401).send('invalid signature');
const evt = JSON.parse(rawBody);
if (evt.event === 'payment.paid') {
// tandai order lunas — evt.data.reference, evt.data.total_pay, dst.
}
res.sendStatus(200); // balas 2xx secepatnya
}
);Error handling
const { GatePayError } = GatePay;
try {
await gp.createPayment({ amount: 100 }); // di bawah minimum (min Rp500)
} catch (e) {
if (e instanceof GatePayError) console.log(e.status, e.message, e.data);
}API
| Method | Keterangan |
|---|---|
| createPayment({ amount, note?, expiryMinutes?, adminMode? }) | Buat transaksi QRIS |
| getPayment(reference) | Cek status transaksi |
| cancelPayment(reference, { reason? }) | Batalkan (hanya pending) |
| watchPayment(reference, { interval?, timeout?, onUpdate? }) | Poll status sampai selesai (paid/expired/cancelled) atau timeout |
| verifyWebhook({ rawBody, timestamp, signature, secret? }) | Verifikasi tanda tangan webhook → boolean |
MIT © GatePay
