Flow paling umum:
- Buat transaksi (
request=new) → dapatqr_url/qr_content - Tampilkan QR ke user
- Terima callback saat sukses (recommended) atau cek status (
request=status) - Jika perlu, lakukan withdraw saldo
curl -X POST "https://pay.zannstore.com/v1/" \ -H "Content-Type: application/x-www-form-urlencoded" \ --data-urlencode "merchant=ZNxxxx" \ --data-urlencode "trx_id=TX-2609FFKJ" \ --data-urlencode "request=new" \ --data-urlencode "payment=QRIS" \ --data-urlencode "amount=10000" \ --data-urlencode "note=Pembelian paket A" \ --data-urlencode "expired_time=30m" \ --data-urlencode "type_fee=user" \ --data-urlencode "signature=SHA256(merchant+secret_key+trx_id)"
signature adalah hash SHA256 sesuai formula (lihat section Auth & Signature).Signature digunakan untuk memverifikasi request. Pastikan secret_key disimpan aman di server (jangan di client).
| Request | Formula Signature | Contoh |
|---|---|---|
| new / status | SHA256(merchant + secret_key + trx_id) |
SHA256("ZNxxxx"+"SECRET"+"TX-001") |
| profile | SHA256(merchant + secret_key + pin) |
SHA256("ZNxxxx"+"SECRET"+"123456") |
| withdraw / withdraw_auto | SHA256(merchant + pin) |
SHA256("ZNxxxx"+"123456") |
signature=SHA256(merchant+secret_key+trx_id)
Body (x-www-form-urlencoded)
| Field | Wajib | Deskripsi | Contoh |
|---|---|---|---|
merchant | Ya | Kode merchant | ZNxxxx |
trx_id | Ya | ID unik dari sistem kamu | TX-2609FFKJ |
request | Ya | Gunakan new | new |
payment | Ya | Jenis pembayaran | QRIS |
amount | Ya | Nominal transaksi | 10000 |
note | Opsional | Catatan transaksi | Order #123 |
expired_time | Ya | Format: 1j atau 30m | 30m |
type_fee | Ya | user atau merchant | user |
signature | Ya | SHA256(merchant+secret_key+trx_id) | … |
POST https://pay.zannstore.com/v1/ merchant=ZNxxxx trx_id=TX-2609FFKJ request=new payment=QRIS amount=10000 note=Order%20%23123 expired_time=30m type_fee=user signature=SHA256(merchant+secret_key+trx_id)
{
"status": true,
"message": "Berhasil membuat transaksi",
"data": {
"trx_svr": "ZN1751695793",
"trx_id": "TRX1751695792",
"status": "Pending",
"amount": 100,
"diterima": 100,
"fee": 1,
"type_fee": "user",
"qr_url": "https://pay.zannstore.com/qris/ZN1751695793.png",
"qr_content": "000201...",
"expired_at": "2025-07-05 17:09:55"
}
}
Body (x-www-form-urlencoded)
| Field | Wajib | Deskripsi | Contoh |
|---|---|---|---|
merchant | Ya | Kode merchant | ZNxxxx |
trx_id | Ya | ID transaksi dari sistem kamu | TRX1751705075 |
request | Ya | Gunakan status | status |
signature | Ya | SHA256(merchant+secret_key+trx_id) | … |
{
"status": true,
"message": "Status transaksi berhasil diambil.",
"data": {
"trx_svr": "ZN1751705075",
"trx_id": "TRX1751705075",
"status": "Success",
"amount": "1000",
"fee": "7",
"type_fee": "merchant",
"issuer_bank": "Dana",
"rrn": "518649614790",
"diterima": "993",
"paid_at": "2025-07-05 15:45:13"
}
}
| Field | Wajib | Deskripsi | Contoh |
|---|---|---|---|
merchant | Ya | Kode merchant | ZNYWSJ058 |
pin | Ya | PIN rahasia merchant | 123456 |
request | Ya | Gunakan profile | profile |
signature | Ya | SHA256(merchant+secret_key+pin) | … |
{
"status": true,
"msg": "Data ditemukan.",
"data": {
"nama_pemilik": "Zannstore",
"merchant": "ZNYWSJ058",
"saldo_kliring": "Rp 993",
"withdraw": "Rp 2.979",
"whatsapp": "6285174279764",
"created_at": "2025-07-04 09:49:28"
}
}
⚠️ E-wallet: Rp1.500 • Bank: Rp3.000
| Field | Wajib | Deskripsi | Contoh |
|---|---|---|---|
merchant | Ya | Kode merchant | ZNXXXX |
pin | Ya | PIN rahasia | 123456 |
request | Ya | Gunakan withdraw_auto | withdraw_auto |
amount | Ya | Nominal penarikan | 50000 |
type_bank | Ya | bank atau emoney | bank |
bank_code | Ya | Kode bank/e-money | 002 / DANA |
tujuan | Ya | No rekening / No HP | 901341077047 |
signature | Ya | SHA256(merchant+pin) | … |
{
"status": "Success",
"msg": "Withdraw berhasil diproses.",
"trx_id": "WD687271a36121b",
"nominal": 10000,
"biaya": 3000,
"total": 13000,
"saldo_awal": 13500,
"saldo_akhir": 500,
"tujuan": "901341077047",
"jenis": "BANK",
"bank_code": "535",
"account_name": "NI LUH SUKERTHI",
"bank_name": "SEABANK INDONESIA"
}
⚠️ E-wallet: Rp1.000 (Min 15.000) • Bank: Rp2.000 (Min 15.000)
| Field | Wajib | Deskripsi | Contoh |
|---|---|---|---|
merchant | Ya | Kode merchant | ZNXXXX |
pin | Ya | PIN merchant | 123456 |
request | Ya | Gunakan withdraw | withdraw |
amount | Ya | Nominal | 15000 |
tujuan | Ya | Format tujuan | OVO | 085174667722 |
signature | Ya | SHA256(merchant+pin) | … |
{
"status": true,
"msg": "Withdraw berhasil diproses.",
"trx_id": "WD68690055300e7"
}
Setelah pembayaran QRIS sukses, sistem gateway akan mengirim notifikasi ke callback_url kamu.
Pastikan endpoint callback kamu cepat, aman, dan selalu membalas HTTP 200.
{
"data": {
"trx_svr": "ZN1751705075",
"trx_id": "INV-00123",
"status": "Success",
"amount": "10000",
"fee": "500",
"diterima": "9500",
"type_fee": "user",
"issuer_bank": "Dana",
"rrn": "123456789012",
"paid_at": "2025-07-06 14:15:00"
}
}
{
"status": true,
"msg": "Callback diterima"
}
<?php
$data = json_decode(file_get_contents("php://input"), true);
if (!isset($data["data"]["status"])) {
http_response_code(400);
echo json_encode(["status" => false, "msg" => "Invalid payload"]);
exit;
}
if ($data["data"]["status"] === "Success") {
// TODO: update database, set paid, kirim notifikasi, dsb
http_response_code(200);
echo json_encode(["status" => true, "msg" => "Callback diterima"]);
} else {
http_response_code(400);
echo json_encode(["status" => false, "msg" => "Invalid status"]);
}
?>
trx_id sudah diproses atau belum).
- Jangan taruh secret_key di frontend — generate signature di server.
- Gunakan callback untuk update status real-time, polling hanya fallback.
- Idempotency: transaksi dengan
trx_idsama jangan diproses dua kali. - Timeout & retry: callback endpoint harus cepat (mis. < 2 detik), kalau perlu proses berat, antrikan (queue).
- Validasi input: amount integer, expired_time format benar, type_fee hanya
user/merchant. - Logging: simpan request + response untuk audit & troubleshooting.