Terima event Klik Flow di sistem Anda.
Tambahkan URL HTTPS di Pengaturan › API & Webhook › Webhook (atau lewat POST /api/v2/webhooks) dan pilih event-nya. Klik Flow mengirim POST JSON yang ditandatangani dengan secret webhook itu. Daftar event dan isinya ada di panduan Event webhook.
Bentuk kiriman
Setiap event dikirim dengan bentuk yang sama:
{
"id": "evt_9Qx2Lm4Kp7Rt1Zs8",
"type": "message.status",
"created": "2026-11-01T09:13:10+07:00",
"business_id": 7,
"data": {
"message_id": 99140,
"conversation_id": 812,
"channel": "whatsapp_official",
"to": "6281234567890",
"status": "read",
"error": null,
"at": "2026-11-01T09:13:10+07:00"
}
}id: id unik event (evt_…), sama di setiap percobaan. Simpan, dan abaikan bila sudah pernah diproses.created: waktu kejadian dalam zona waktu bisnis Anda, lengkap dengan selisihnya (+07:00).test: trueada pada event uji dan pada status pesan yang dikirim kunci tes.- Maksimal 5 webhook per bisnis; setiap webhook punya secret sendiri.
Header
Klikflow-Event: nama event, misalnyamessage.received.Klikflow-Event-Id: sama denganiddi isi.Klikflow-Delivery-Attempt: percobaan ke berapa (1–7).Klikflow-Signature: t=<detik>,v1=<HMAC-SHA256 dari "<t>.<body>">, dibuat ulang di setiap percobaan.
Verifikasi tanda tangan (Node.js)
import crypto from "node:crypto";
// rawBody: isi permintaan apa adanya (string), sebelum di-parse.
function verifyKlikFlow(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(",").map((p) => p.trim().split("=")));
const t = Number(parts.t);
if (!t || Math.abs(Date.now() / 1000 - t) > 300) return false; // lebih dari 5 menit: tolak
const expected = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
return parts.v1?.length === expected.length && crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected));
}Verifikasi tanda tangan (PHP)
<?php
$raw = file_get_contents("php://input");
$header = $_SERVER["HTTP_KLIKFLOW_SIGNATURE"] ?? "";
parse_str(str_replace(",", "&", $header), $parts);
$t = intval($parts["t"] ?? 0);
$expected = hash_hmac("sha256", $t . "." . $raw, getenv("KLIKFLOW_WEBHOOK_SECRET"));
if (!$t || abs(time() - $t) > 300 || !hash_equals($expected, $parts["v1"] ?? "")) {
http_response_code(400);
exit;
}
$event = json_decode($raw, true);
http_response_code(200);Verifikasi tanda tangan (Python)
import hashlib, hmac, time
def verify_klikflow(raw_body: bytes, header: str, secret: str) -> bool:
parts = dict(p.strip().split("=", 1) for p in header.split(",") if "=" in p)
t = int(parts.get("t", "0"))
if not t or abs(time.time() - t) > 300:
return False
expected = hmac.new(secret.encode(), f"{t}.".encode() + raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, parts.get("v1", ""))Menjawab dan kirim ulang
Jawab 2xx dalam 8 detik, lalu proses di belakang. Bila tidak, kiriman diulang setelah 1 menit, 5 menit, 30 menit, 2 jam, 6 jam, 24 jam (7 percobaan, sekitar 33 jam). Setelah itu kiriman masuk daftar gagal.
- Klik Flow tidak mengikuti redirect: 3xx dihitung gagal, jadi pakai URL akhir.
- Hanya alamat HTTPS publik; alamat jaringan lokal ditolak.
- Kirim ulang atau Kirim ulang semua di Pengaturan › API & Webhook mengirim event yang sama (id dan isi sama) dengan percobaan baru.
- Bila semua kiriman gagal selama 3 hari, webhook dijeda otomatis dan alasannya tampil di kartunya. Aktifkan lagi setelah penerima diperbaiki; kiriman yang menunggu dicoba ulang saat itu juga.
- Log kiriman (status, kode HTTP, waktu, dan isi) disimpan 30 hari.
Urutan dan duplikat
Event bisa tiba tidak berurutan, dan setelah gangguan jaringan bisa tiba dua kali. Pakai id untuk mengabaikan ulangan, dan waktu di data (misalnya at pada status pesan) untuk urutan.
Event uji
Tombol Kirim event uji di kartu webhook, atau POST /api/v2/webhooks/{id}/test, mengirim contoh satu event dengan test: true dan langsung menampilkan jawaban sistem Anda. Event uji tidak diulang bila gagal dan tidak dihitung dalam kesehatan webhook.