Untuk menjaga integritas komunikasi webhook di backend Cowart, Anda perlu menegakkan kontrak API yang eksplisit, memverifikasi payload, menghindari eksekusi ganda melalui idempotensi, lalu menerapkan retry/backoff yang terkendali. Artikel ini langsung membahas bagaimana mendesain alur tersebut secara praktis dengan pendekatan tangguh terhadap payload, signature, dan observabilitas.

Menentukan kontrak webhook API yang jelas

Kontrak webhook harus menjadi dokumen teknis yang menyatakan:

  • Endpoint HTTP target (misalnya POST /cowart/api/webhook/event).
  • Struktur payload JSON lengkap dengan tipe data, field wajib, serta contoh valid.
  • Kode status HTTP untuk respon sukses/gagal (200 untuk diterima, 4xx untuk invalid, 5xx untuk retry).
  • Header tambahan seperti X-Signature dan X-Event-Id.

Dokumentasi ini harus disimpan dalam repositori atau sistem API management (OpenAPI/AsyncAPI) agar pengembang consumer dan provider mengutipnya secara konsisten.

Contoh struktur HTTP request/response

POST /cowart/api/webhook/event HTTP/1.1
Host: webhook.cowart.internal
Content-Type: application/json
X-Event-Id: a1d2e3f4-7890
X-Signature: sha256=ab12…

{
  "event_type": "payment.completed",
  "timestamp": "2025-03-01T12:34:56Z",
  "data": {
    "order_id": "ORD-123",
    "amount": 150000
  }
}

HTTP/1.1 200 OK
Content-Type: application/json

{"status":"accepted"}

Pastikan respons menyertakan status dan pesan ringkas agar provider webhook mengetahui apakah event sudah dikelola.

Autentikasi dan verifikasi payload

Bubble security dimulai dengan autentikasi payload. Cowart menggunakan shared secret untuk membuat signature HMAC pada setiap payload. Server penerima harus:

  1. Mengambil header X-Signature dan X-Event-Id.
  2. Membuat kembali HMAC dari badan HTTP (JSON string) dengan algoritme yang sama dan membandingkannya menggunakan perbandingan waktu konstan.
  3. Memastikan event ID belum pernah diproses sebelumnya.

Perhatikan bahwa signature harus dihitung sebelum payload diubah formatnya (misalnya tanpa pretty print) untuk memastikan kesesuaian.

Checklist verifikasi payload/signature

  • Header lengkap: X-Signature, X-Event-Id, Content-Type.
  • Validitas JSON: gunakan schema validator seperti JSON Schema untuk memvalidasi field wajib.
  • Signature HMAC: hitung ulang dengan secret yang sama dan bandingkan.
  • Timestamp atau nonce: pastikan payload tidak replay attack (misalnya periksa timestamp terhadap selisih maksimum).

Mengelola idempotensi dan duplikasi

Webhook sering kali dikirim ulang saat provider tidak menerima respons 200. Oleh karena itu, idempotensi wajib. Pendekatan yang digunakan Cowart:

  • Simpan event_id dan status penanganannya di tabel terpisah (misalnya webhook_events dengan kolom event_id, status, last_attempt_at).
  • Saat webhook diterima lagi, cek tabel tersebut. Jika event sudah processed, kembalikan 200 tanpa memproses ulang.
  • Bila event sedang dalam proses (processing), gunakan locking atau flag untuk mencegah race condition.

Catat juga state berikut untuk troubleshooting: apakah event diverifikasi dengan signature, apakah hasil eksekusi sukses, serta apakah terjadi exception internal. Ini memudahkan pelacakan duplikasi atau kondisi stuck.

Strategi retry/backoff untuk menghindari efek samping ganda

Provider harus menerapkan retry dengan backoff yang eksplisit: 3-5 percobaan dengan delay yang meningkat (misalnya linear/basis eksponensial). Server Cowart harus mengembalikan status 500 saat terjadi error internal agar provider tahu harus retry. Jika kesalahan merupakan validasi payload, segera kirim status 400 untuk menghentikan retry.

Beberapa pertimbangan:

  • Retry Consumer: atur interval retry untuk bertumbuh, misalnya 1s, 5s, 15s, dan minimal 1 jam sebelum percobaan terakhir.
  • Timeout: pastikan handler webhook memiliki batas waktu (misalnya 3-5 detik) untuk menghindari hanging request.
  • Fail-safe: jika retry masih gagal, pindahkan event ke queue dead-letter dan notifkan tim operasi.

Trade-offnya adalah Anda harus mempertimbangkan beban sistem akibat retry. Pastikan juga Anda memiliki mekanisme untuk membedakan antara kesalahan transient dan permanent.

Pengujian integrasi dan observabilitas

Pengujian integrasi punya peran penting untuk menjamin workflow: gunakan versi stub layanan webhook provider untuk mengirim event real-time ke endpoint Anda. Tes harus mencakup skenario sukses, signature invalid, dan duplikasi.

Observabilitas meliputi:

  • Logging: catat event ID, status verifikasi signature, dan hasil handler.
  • Metrics: hitung jumlah event diterima, signature failures, dan retry count (Gunakan Prometheus atau tooling observasi setara).
  • Tracing: sertakan trace ID dari request untuk menelusuri jalur eksekusi di distributed system.

Debugging tip: jika signature selalu gagal, log badan request original dari streaming input (sebelum parsing) dan bandingkan dengan string yang digunakan untuk signature. Untuk event duplikat, cek tabel webhook_events dan log last_attempt_at untuk melihat apakah ada gap besar antara percobaan.

Dengan kontrak yang kuat, autentikasi yang tegas, idempotensi yang terjaga, dan retry yang cerdas, webhook Cowart dapat diandalkan tanpa menimbulkan efek samping ganda. Lengkapi dengan observabilitas dan pengujian yang konsisten agar operasi tetap aman.