API Reference ZANNPAY
Integrasi API ZANNPAY menggunakan arsitektur Single Endpoint (`POST /v1`). Semua request dikirimkan dalam format JSON.
request (contoh: request=new untuk transaksi baru, request=status untuk cek status, request=cancel untuk pembatalan).
Mode Sandbox & Production
Gunakan Mode DEV (Sandbox) untuk menguji alur integrasi dan respon API tanpa menggunakan dana riil.
- Aktifkan mode DEV via toggle di dashboard merchant.
- Transaksi yang dibuat via API saat mode DEV aktif otomatis berstatus
Sandbox. - Gunakan tombol Simulasikan Pembayaran Berhasil di invoice Sandbox untuk menguji notifikasi Webhook ke server Anda.
Otentikasi & Signature
Setiap request API wajib menyertakan parameter merchant ID dan signature SHA-256.
1. Formula Signature Transaksi (`new`, `status`, `cancel`):
signature = sha256(merchant + secret_key + trx_id)
2. Formula Signature Penarikan (`withdraw_auto`):
signature = sha256(merchant + pin)
Gabungkan string parameter di atas tanpa spasi, lalu hitung hash SHA-256 dalam format huruf kecil (*lowercase*).
Signature Calculator
Kalkulator instan untuk menguji hasil perhitungan SHA-256 signature:
1. Buat Transaksi Baru (`request: "new"`)
Gunakan parameter request = "new" untuk menghasilkan transaksi dan QRIS / Link pembayaran baru.
Parameter Request (POST /v1):
| Field Name | Type | Status | Deskripsi & Ketentuan |
|---|---|---|---|
| request | string | REQUIRED | Wajib diisi string "new" |
| merchant | string | REQUIRED | Merchant ID terdaftar Anda (cth: MERCHANT123) |
| trx_id | string | REQUIRED | ID Transaksi unik dari sistem toko Anda (cth: INV-1001) |
| payment | string | REQUIRED | Kode pembayaran (cth: QRISNB, BRIVA, ALFAMART) |
| amount | integer | REQUIRED | Nominal transaksi dalam Rupiah (minimal 1000) |
| note | string | REQUIRED | Catatan pesanan (cth: Pembayaran Invoice #1001) |
| expired_time | string | REQUIRED | Masa berlaku transaksi (cth: 30m, 1h, 24h) |
| type_fee | string | REQUIRED | Beban biaya: "user" (pelanggan) atau "merchant" |
| callback_url | string | REQUIRED | URL Webhook merchant tempat menerima status sukses |
| customer_name | string | OPTIONAL | Nama pembeli (Opsional. Default: Nama Toko Anda) |
| return_url | string | OPTIONAL | URL pengalihan otomatis setelah sukses bayar (Opsional. Default: https://pay.zannstore.com) |
| signature | string | REQUIRED | Hash sha256(merchant + secret_key + trx_id) |
Contoh Integrasi Kode:
curl -X POST https://pay.zannstore.com/v1 \
-H "Content-Type: application/json" \
-d '{
"request": "new",
"merchant": "MERCHANT123",
"trx_id": "INV-1001",
"payment": "QRISNB",
"amount": 10000,
"customer_name": "I Putu Anantha Saputra",
"note": "Pembayaran Tagihan INV-1001",
"expired_time": "30m",
"type_fee": "user",
"return_url": "https://tokoanda.com/sukses",
"callback_url": "https://tokoanda.com/api/callback",
"signature": "HASIL_SHA256_SIGNATURE"
}'
<?php
$merchant = "MERCHANT123";
$secretKey = "your_secret_key_here";
$trxId = "INV-1001";
$signature = hash('sha256', $merchant . $secretKey . $trxId);
$payload = [
"request" => "new",
"merchant" => $merchant,
"trx_id" => $trxId,
"payment" => "QRISNB",
"amount" => 10000,
"customer_name" => "I Putu Anantha Saputra",
"note" => "Pembayaran Tagihan INV-1001",
"expired_time" => "30m",
"type_fee" => "user",
"return_url" => "https://tokoanda.com/sukses",
"callback_url" => "https://tokoanda.com/api/callback",
"signature" => $signature
];
$ch = curl_init("https://pay.zannstore.com/v1");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
const crypto = require('crypto');
const merchant = "MERCHANT123";
const secretKey = "your_secret_key_here";
const trxId = "INV-1001";
const signature = crypto
.createHash('sha256')
.update(merchant + secretKey + trxId)
.digest('hex');
const payload = {
request: "new",
merchant: merchant,
trx_id: trxId,
payment: "QRISNB",
amount: 10000,
customer_name: "I Putu Anantha Saputra",
note: "Pembayaran Tagihan INV-1001",
expired_time: "30m",
type_fee: "user",
return_url: "https://tokoanda.com/sukses",
callback_url: "https://tokoanda.com/api/callback",
signature: signature
};
fetch('https://pay.zannstore.com/v1', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
})
.then(res => res.json())
.then(data => console.log(data));
import hashlib
import requests
merchant = "MERCHANT123"
secret_key = "your_secret_key_here"
trx_id = "INV-1001"
raw_str = merchant + secret_key + trx_id
signature = hashlib.sha256(raw_str.encode('utf-8')).hexdigest()
payload = {
"request": "new",
"merchant": merchant,
"trx_id": trx_id,
"payment": "QRISNB",
"amount": 10000,
"customer_name": "I Putu Anantha Saputra",
"note": "Pembayaran Tagihan INV-1001",
"expired_time": "30m",
"type_fee": "user",
"return_url": "https://tokoanda.com/sukses",
"callback_url": "https://tokoanda.com/api/callback",
"signature": signature
}
res = requests.post("https://pay.zannstore.com/v1", json=payload)
print(res.json())
Contoh Response Success (HTTP 200 OK):
{
"status": true,
"message": "Berhasil membuat transaksi",
"data": {
"trx_svr": "ZP260727ABC123",
"trx_id": "INV-1001",
"method_code": "QRISNB",
"method_name": "QRIS by Nationalnobu",
"status": "Pending",
"amount": 10000,
"unique_code": 0,
"diterima": 9990,
"fee": 10,
"type_fee": "user",
"qr_url": "https://cekid.zannstore.com/qris/render/ZP260727ABC123",
"qr_content": "00020101021226670016ID.CO.QRIS.WWW.NOBU...",
"note": "Pembayaran Tagihan INV-1001",
"checkout_url": "https://pay.zannstore.com/invoice?reffID=ZP260727ABC123&payRef=HASH",
"expired_at": "2026-07-27 20:30:00",
"callback_url": "https://tokoanda.com/api/callback"
}
}
{
"status": true,
"message": "Berhasil membuat transaksi",
"data": {
"trx_svr": "ZP260727VA987",
"trx_id": "INV-1002",
"method_code": "BRIVA",
"method_name": "BANK RAKYAT INDONESIA VA",
"status": "Pending",
"amount": 50000,
"diterima": 50000,
"fee": 3500,
"type_fee": "user",
"virtual_account": "8881008123456789",
"note": "Pembayaran Tagihan INV-1002",
"checkout_url": "https://pay.zannstore.com/invoice?reffID=ZP260727VA987&payRef=HASH",
"created_at": "2026-07-27 20:00:00",
"expired_at": "2026-07-27 20:30:00",
"callback_url": "https://tokoanda.com/api/callback"
}
}
{
"status": true,
"message": "Berhasil membuat transaksi",
"data": {
"trx_svr": "ZP260727RET456",
"trx_id": "INV-1003",
"method_code": "ALFAMART",
"method_name": "RETAIL ALFAMART",
"status": "Pending",
"amount": 100000,
"diterima": 100000,
"fee": 2500,
"type_fee": "user",
"payment_code": "895012345678",
"note": "Pembayaran Tagihan INV-1003",
"checkout_url": "https://pay.zannstore.com/invoice?reffID=ZP260727RET456&payRef=HASH",
"created_at": "2026-07-27 20:00:00",
"expired_at": "2026-07-27 20:30:00",
"callback_url": "https://tokoanda.com/api/callback"
}
}
2. Cek Status Transaksi (`request: "status"`)
Gunakan parameter request = "status" untuk memeriksa status real-time transaksi yang pernah dibuat.
Parameter Request (POST /v1):
| Field Name | Type | Status | Deskripsi |
|---|---|---|---|
| request | string | REQUIRED | Wajib diisi string "status" |
| merchant | string | REQUIRED | Merchant ID terdaftar Anda (cth: MERCHANT123) |
| trx_id | string | REQUIRED | ID Transaksi dari merchant (cth: INV-1001) |
| signature | string | REQUIRED | Hash sha256(merchant + secret_key + trx_id) |
Contoh Response Check Status:
{
"status": true,
"msg": "Yeay, detail transaksi berhasil diambil",
"data": {
"trx_svr": "ZP260727ABC123",
"trx_id": "INV-1001",
"metode_name": "QRISNB",
"status": "Success",
"amount": 10000,
"fee": 70,
"diterima": 9930,
"note": "Pembayaran Tagihan INV-1001",
"type_fee": "user",
"issuer_bank": "QRIS",
"rrn": "REF123456789",
"paid_at": "2026-07-27 19:40:12",
"created_at": "2026-07-27 19:35:00",
"expired_at": "2026-07-27 20:05:00"
}
}
3. Batalkan Transaksi (`request: "cancel"`)
Gunakan parameter request = "cancel" untuk membatalkan transaksi yang berstatus Pending.
Pending yang dapat dibatalkan. Transaksi yang sudah Success, Expired, atau Canceled tidak dapat dibatalkan lagi.
Parameter Request (POST /v1):
| Field Name | Type | Status | Deskripsi |
|---|---|---|---|
| request | string | REQUIRED | Wajib diisi string "cancel" |
| merchant | string | REQUIRED | Merchant ID terdaftar Anda (cth: MERCHANT123) |
| trx_id | string | REQUIRED | ID Transaksi dari merchant (cth: INV-1001) |
| signature | string | REQUIRED | Hash sha256(merchant + secret_key + trx_id) |
4. Penarikan Otomatis (`request: "withdraw_auto"`)
Gunakan parameter request = "withdraw_auto" untuk mencairkan saldo merchant secara otomatis ke rekening bank atau e-wallet.
Parameter Request (POST /v1):
| Field Name | Type | Status | Deskripsi |
|---|---|---|---|
| request | string | REQUIRED | Wajib diisi string "withdraw_auto" |
| merchant | string | REQUIRED | Merchant ID terdaftar Anda |
| pin | string | REQUIRED | PIN Keamanan 6-digit akun Anda |
| amount | integer | REQUIRED | Nominal penarikan saldo (dalam Rupiah) |
| type_bank | string | REQUIRED | Jenis tujuan: "bank" atau "emoney" |
| tujuan | string | REQUIRED | Nomor rekening bank / nomor HP e-wallet tujuan |
| bank_code | string | REQUIRED | Kode bank / e-wallet (cth: BRI, BCA, DANA) |
| signature | string | REQUIRED | Hash sha256(merchant + pin) |
Spesifikasi Webhook Callback Notification
Ketika pembayaran berhasil dibayar (atau disimulasikan pada mode Sandbox), sistem ZANNPAY akan mengirimkan request POST notifikasi ke callback_url merchant.
Payload Notifikasi Webhook:
{
"data": {
"trx_svr": "ZP260727ABC123",
"trx_id": "INV-1001",
"status": "Success",
"amount": "10000",
"fee": "70",
"type_fee": "user",
"issuer_bank": "QRIS",
"rrn": "REF123456789",
"diterima": "10000",
"paid_at": "2026-07-27 19:40:12"
}
}
200 OK dan body JSON:
{"status": true} agar sistem mencatat bahwa notifikasi berhasil dikirimkan.
Daftar Metode Pembayaran & Bank (Dinamis)
Metode Pembayaran Aktif (Request `new`):
| Kode Payment | Nama Metode Pembayaran | Kategori | Biaya Fee | Status System |
|---|---|---|---|---|
| QRISNB | QRIS by National Nobu | QRIS / E-Wallet | 0.1% | ACTIVE |
| QRISCUSTOM | QRIS Custom Name | QRIS / E-Wallet | 0.7% + Rp 100 | ACTIVE |
| QRIS2 | QRIS Realtime Dynamic | QRIS / E-Wallet | 0.2% | ACTIVE |
| QRIS | QRIS by Danamon | QRIS / E-Wallet | 0.7% | ACTIVE |
| BNCVA | BANK NEO COMMERCE VA | Virtual Account | Rp 3.500 | ACTIVE |
| BRIVA | BANK RAKYAT INDONESIA VA | Virtual Account | Rp 3.500 | ACTIVE |
| BSIVA | BANK BSI VA | Virtual Account | Rp 3.500 | ACTIVE |
| BNIVA | BANK NEGARA INDONESIA VA | Virtual Account | Rp 3.500 | ACTIVE |
| DANAMONVA | DANAMON VA | Virtual Account | Rp 3.500 | ACTIVE |
| CIMBVA | CIMB NIAGA VA | Virtual Account | Rp 3.500 | ACTIVE |
| MANDIRIVA | BANK MANDIRI VA | Virtual Account | Rp 3.500 | ACTIVE |
| MAYBANKVA | BANK MAYBANK VA | Virtual Account | Rp 3.500 | ACTIVE |
| MUAMALATVA | BANK MUAMALAT VA | Virtual Account | Rp 3.500 | ACTIVE |
| PERMATAVA | BANK PERMATA VA | Virtual Account | Rp 3.500 | ACTIVE |
| SINARMASVA | SINARMAS VA | Virtual Account | Rp 3.500 | ACTIVE |
| ALFAMART | RETAIL ALFAMART | Retail / Paylink | Rp 2.500 | ACTIVE |
| INDOMARET | RETAIL INDOMARET | Retail / Paylink | Rp 2.500 | ACTIVE |
| QRIS3 | QRIS by DANA 0% | QRIS / E-Wallet | 0.1% | INACTIVE |
Daftar Status Transaksi
| Nama Status | Badge Indicator | Penjelasan & Keterangan |
|---|---|---|
| Pending | Pending | Transaksi telah dibuat dan sedang menunggu pembayaran dari pelanggan. |
| Success | Success | Transaksi telah berhasil dibayar, saldo diteruskan ke merchant, & callback dikirim. |
| Expired | Expired | Pembayaran tidak dilakukan hingga batas waktu kedaluwarsa (expired_time) habis. |
| Canceled | Canceled | Transaksi dibatalkan secara manual oleh merchant via API request: "cancel". |
Daftar Status Code & Exception Error
| Status HTTP | Pesan Error | Penyebab & Solusi Penanganan |
|---|---|---|
| 400 | Signature tidak valid | Perhitungan SHA256 signature tidak cocok. Pastikan rumus sha256(merchant + secret_key + trx_id) disusun tanpa spasi dengan huruf kecil. |
| 400 | trx_id sudah digunakan | trx_id yang Anda kirimkan sudah terdaftar pada sistem. Gunakan ID unik untuk setiap transaksi baru. |
| 403 | Akun merchant diblokir | Akun merchant Anda sedang dinonaktifkan oleh administrator. Hubungi tim support ZANNPAY. |
| 404 | Transaksi tidak ditemukan | trx_id tidak ditemukan pada sistem saat dipanggil untuk request status atau cancel. |