← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Webhook Design

api_design PHP 5.0+ Intermediate

Also Known As

webhook HTTP callback event notification webhook security

TL;DR

Best practices for reliable webhooks — HMAC signature verification, idempotency, delivery retry with exponential backoff, and handling slow consumers with queues.

Explanation

Webhooks push events to consumer endpoints via HTTP POST. Design considerations: Signature verification (HMAC-SHA256 of the payload with a shared secret — prevents forged payloads), idempotency (the same event may be delivered multiple times — consumers must be idempotent), delivery guarantees (retry with exponential backoff on non-2xx responses), timeouts (consumer must respond within 5-30 seconds — queue slow processing), event ordering (not guaranteed — include timestamps and sequence numbers), and dead letter handling (failed deliveries after retries need alerting).

Common Misconception

Webhooks are fire-and-forget — providers retry on failure, so consumers must be idempotent; receiving the same event twice must produce the same result, not duplicate side effects.

Why It Matters

A webhook consumer that processes a payment event twice (due to retry) charges a customer twice — idempotency using the event ID prevents duplicate processing.

Common Mistakes

  • Not verifying HMAC signature — any HTTP client can forge webhook payloads.
  • Non-idempotent consumers — retries cause duplicate charges, emails, or database records.
  • Slow processing in webhook handler — slow handlers cause timeouts and trigger retries.
  • No dead letter handling — failed webhooks silently lost means missed events.

Code Examples

✗ Vulnerable
// No signature verification, not idempotent:
$payload = file_get_contents('php://input');
$event   = json_decode($payload);
// No verification — anyone can POST fake events!
if ($event->type === 'payment.completed') {
    $this->processPayment($event->data); // Not idempotent — retries = double charge!
}
✓ Fixed
// Secure webhook handler:
$payload   = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_SIGNATURE'] ?? '';

// Verify HMAC signature:
$expected = 'sha256=' . hash_hmac('sha256', $payload, WEBHOOK_SECRET);
if (!hash_equals($expected, $signature)) {
    http_response_code(401); exit;
}

$event = json_decode($payload);

// Idempotency — skip if already processed:
if ($this->events->isProcessed($event->id)) {
    http_response_code(200); exit; // Acknowledge but skip
}

// Respond 200 immediately, process asynchronously:
http_response_code(200);
ProcessWebhookJob::dispatch($event->id)->afterResponse();
$this->events->markProcessed($event->id);

Added 16 Mar 2026
Edited 22 Mar 2026
Views 30
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 1 ping F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 5 pings T 3 pings F 0 pings S 0 pings S 1 ping M 0 pings T 1 ping W 0 pings T 2 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 1 ping F 0 pings S
No pings yet today
Amazonbot 9 ChatGPT 9 Perplexity 5 Google 3 Ahrefs 2
crawler 26 crawler_json 2
DEV INTEL Tools & Severity
🟠 High ⚙ Fix effort: Medium
⚡ Quick Fix
Validate webhook signatures (HMAC-SHA256), respond with 200 immediately and process asynchronously via queue, implement idempotency via event ID — these three practices prevent the common webhook failures
📦 Applies To
PHP 5.0+ web api
🔗 Prerequisites
🔍 Detection Hints
Webhook endpoint with no signature validation; processing webhook inline taking >5 seconds causing retries; no idempotency check for duplicate delivery
Auto-detectable: ✓ Yes semgrep postman
⚠ Related Problems
🤖 AI Agent
Confidence: High False Positives: Medium ✗ Manual fix Fix: Medium Context: File Tests: Update
CWE-345 CWE-20

✓ schema.org compliant