Webhook adalah mekanisme di mana server mengirim data ke URL yang kamu tentukan saat event tertentu terjadi.
Push vs Poll:
| Pendekatan | Cara Kerja | Kelebihan | Kekurangan |
|---|---|---|---|
| Polling | Client tanya server berulang-ulang | Sederhana | Boros resource, delay |
| Webhook | Server kirim notifikasi ke client | Real-time, efisien | Setup lebih kompleks |
Cara kerja webhook:
1. Kamu daftarkan URL endpoint di service (misal Stripe)
2. Event terjadi (pembayaran berhasil)
3. Stripe kirim POST request ke URL-mu dengan payload
4. Server-mu terima dan proses data
Webhook Payload:
{
"event": "payment.success",
"timestamp": "2024-01-15T10:30:00Z",
"data": {
"id": "pay_abc123",
"amount": 500000,
"currency": "IDR",
"customer": "cust_xyz"
}
}
Signature Verification (HMAC): Pastikan webhook benar-benar dari sumber yang dipercaya:
const crypto = require("crypto");
function verifyWebhook(payload, signature, secret) {
const expected = crypto
.createHmac("sha256", secret)
.update(payload)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
app.post("/webhooks/stripe", (req, res) => {
const sig = req.headers["x-webhook-signature"];
if (!verifyWebhook(JSON.stringify(req.body), sig, WEBHOOK_SECRET)) {
return res.status(401).json({ error: "Invalid signature" });
}
// Proses event...
res.status(200).json({ received: true });
});
Retry Strategy: Jika endpoint-mu down, service biasanya retry dengan exponential backoff (1s, 2s, 4s, 8s...).
Idempotency Key: Gunakan ID unik per event agar pemrosesan ulang (retry) tidak menyebabkan duplikat:
const processedEvents = new Set();
if (processedEvents.has(event.id)) {
return res.json({ already_processed: true });
}
Contoh nyata: Stripe (pembayaran), GitHub (push/PR), WhatsApp Business (pesan masuk).