Lewati ke konten utama

Integration Flow Overview

High-level flow antara Bank / Acquirer dan platform Kesles Merchant.

Arsitektur

Bank / Acquirer Kesles Merchant
│ │
│ GET /api/psp/v1/merchants/ │
│ by-nmid/{nmid} ──────────────> │ verify HMAC (X-API-Key-ID)
│ │ filter by bank_code
│ <── 200 { merchant: {...} } ───── │
│ │
│ POST /psp/v1/events ─────────> │ verify HMAC (X-PSP-Key-ID)
│ { external_event_id, event_type, │ idempotency check
│ nmid, gross_amount, ... } │ route Flow A atau B
│ │
│ (merchant lifecycle webhook) │
│ <── POST /your-webhook-url ────── │ merchant diapprove /
│ │ suspend / terminate

Service & Port Map

ServicePortPrefix endpointKegunaan
dashboard_api8082/api/psp/v1/merchants/*Merchant lookup (read-only)
payment-service8085/psp/v1/events · /psp/v1/settlementsPayment event receiver

Flow 1 — Merchant Lookup (Outbound dari Bank)

Bank menerima transaksi QRIS → perlu data merchant dari Kesles berdasarkan NMID.

Langkah:

  1. Bank menerima NMID dari transaksi
  2. Bank memanggil GET /api/psp/v1/merchants/by-nmid/{nmid}
  3. Kesles memverifikasi HMAC (X-API-Key-ID / X-Timestamp / X-Signature) + IP allowlist
  4. Kesles mengembalikan data merchant (hanya merchant yang bank_code-nya cocok)
  5. Bank menggunakan data untuk proses transaksi / settlement
Bank Kesles Merchant (dashboard_api:8082)
│ │
├─ GET /by-nmid/ID102326873XXXX ──────> │
│ X-API-Key-ID: key-id │ 1. verify HMAC
│ X-Timestamp: 1716452580 │ 2. check IP allowlist
│ X-Signature: hmac-sha256=... │ 3. filter bank_code = BMRI
│ X-Request-ID: uuid-v4 │ 4. return merchant data
│ │
│ <── 200 { merchant: { nmid, name, │
│ status, kyc_status, ... } } │

Performance SLA:

  • p95 by-nmid < 50ms (indexed + Redis cache 30s)
  • p95 merchants/{id} < 100ms (Redis cache 30s)

Flow 2 — Forward Payment Event (Inbound ke Kesles)

Transaksi sukses di bank → PSP push event ke Kesles.

Format Payload Flat

Events API (/psp/v1/events) menggunakan payload flat — bukan nested envelope. Field external_event_id menggantikan field event_id lama. Lihat Events API untuk schema lengkap.

Bank / PSP Kesles (payment-service:8085)
│ │
├─ POST /psp/v1/events ───────────────> │
│ X-PSP-Key-ID: key-id │ 1. verify HMAC
│ X-PSP-Timestamp: <rfc3339> │ 2. idempotency check
│ X-PSP-Signature: <hex,noprefix> │ 3. routing Flow A atau B
│ { │ 4. INSERT payment.transactions
│ "external_event_id": "psp-evt-xyz" │ 5. push notification (async)
│ "event_type": "transaction.success"│
│ "nmid": "ID102326873XXXX", │
│ "gross_amount": 75000, │
│ ...flat fields... │
│ } │
│ │
│ <── 200 { status: "success", flow: "A", merchant_id } ┤

Flow A vs Flow B

Nilai nmidFlowAksi
NMID milik merchantA — customer membayar merchantINSERT payment.transactions + push notification ke merchant
ID9999999999999 (NMID korporat Kesles)B — merchant beli produk KeslesNotify order-service saja

Flow 3 — Delta Sync (Bulk Lookup)

Untuk initial load atau reconciliation, bank bisa fetch semua merchant aktif secara berkala.

Bank Kesles Merchant
│ │
├─ GET /merchants?limit=500 ──────────> │
│ &updated_since=2026-05-20T00:00:00Z │ filter: bank_code + updated_since
│ │
│ <── 200 { items: [...], │
│ pagination: { │
│ next_cursor: "...", │
│ has_more: true } } │
│ │
├─ GET /merchants?cursor=... ──────────>│ (next page)
│ <── 200 { items: [...], │
│ pagination: { has_more: false } }
Rekomendasi Sync
  • Initial load: fetch semua merchant sekali saat go-live
  • Delta sync: jalankan setiap 5–15 menit dengan updated_since = last_sync_time
  • Per-transaction lookup: gunakan by-nmid untuk real-time, jangan /merchants list

Flow 4 — Merchant Lifecycle Webhook (Inbound ke Bank)

Ketika status merchant berubah di Kesles (diapprove / suspend / terminate), Kesles akan mengirim webhook ke endpoint yang disepakati saat onboarding.

Kesles Merchant Bank Webhook Endpoint
│ │
│ (merchant diapprove / suspend / terminate) │
│ │
├─ POST {your-webhook-url} ─────────────────> │
│ X-Kesles-Signature: sha256=... │ 1. verify signature
│ X-Kesles-Timestamp: unix_secs │ 2. update local state
│ X-Kesles-Event-ID: evt-uuid │
│ Content-Type: application/json │
│ { │
│ "event_id": "evt-uuid-v4", │
│ "event": "merchant.suspended", │
│ "merchant": { "nmid": "ID102...", ... } │
│ "change": { "reason": "kyc_expired" } │
│ } │
│ <── 200 OK ──────────────────────────────── │

Lihat Events untuk payload lengkap dan daftar event types.

Retry Policy

Untuk request yang gagal (network error, 5xx), implementasikan:

AttemptDelay
1Langsung
21 detik
35 detik
430 detik
52 menit

Setelah 5 attempts gagal, log error dan alert. Jangan retry 4xx (kecuali 429).