PHP

Secure Webhook Receiver with Signature Verification in PHP

Create a secure PHP endpoint to receive webhooks, verify incoming request signatures, and prevent tampering or spoofing attempts from external APIs.

<?php

// IMPORTANT: Replace with your actual secret key from the webhook provider
const WEBHOOK_SECRET = 'your_super_secret_webhook_key'; 

// 1. Get the raw POST body
$payload = file_get_contents('php://input');

// 2. Get the signature from the header (header name might vary, e.g., X-Hub-Signature, X-Signature, X-Webhook-Signature)
// For this example, let's assume 'X-Webhook-Signature' and it's a SHA256 HMAC
$header_signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';

if (empty($header_signature)) {
    http_response_code(401); // Unauthorized
    echo json_encode(['error' => 'No signature header provided.']);
    exit();
}

// 3. Calculate your own signature
$calculated_signature = hash_hmac('sha256', $payload, WEBHOOK_SECRET);

// 4. Compare the signatures securely
// Use hash_equals for timing attack safe comparison
if (!hash_equals($header_signature, $calculated_signature)) {
    http_response_code(401); // Unauthorized
    echo json_encode(['error' => 'Invalid webhook signature.']);
    exit();
}

// 5. If signatures match, process the webhook payload
$data = json_decode($payload, true);

if (json_last_error() !== JSON_ERROR_NONE) {
    http_response_code(400); // Bad Request
    echo json_encode(['error' => 'Invalid JSON payload.']);
    exit();
}

// Log or process the data
error_log('Webhook received and verified successfully. Data: ' . print_r($data, true));

// Send a success response
http_response_code(200);
echo json_encode(['status' => 'success', 'message' => 'Webhook received.']);

?>
How it works: This PHP snippet provides a secure endpoint for receiving webhooks by implementing signature verification. It retrieves the raw POST body and the signature typically sent in a custom HTTP header by the webhook provider. Your application then calculates its own HMAC signature using a shared secret key and the received payload. By comparing the calculated signature with the provided header signature using `hash_equals` (which is timing-attack safe), the endpoint can ensure the request originated from a trusted source and the payload hasn't been tampered with. Only verified webhooks are processed.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs