Integrasikan pembayaran tanpa menebak.
Referensi endpoint, format data, callback, dan contoh kode Poko Payment. Gunakan API key dari bot dan uji alur integrasi di server Anda sebelum dipakai pelanggan.
Kredensial API Key
Dapatkan API Key unik toko Anda dari menu API Key di bot Telegram @pokopaymentbot.
Koneksi QRIS & Sesi (GoBiz / DANA)
Hubungkan akun GoBiz atau DANA melalui bot Telegram dan kirimkan foto QRIS toko Anda (auto-detect GoPay & DANA).
Integrasikan ke Sistem Anda
Tembak endpoint /create-qris setiap kali ada checkout pesanan di website/aplikasi Anda.
Authorization: Bearer:
Authorization: Bearer mch_live_xxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
?api_key=...).
Query string tersimpan di access log server, history browser, dan header Referer — sehingga API Key Anda bisa bocor tanpa disadari.
Format ini sudah otomatis ditolak oleh gateway kami.
X-Api-Key: mch_live_xxx.
Jika API Key Anda pernah bocor, hubungi @pokosoft untuk rotasi atau klik Reset API Key di menu bot.
| Parameter (JSON Body) | Tipe | Keterangan |
|---|---|---|
| amount WAJIB | Integer | Nominal tagihan dalam Rupiah (contoh: 25000). Minimal Rp 100, maksimal Rp 100.000.000. |
| unique_code OPSIONAL | Boolean | Jika true, sistem menambah kode unik genap (Rp 2, 4, 6, ...) agar mutasi tidak pernah ambigu saat nominal identik bentrok. Nilai akhir ada di data.amount. |
| trx_id OPSIONAL | String | ID Invoice unik sistem Anda (contoh: INV-2026-001). |
| customer_name OPSIONAL | String | Nama pembeli untuk pencatatan log transaksi. |
| description OPSIONAL | String | Catatan transaksi (mis. nomor order). Maks 255 karakter. |
| webhook_url OPSIONAL | String | URL notifikasi callback instan saat pembayaran berhasil. Alamat IP internal otomatis ditolak (proteksi SSRF). |
Alasannya: Tag 59 adalah data merchant terdaftar. Mengubahnya berisiko QR ditolak saat pemindaian, nama menyamar kepada pembeli, dan menyimpang dari standar QRIS Bank Indonesia.
Jika nama perlu diganti: ubah nama outlet di aplikasi GoBiz/DANA Anda, lalu upload ulang QRIS statisnya lewat bot (menu Setup Toko → Atur QRIS Statis). Gateway akan membaca ulang Tag 59 secara otomatis.
429 + header Retry-After.
Contoh kode unik: kirim
amount: 25000, unique_code: true → amount: 25002, unique_code: 2.
{
"success": true,
"data": {
"qris_id": "cg4chpec",
"trx_id": "INV-2026-001",
"qris_url": "https://domain.com/qr/cg4chpec",
"qris_code": "00020101021226610014COM.GO-JEK.WWW...",
"amount": 25000,
"expires_at": "2026-10-25T02:00:00.000Z",
"expires_in": "5 menit"
}
}
| Parameter | Tipe | Keterangan |
|---|---|---|
| amount WAJIB | Integer | Nominal pembayaran yang ingin diverifikasi. |
| trx_id OPSIONAL | String | ID Invoice / scope transaksi. |
{
"success": true,
"paid": true,
"transaction": {
"transaction_id": "01a17042-2ee0-7000-a4e3-2a145a499062",
"order_id": "QRIS-0620261024233228d4dtSizdbNID",
"amount": 25000,
"payer_issuer": "DANA / GoPay / BCA",
"transaction_time": "2026-10-25T01:58:30+07:00"
}
}
payment.success ke URL Webhook Anda.
Callback URL yang didaftarkan di dashboard akuisir:
https://pokopayment.biz.id/webhook/payment/gopay/<TOKEN>
https://pokopayment.biz.id/webhook/payment/dana/<TOKEN>
Ambil URL Anda lewat bot: Setup Toko → Callback URL. Tiap merchant mendapat token privat sendiri, sehingga callback milik satu merchant tidak bisa menandai QRIS merchant lain sebagai lunas.
Keamanan: token path WAJIB ada dan dibandingkan secara timing-safe. Tanpa token yang benar, permintaan ditolak
401
dan tidak ada transaksi yang diproses — mencegah transaksi palsu. Signature HMAC-SHA256 diverifikasi tambahan bila dikonfigurasi.
{
"event": "payment.success",
"timestamp": "2026-10-25T02:15:30.412Z",
"data": {
"trx_id": "INV-2026-001",
"qris_id": "cg4chpec",
"amount": 25000,
"customer_name": "Budi Santoso",
"description": "Order #9912",
"transaction": {
"id": "01a17042-2ee0-7000-a4e3-2a145a499062",
"order_id": "INV-2026-001",
"amount": 25000,
"issuer": "DANA",
"payment_type": "DANA_QRIS",
"transaction_time": "2026-10-25T02:15:10+07:00"
}
}
}
X-Webhook-Signature.
Lihat panduan lengkap di tab Keamanan.
X-Webhook-Signature untuk memastikan integritas payload dari pemalsuan data:
| Header | Isi | Fungsi |
|---|---|---|
X-Webhook-Signature |
HMAC-SHA256(body) | Integritas payload |
X-Webhook-Timestamp |
Unix ms | Anti replay attack |
X-Webhook-Signature-Ts |
HMAC-SHA256(ts.body) | Mengikat payload + waktu |
<?php
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$secret = 'WEBHOOK_SECRET_ANDA';
$expectedSignature = hash_hmac('sha256', $payload, $secret);
if (hash_equals($expectedSignature, $signature)) {
$event = json_decode($payload, true);
$trxId = $event['data']['trx_id'];
// Update status pesanan di database toko Anda menjadi LUNAS:
// updateOrderStatus($trxId, 'PAID');
http_response_code(200);
echo json_encode(['success' => true]);
} else {
http_response_code(403);
echo 'Tanda tangan webhook tidak valid';
}
?>
Security Headers
CSP, HSTS, Referrer-Policy, Permissions-Policy, X-Content-Type-Options & X-Frame-Options aktif di setiap response.
Rate Limiting
Kuota per IP di semua endpoint sensitif, dengan header X-RateLimit-* dan Retry-After.
Brute-Force Lockout
5× autentikasi gagal → IP dikunci 30 menit otomatis.
Constant-Time Compare
Perbandingan API Key memakai crypto.timingSafeEqual — menutup celah timing attack.
API Key Hashing
API Key disimpan sebagai hash SHA-256, tidak pernah plaintext di memori server.
Anti-SSRF
Webhook diblokir ke IP privat, loopback, link-local, dan metadata cloud (169.254.169.254).
Input Validation
Nominal dibatasi 100–100.000.000, string disanitasi, payload dibatasi 64 KB.
CORS Restrictive
Hanya origin domain gateway sendiri yang diizinkan untuk akses browser.
Endpoint Terpisah
Log server & status keamanan hanya untuk root key.
X-RateLimit-Limit, X-RateLimit-Remaining, dan X-RateLimit-Reset agar Anda bisa menangani 429 dengan rapi.
| Endpoint | Kuota | Periode | Keterangan |
|---|---|---|---|
/create-qris |
30 request | per menit | Ditambah batas global 120/menit per IP |
/check-payment |
20 request | per menit | Query mutasi ke API GoPay/DANA — dibatasi ketat |
/api/qr-status/:id, /qr/:id |
20 request | per menit | Endpoint publik, memicu query ke penyedia |
| Endpoint bertoken (auth) | 20 request | per 5 menit | Menutupi seluruh request yang gagal autentikasi |
| Semua request (global) | 120 request | per menit | Pembatas keseluruhan untuk request dari IP yang sama |
| Autentikasi gagal | 5× → lock | kunci 30 menit | IP dikunci otomatis, header Retry-After dikirim |
429.
Jangan retry secara agresif — gunakan nilai Retry-After yang kami kirim.
| Header | Isi | Fungsi |
|---|---|---|
X-Webhook-Signature |
HMAC-SHA256(body) | Memastikan payload asli dari gateway, bukan dipalsukan |
X-Webhook-Timestamp |
Unix timestamp (ms) | Menjaga agar request lama tidak bisa diputar ulang |
X-Webhook-Signature-Ts |
HMAC-SHA256(timestamp.body) |
Signature yang mengikat payload dengan waktu pengiriman |
const crypto = require('crypto');
// 1. Tolak request lama (> 5 menit) untuk cegah replay attack
const ts = req.headers['x-webhook-timestamp'];
if (!ts || Math.abs(Date.now() - Number(ts)) > 300000) {
return res.status(400).send('Request kedaluwarsa');
}
// 2. Cocokkan signature (wajib timing-safe)
const rawBody = req.rawBody; // siapkan body mentah, jangan parse JSON dulu
const secret = process.env.WEBHOOK_SECRET;
const expected = crypto.createHmac('sha256', secret)
.update(rawBody).digest('hex');
if (!crypto.timingSafeEqual(
Buffer.from(expected, 'hex'),
Buffer.from(req.headers['x-webhook-signature'] || '', 'hex')
)) {
return res.status(401).send('Signature tidak valid');
}
// 3. Payload sekarang aman diproses
const event = JSON.parse(rawBody);
markAsPaid(event.data.trx_id, event.data.amount);
rawBody tersedia (misalnya express.raw() atau verify di body-parser).
| Endpoint | Fungsi | Akses |
|---|---|---|
GET /api/logs |
Log aktivitas server internal | Root Key |
GET /api/security/status |
Status konfigurasi keamanan gateway | Root Key |
curl -H "Authorization: Bearer <ROOT_KEY>" https://pokopayment.biz.id/api/security/status
1. Segera Reset
Buka bot → API Key → pilih Reset API Key Baru. Key lama langsung tidak berlaku.
2. Update Server Anda
Ganti API Key di konfigurasi website/app Anda, lalu lakukan request uji.
3. Laporkan
Hubungi @pokosoft bila Anda curiga ada penyalahgunaan API Key.