Merchant Lifecycle Events
Kesles mengirim webhook ke endpoint bank ketika status merchant berubah. Bank wajib merespons dengan 200 OK dalam 10 detik.
Halaman ini mendokumentasikan outbound webhook dari Kesles ke bank (lifecycle merchant). Untuk arah sebaliknya — meneruskan payment event dari bank ke Kesles — lihat Events API di bawah atau Endpoint List.
Verifikasi Signature Webhook
Setiap lifecycle webhook dari Kesles ke bank menyertakan header:
X-Kesles-Signature: sha256=<signature>
X-Kesles-Timestamp: <unix_seconds>
X-Kesles-Event-ID: <uuid — untuk idempotency>
Verifikasi dengan cara yang sama seperti outbound request (lihat Integration Contract).
Tolak webhook yang |now - X-Kesles-Timestamp| > 300 detik untuk mencegah replay attack.
Tipe Event Lifecycle Merchant
| Event | Trigger |
|---|---|
merchant.activated | Merchant pertama kali diaktifkan (KYC verified + NMID assigned) |
merchant.suspended | Merchant di-suspend (KYC expired, violation, dll) |
merchant.reactivated | Merchant di-reaktivasi setelah suspend |
merchant.terminated | Merchant dihapus permanen dari platform Kesles |
merchant.profile_updated | Nama, alamat, atau data KYC diperbarui |
Format Payload Lifecycle
Semua event lifecycle menggunakan envelope yang sama:
{
"event_id": "evt-uuid-v4",
"event": "merchant.activated",
"occurred_at": "2026-05-21T10:00:00Z",
"merchant": {
"id": "kesles-merchant-uuid",
"nmid": "ID102326873XXXX",
"bank_code": "BMRI",
"merchant_name": "Warung Pak Budi",
"legal_name": "CV Sumber Rejeki",
"status": "active",
"kyc_status": "verified",
"category_code": "5411",
"phone": "081234567890",
"address": {
"city": "Makassar",
"province": "Sulawesi Selatan",
"country": "ID"
},
"updated_at": "2026-05-21T10:00:00Z"
},
"change": {
"field": "status",
"old_value": "inactive",
"new_value": "active",
"reason": "kyc_verified"
}
}
merchant.suspended
{
"event_id": "evt-uuid-v4",
"event": "merchant.suspended",
"occurred_at": "2026-05-21T11:00:00Z",
"merchant": { "...": "sama seperti di atas" },
"change": {
"field": "status",
"old_value": "active",
"new_value": "suspended",
"reason": "kyc_expired"
}
}
reason untuk merchant.suspended:
| Reason | Keterangan |
|---|---|
kyc_expired | Dokumen KYC kadaluarsa |
violation | Pelanggaran terms of service |
operator_action | Disuspend manual oleh operator Kesles |
inactivity | Tidak ada transaksi selama 6 bulan |
merchant.terminated
{
"event_id": "evt-uuid-v4",
"event": "merchant.terminated",
"occurred_at": "2026-05-21T12:00:00Z",
"merchant": {
"id": "kesles-merchant-uuid",
"nmid": "ID102326873XXXX",
"bank_code":"BMRI",
"status": "deleted"
},
"change": {
"field": "status",
"old_value": "active",
"new_value": "deleted",
"reason": "merchant_request"
}
}
Setelah merchant.terminated, NMID tidak lagi valid. Bank harus menolak transaksi dengan NMID tersebut dan menghapus dari local cache.
Payment Events API (Bank → Kesles)
PSP meneruskan payment event ke Kesles via payment-service di POST /psp/v1/events.
Auth Headers (Events API)
X-PSP-Key-ID: {key_id}
X-PSP-Timestamp: {RFC3339 timestamp — contoh 2026-06-08T10:30:00+07:00}
X-PSP-Signature: {raw hex signature — tanpa prefix}
X-Request-ID: {uuid}
Format Signed Payload
Events API signed_payload: {method}\n{path}\n{timestamp}\n{body} — timestamp adalah nilai RFC3339 yang sama dengan header X-PSP-Timestamp.
POST
/psp/v1/events
2026-06-08T10:30:00+07:00
{"external_event_id":"psp-evt-abc-123",...}
Tipe Payment Event
| event_type | Keterangan |
|---|---|
transaction.success | Transaksi baru berhasil di bank |
transaction.failed | Transaksi gagal diproses |
transaction.cancelled | Transaksi dibatalkan sebelum selesai |
transaction.refunded | Refund transaksi sebelumnya |
transaction.reversed | Pembalikan (reversal) transaksi |
qris.payment.success | Pembayaran QRIS berhasil |
qris.payment.failed | Pembayaran QRIS gagal |
qris.payment.refunded | Refund pembayaran QRIS |
nmid.status_changed | Bank suspend atau aktifkan NMID |
Payload transaction.success
{
"external_event_id": "psp-evt-abc-123",
"event_type": "transaction.success",
"nmid": "ID102326873XXXX",
"gross_amount": 75000,
"transaction_code": "TRX-PSP-20260523-001",
"reference_number": "BI20260523142345XXXX",
"rrn": "301234567890",
"transaction_at": "2026-05-23T14:23:45Z",
"payer_bank_code": "014",
"payer_bank_name": "BCA",
"payer_name_masked": "Budi S.",
"mdr_fee_bank": 300,
"switching_fee": 150,
"platform_fee": 75,
"status": "success"
}
Payload nmid.status_changed
{
"external_event_id": "psp-evt-nmid-789",
"event_type": "nmid.status_changed",
"nmid": "ID102326873XXXX",
"nmid_new_status": "suspended",
"nmid_old_status": "active",
"nmid_reason": "fraud_detected",
"transaction_at": "2026-05-23T12:00:00Z"
}
Idempotency (Lifecycle Webhook dari Kesles)
Gunakan event_id dari header X-Kesles-Event-ID untuk deduplikasi. Jika webhook yang sama diterima dua kali, proses sekali saja — kembalikan 200 OK untuk keduanya.
Retry dari Kesles
Jika endpoint bank tidak merespons 200 dalam 10 detik, Kesles akan retry:
| Attempt | Delay |
|---|---|
| 2 | 30 detik |
| 3 | 5 menit |
| 4 | 30 menit |
| 5 | 2 jam |
Setelah 5 kali gagal, tim Kesles akan mengirim notifikasi manual ke technical PIC.
Registrasi Webhook Endpoint
Daftarkan URL webhook kamu ke tim Kesles saat onboarding. URL harus:
- HTTPS dengan certificate valid
- Merespons
200 OKdalam 10 detik - Menerima
Content-Type: application/json