Skip to main content

Webhook

Kesles dapat mengirimkan event realtime ke endpoint HTTPS milik Anda setiap kali terjadi perubahan status pada merchant di portfolio Anda. Ini memungkinkan sistem Anda bereaksi langsung tanpa harus polling API.

Cara Kerja

Kesles Backend

├─ Event terjadi (mis. transaksi masuk, status merchant berubah)


partner_service mengambil webhook_url dari konfigurasi partner


POST {webhook_url}
Headers: X-Kesles-Signature, Content-Type: application/json
Body: { "event_type": "...", "data": {...}, "timestamp": "..." }


Server Anda merespons 2xx dalam 10 detik

Kesles mencatat setiap percobaan pengiriman (sukses maupun gagal) di log internal. Webhook bersifat best-effort — tidak ada retry otomatis saat ini; pastikan endpoint Anda reliable dan merespons cepat.

Konfigurasi Webhook

Webhook URL dan secret dikonfigurasi oleh tim Kesles saat onboarding partner. Untuk mengubah URL atau secret, hubungi support@kesles.com atau minta tim Kesles via dashboard internal.

info

Partner API publik saat ini tidak menyediakan endpoint self-service untuk mengubah webhook config. Ini adalah keterbatasan yang direncanakan untuk diatasi di versi mendatang.

Verifikasi Tanda Tangan

Setiap request webhook dari Kesles menyertakan header X-Kesles-Signature. Nilai header ini adalah HMAC-SHA256 dari request body menggunakan webhook secret yang diberikan saat onboarding.

Format Header

X-Kesles-Signature: sha256=<hex_digest>

Cara Verifikasi (Go)

import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
)

func verifyWebhookSignature(body []byte, secret, signature string) bool {
mac := hmac.New(sha256.New, []byte(secret))
mac.Write(body)
expected := "sha256=" + hex.EncodeToString(mac.Sum(nil))
return hmac.Equal([]byte(expected), []byte(signature))
}

Cara Verifikasi (Python)

import hmac
import hashlib

def verify_webhook_signature(body: bytes, secret: str, signature: str) -> bool:
expected = "sha256=" + hmac.new(
secret.encode(), body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)
warning

Selalu gunakan constant-time comparison (hmac.Equal / hmac.compare_digest) saat membandingkan signature — bukan == biasa — untuk mencegah timing attack.

Format Payload

{
"event_type": "transaction.completed",
"event_id": "evt_01j2abcd…",
"timestamp": "2026-06-07T10:30:00+07:00",
"partner_id": "uuid-partner",
"data": {
"merchant_id": "uuid-merchant",
"merchant_code": "MRC-XXXXX",
...
}
}
FieldTipeDeskripsi
event_typestringJenis event (lihat katalog di bawah)
event_idstringID unik event — gunakan untuk idempotency
timestampRFC3339Waktu event terjadi (timezone +07:00)
partner_idUUIDID partner penerima
dataobjectPayload spesifik per event type

Katalog Event

Event yang akan Anda terima bergantung pada scope partner yang dikonfigurasi saat onboarding. Berikut event-event yang saat ini didukung:

Transaksi

Event TypeTriggerField utama di data
transaction.completedPembayaran QRIS/terminal berhasilmerchant_id, amount, currency, terminal_id, reference_id
transaction.failedPembayaran gagal / expiredmerchant_id, amount, failure_reason
transaction.refundedRefund berhasil diprosesmerchant_id, original_transaction_id, refund_amount

Status Merchant

Event TypeTriggerField utama di data
merchant.status_changedStatus merchant berubah (active, suspended, pending_review, dll.)merchant_id, merchant_code, old_status, new_status
merchant.registeredMerchant baru di-refer oleh partner ini selesai registrasimerchant_id, merchant_code, referral_code
info

Daftar event type di atas adalah event yang saat ini tersedia. Event type baru dapat ditambahkan seiring pengembangan platform — perubahan ini akan dikomunikasikan via email ke alamat kontak partner yang terdaftar.

Keamanan Endpoint

Pastikan endpoint webhook Anda memenuhi persyaratan berikut:

  1. HTTPS wajib — Kesles menolak konfigurasi URL HTTP atau IP privat
  2. Respons cepat — Kembalikan 200 OK dalam 10 detik. Jika processing membutuhkan waktu lebih, queue dulu dan proses secara async
  3. Idempotent — Simpan event_id dan abaikan event duplikat (Kesles bisa mengirim ulang dalam kasus network failure)
  4. Verifikasi signature — Selalu validasi X-Kesles-Signature sebelum memproses payload

Troubleshooting

Endpoint Tidak Menerima Event

  • Pastikan URL dapat diakses dari internet (bukan localhost atau IP privat)
  • Pastikan firewall tidak memblokir koneksi masuk dari IP Kesles
  • Hubungi tim Kesles untuk memeriksa log delivery terbaru

Signature Verification Gagal

  • Pastikan Anda menggunakan raw request body bytes (sebelum parsing JSON) sebagai input HMAC
  • Pastikan secret yang digunakan sesuai dengan yang dikonfigurasi tim Kesles
  • Jangan trim whitespace atau modifikasi body sebelum verifikasi

Event Duplikat

Implementasi idempotency dengan menyimpan event_id yang sudah diproses:

INSERT INTO processed_webhook_events (event_id, processed_at)
VALUES ($1, NOW())
ON CONFLICT (event_id) DO NOTHING
RETURNING event_id

Jika RETURNING tidak mengembalikan row, event sudah pernah diproses — skip.