Skip to main content

Event Webhook

IsiKuota mengirim dua tipe event lewat mekanisme webhook yang sama: transaction.updated (order prabayar/game/pascabayar) dan deposit.updated (deposit saldo via API). Cek nilai event untuk tahu jenis notifikasinya, lalu tentukan tindakan Anda berdasarkan data.status — bukan cuma dari nama event.

Kenapa cuma dua event?

Dengan event yang konsisten per domain (transaksi vs deposit), integrasi Anda lebih sederhana: cukup baca event untuk routing, lalu data.status untuk detail penanganan. Tidak perlu menangani banyak nama event yang berbeda-beda per status.

Event transaction.updated​

Dikirim setiap kali status order prabayar/game/pascabayar berubah.

Nilai data.status​

StatusArti
pendingTransaksi sedang diproses
successTransaksi berhasil — sn terisi (untuk produk yang punya SN)
failedTransaksi gagal — saldo dikembalikan otomatis

Contoh Payload per Status​

Dikirim saat transaksi baru dibuat / sedang diproses.

{
"event": "transaction.updated",
"event_id": "evt_01J3K8M2N4P5Q6R7S8T9U0V1W2",
"timestamp": "2025-01-15T14:29:55+07:00",
"data": {
"ref_id": "ORDER-2025-001",
"status": "pending",
"product_code": "TSEL10",
"product_name": "Telkomsel 10.000",
"customer_no": "081234567890",
"price": 11500,
"sn": null,
"message": "Transaksi sedang diproses",
"balance": 489000,
"created_at": "2025-01-15T14:29:55+07:00",
"updated_at": "2025-01-15T14:29:55+07:00"
}
}

Field Data Payload​

FieldTipeKeterangan
eventstringSelalu transaction.updated
event_idstringID unik per pengiriman (ULID), untuk deduplikasi
timestampstringWaktu event dikirim (ISO 8601, +07:00)
data.ref_idstringID referensi dari sistem Anda
data.statusstringpending / success / failed
data.product_codestringKode produk
data.product_namestringNama produk
data.customer_nostringNomor tujuan transaksi
data.pricenumberHarga transaksi (Rp)
data.snstring|nullSerial number (null jika belum / tidak ada)
data.messagestring|nullPesan status dari provider
data.balancenumberSaldo akun Anda setelah transaksi
data.created_atstringWaktu transaksi dibuat
data.updated_atstringWaktu update terakhir

Event deposit.updated​

Dikirim setiap kali status deposit saldo yang dibuat lewat POST /v1/deposit (cmd=create) mencapai status final. Berbeda dari transaction.updated, event ini tidak dikirim untuk status pending — hanya saat deposit selesai diproses (oleh provider pembayaran, oleh sistem karena kedaluwarsa, atau oleh Anda sendiri lewat cmd=cancel).

Mengaktifkan webhook untuk deposit

Event ini dikirim ke URL webhook yang sama dengan transaction.updated (satu callback_url per akun, diatur di Pengaturan → API → Webhook). Tidak ada konfigurasi terpisah — begitu URL webhook Anda terdaftar, kedua jenis event otomatis terkirim ke sana.

Nilai data.status​

StatusArti
successDeposit berhasil, saldo sudah ditambahkan
failedDeposit gagal (mis. gateway pembayaran menolak permintaan)
expiredBatas waktu pembayaran terlewati tanpa pembayaran masuk
cancelledDibatalkan lewat cmd=cancel atau oleh admin

Contoh Payload​

{
"event": "deposit.updated",
"event_id": "evt_01J3K8M2N4P5Q6R7S8T9U0V1W5",
"timestamp": "2026-09-20T00:55:06+07:00",
"data": {
"ref_id": "DEP20260920005429RKXIEJ",
"status": "success",
"amount": 100000,
"pay_amount": 100700,
"get_amount": 100000,
"deposit_method_name": "QRIS - Semua E-Wallet & Bank",
"deposit_channel": "QRIS",
"note": null,
"balance": 250000,
"paid_at": "2026-09-20T00:55:06+07:00",
"created_at": "2026-09-20T00:54:29+07:00",
"updated_at": "2026-09-20T00:55:06+07:00"
}
}

Field Data Payload​

FieldTipeKeterangan
eventstringSelalu deposit.updated
event_idstringID unik per pengiriman (ULID), untuk deduplikasi
timestampstringWaktu event dikirim (ISO 8601, +07:00)
data.ref_idstringID referensi deposit — sama dengan ref_id dari cmd=create
data.statusstringsuccess / failed / expired / cancelled
data.amountnumberNominal deposit yang diminta — belum termasuk biaya admin/kode unik — sama seperti field amount pada response Deposit Saldo
data.pay_amountnumberNominal final yang harus dibayar/ditransfer (= amount + biaya admin + kode unik jika berlaku). Gunakan field ini untuk verifikasi pembayaran, bukan data.amount
data.get_amountnumberNominal yang dikreditkan ke saldo Anda — bisa lebih besar dari data.amount kalau metode memakai kode unik (tidak termasuk biaya admin)
data.deposit_method_namestringNama metode deposit yang dipakai
data.deposit_channelstring|nullChannel spesifik (mis. QRIS, VA BCA)
data.notestring|nullCatatan tambahan, mis. alasan gagal dari gateway
data.balancenumberSaldo akun Anda setelah deposit diproses
data.paid_atstring|nullWaktu pembayaran diterima (null jika belum/tidak pernah dibayar)
data.created_atstringWaktu deposit dibuat
data.updated_atstringWaktu status terakhir diperbarui

Contoh Handler Berdasarkan Status​

info

Contoh di bawah fokus pada logika penanganan status setelah payload diterima, untuk event transaction.updated. Untuk verifikasi X-Isikuota-Signature, lihat Verifikasi Signature. Karena kedua event dikirim ke URL yang sama, cek field event lebih dulu sebelum menangani data.status — lihat contoh routing di bawah.

<?php
$payload = json_decode(file_get_contents('php://input'), true);

switch ($payload['event']) {
case 'transaction.updated':
handleTransactionUpdated($payload['data']);
break;
case 'deposit.updated':
handleDepositUpdated($payload['data']);
break;
}
switch (payload.event) {
case 'transaction.updated':
handleTransactionUpdated(payload.data);
break;
case 'deposit.updated':
handleDepositUpdated(payload.data);
break;
}

Contoh berikut mengasumsikan Anda sudah routing berdasarkan event seperti di atas, dan sekarang berada di dalam handleTransactionUpdated():

<?php
$payload = json_decode(file_get_contents('php://input'), true);

$data = $payload['data'];
$refId = $data['ref_id'];

switch ($data['status']) {
case 'success':
// Update status order di DB, kirim SN ke user
updateOrder($refId, 'success', $data['sn']);
notifyUser($refId, $data['sn']);
break;

case 'failed':
// Update status, notifikasi user gagal
updateOrder($refId, 'failed');
notifyUserFailed($refId, $data['message']);
break;

case 'pending':
// Opsional: catat bahwa transaksi sedang diproses
updateOrder($refId, 'pending');
break;
}

http_response_code(200);
echo json_encode(['status' => 'ok']);
Idempoten

Gunakan event_id untuk mendeteksi pengiriman ganda. Simpan event_id yang sudah diproses, dan lewati jika menerima ulang.