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 Cek Profil (`profile`):
signature = sha256(merchant + secret_key + pin)
3. 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,
"msg": "Sukses membuat transaksi E-Wallet",
"data": {
"merchant": "ZN3UC49T",
"amount": 25000,
"fee": 625,
"total_amount": 25625,
"total_amount_bayar": 25625,
"diterima": 25000,
"type_fee": "user",
"prov_txid": "ZN1788400844894",
"trx_id": "INV-1004",
"method_code": "SHOPEEPAY",
"method_name": "SHOPEEPAY",
"checkout_url": "https://pay.zannstore.com/invoice?reffID=ZN1788400844894&payRef=HASH",
"payment_url": "https://pay.zannstore.com/invoice?reffID=ZN1788400844894&payRef=HASH",
"status": "Pending",
"expired_time": "2026-09-04 09:00:46",
"created_at": "2026-09-03 09:00:46"
}
}
{
"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.
trx_id). Jika melebihi batas, sistem akan merespon status 429 Too Many Requests beserta parameter retry_after. Transaksi lain milik merchant tidak akan terpengaruh.
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. Cek Profil Merchant (`request: "profile"`)
Gunakan parameter request = "profile" untuk mendapatkan informasi profil merchant, saldo kliring, saldo aktif/tersedia, email, dan nomor WhatsApp secara realtime.
Parameter Request (POST /v1):
| Field Name | Type | Status | Deskripsi |
|---|---|---|---|
| request | string | REQUIRED | Wajib diisi string "profile" |
| merchant | string | REQUIRED | Merchant ID terdaftar Anda (cth: MERCHANT123) |
| pin | string | REQUIRED | PIN Keamanan 6-digit akun Anda |
| secret_key | string | REQUIRED | Secret Key API milik merchant Anda |
| signature | string | REQUIRED | Hash sha256(merchant + secret_key + pin) |
Contoh Request (cURL):
curl -X POST https://pay.zannstore.com/api/v1 \
-H "Content-Type: application/json" \
-d '{
"request": "profile",
"merchant": "MERCHANT123",
"pin": "123456",
"secret_key": "YOUR_SECRET_KEY",
"signature": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}'
Contoh Response Sukses (200 OK):
{
"status": true,
"msg": "Yeay, data profile berhasil diambil",
"data": {
"nama_pemilik": "John Doe",
"merchant": "MERCHANT123",
"saldo_kliring": "50000.00",
"saldo_tersedia": "1500000.00",
"whatsapp": "081234567890",
"email": "[email protected]",
"created_at": "2026-01-01 10:00:00"
}
}
5. List Metode Pembayaran (`request: "payment_methods"`)
Gunakan endpoint ini untuk mendapatkan seluruh daftar metode pembayaran (baik berstatus aktif maupun nonaktif), fee admin, batas settlement, status ketersediaan, URL logo resmi (WebP), serta instruksi/panduan pembayaran jika diminta.
429 Too Many Requests beserta waktu jeda (retry_after).
Parameter Request (POST /v1):
| Field Name | Type | Status | Deskripsi |
|---|---|---|---|
| request | string | REQUIRED | Wajib diisi string "payment_methods" (atau "methods") |
| merchant | string | REQUIRED | Merchant ID terdaftar Anda (cth: MERCHANT123) |
| signature | string | REQUIRED | Hash SHA256: sha256(merchant + secret_key) |
| panduan | boolean | OPSIONAL | Set true untuk menyertakan instruksi/panduan cara bayar lengkap |
Contoh Request Payload (POST /v1):
curl -X POST https://pay.zannstore.com/v1 \
-H "Content-Type: application/json" \
-d '{
"request": "payment_methods",
"merchant": "MERCHANT123",
"signature": "sha256(merchant + secret_key)",
"panduan": true
}'
Contoh Response Sukses (200 OK):
{
"status": true,
"message": "Berhasil mengambil daftar metode pembayaran",
"data": [
{
"code": "BCAVA",
"name": "BANK BCA VA",
"category": "Virtual Account",
"fee": 4500,
"fee_format": "Rp 4.500",
"settlement": "H+1",
"status": "aktif",
"logo": "https://cdn.zannstore.com/assets/project/pay.zannstore.com/methods/bcava_v3.webp",
"panduan": {
"judul": "Bank BCA Virtual Account",
"langkah": [
"1. Buka aplikasi BCA mobile atau KlikBCA",
"2. Pilih menu Transfer > BCA Virtual Account",
"3. Masukkan nomor Virtual Account yang tertera",
"4. Periksa nominal pembayaran lalu konfirmasi dengan PIN"
],
"catatan": "Pembayaran akan diverifikasi secara otomatis dalam beberapa detik."
}
},
{
"code": "QRIS2",
"name": "QRIS Realtime (Fast)",
"category": "QRIS",
"fee": 0.7,
"fee_format": "0.7%",
"settlement": "Instant",
"status": "nonaktif",
"logo": "https://cdn.zannstore.com/assets/project/pay.zannstore.com/methods/qris_cdn.webp",
"panduan": null
}
]
}
6. 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.
trx_svr, trx_id, status, amount, fee, type_fee, diterima, paid_at, dan signature) bersifat SAMA dan KONSISTEN di semua metode pembayaran. Metode spesifik seperti Virtual Account atau Retail menambahkan field relevan (seperti va_code, va_number, atau payment_code).
Pilih Payload Notifikasi Berdasarkan Metode Pembayaran:
{
"data": {
"trx_svr": "ZP260727ABC123",
"trx_id": "INV-1001",
"method_code": "QRISNB",
"status": "Success",
"amount": "10000",
"fee": "70",
"type_fee": "user",
"issuer_bank": "GOPAY",
"rrn": "REF123456789",
"diterima": "10000",
"paid_at": "2026-07-27 19:40:12",
"signature": "c3f7d0936d2b194aabf9de55aea53c21aba21daeebb263b9bffd7f7b3af0ffb0"
}
}
{
"data": {
"trx_svr": "ZP260727VA987",
"trx_id": "INV-1002",
"status": "Success",
"amount": "50000",
"fee": "3500",
"type_fee": "user",
"issuer_bank": "BRI",
"rrn": "REF987654321",
"diterima": "50000",
"paid_at": "2026-07-27 20:05:00",
"va_code": "BRIVA",
"va_number": "8881008123456789",
"customer_name": "JOHN DOE",
"signature": "01c617b2002f734df85204304e3816bd10f76491a36118e8cb1b57ad7782d635"
}
}
{
"status": "Success",
"merchant": "ZN3UC49T",
"trx_id": "INV-1004",
"prov_txid": "ZN1788400844894",
"amount": 25000,
"fee": 625,
"diterima": 25000,
"type_fee": "user",
"paid_at": "2026-09-03 09:05:00",
"method": "SHOPEEPAY",
"rrn": "41233",
"signature": "c89f5...d4b2"
}
{
"data": {
"trx_svr": "ZP260727RET456",
"trx_id": "INV-1003",
"status": "Success",
"amount": "100000",
"fee": "2500",
"type_fee": "user",
"issuer_bank": "ALFAMART",
"rrn": "REF456789123",
"diterima": "100000",
"paid_at": "2026-07-27 20:10:00",
"va_code": "ALFAMART",
"va_number": "895012345678",
"customer_name": "JOHN DOE",
"signature": "7d9a8c2f10b3e5a6c4d7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9"
}
}
Tabel Deskripsi Parameter Webhook:
| Field Name | Type | Kategori | Deskripsi & Contoh |
|---|---|---|---|
| trx_svr | string | UMUM | ID unik transaksi dari server ZANNPAY (cth: ZP260727ABC123) |
| trx_id | string | UMUM | ID Transaksi Invoice milik merchant (cth: INV-1001) |
| status | string | UMUM | Status transaksi, bernilai Success saat lunas |
| amount | string | UMUM | Nominal tagihan transaksi (cth: "10000") |
| fee | string | UMUM | Nominal biaya admin transaksi (cth: "70") |
| type_fee | string | UMUM | Pembebanan biaya: user atau merchant |
| diterima | string | UMUM | Total saldo bersih yang diterima merchant (cth: "10000") |
| paid_at | string | UMUM | Waktu pembayaran terverifikasi (cth: "2026-07-27 19:40:12") |
| signature | string | UMUM | Hash verifikasi keamanan: sha256(merchant + secret_key + buyer_txid) |
| method_code / va_code | string | KHUSUS | Kode metode pembayaran (cth: QRISNB, BRIVA, ALFAMART) |
| issuer_bank / va_number | string | KHUSUS | Penerbit/Nomor Rekening/Kode Bayar (cth: GOPAY, 888100..., 89501...) |
| customer_name | string | OPSIONAL | Nama pelanggan / pembayar jika tersedia (cth: JOHN DOE) |
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.2% | ACTIVE |
| QRISCUSTOM | QRIS Custom Name | QRIS / E-Wallet | 0.7% + Rp 100 | ACTIVE |
| QRIS2 | QRIS Realtime Dynamic | QRIS / E-Wallet | 0.4% | ACTIVE |
| QRISSPY | QRIS ShopeePay | QRIS / E-Wallet | 0.1% | ACTIVE |
| QRIS | QRIS by Danamon | QRIS / E-Wallet | 0.7% | ACTIVE |
| BNCVA | BANK NEO COMMERCE VA | Virtual Account | Rp 3.500 | ACTIVE |
| BCAVA | BANK BCA VA | Virtual Account | Rp 4.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 |
| SHOPEEPAY | ShopeePay (E-Wallet) | Retail / Paylink | 2.9% | ACTIVE |
| OVO | OVO (Push Payment) | Retail / Paylink | 2.5% | ACTIVE |
| LINKAJA | LinkAja (E-Wallet) | Retail / Paylink | 2.5% | 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. |