Creating Custom Webhooks
How to create webhook endpoints for custom integrations
Creating Custom Webhook Endpoints
Step 1: Create Webhook File
Create a new file in /webhooks/ directory:
/webhooks/yourservice.php
Step 2: Basic Structure
<?php
require_once ROOT_PATH . '/includes/bootstrap.php';
// Get webhook payload
$payload = file_get_contents('php://input');
$headers = getallheaders();
// Log webhook
$db = Database::getInstance();
$gateway = 'yourservice';
$stmt = $db->prepare("INSERT INTO webhooks (gateway, payload, created_at) VALUES (?, ?, NOW())");
$stmt->bind_param("ss", $gateway, $payload);
$stmt->execute();
$webhookId = $db->insert_id;
// Verify webhook (signature, IP, etc.)
if (!verifyWebhook($payload, $headers)) {
http_response_code(401);
exit;
}
// Parse payload
$data = json_decode($payload, true);
// Process webhook
try {
processWebhook($data);
// Mark as processed
$db->query("UPDATE webhooks SET processed = 1 WHERE id = $webhookId");
http_response_code(200);
echo json_encode(['success' => true]);
} catch (Exception $e) {
error_log('Webhook error: ' . $e->getMessage());
http_response_code(500);
}
function verifyWebhook($payload, $headers) {
// Implement signature verification
// Check IP whitelist
// Validate timestamp
return true;
}
function processWebhook($data) {
// Handle different event types
$eventType = $data['type'] ?? '';
switch ($eventType) {
case 'payment.completed':
handlePaymentCompleted($data);
break;
case 'refund.processed':
handleRefund($data);
break;
}
}
Step 3: Security Considerations
- Verify Signatures: Always verify webhook signatures
- HTTPS Only: Use HTTPS for webhook endpoints
- Idempotency: Handle duplicate webhooks gracefully
- Timeout Handling: Return 200 quickly, process asynchronously if needed
Step 4: Testing
Use tools like ngrok to test webhooks locally:
ngrok http 80
# Use ngrok URL as webhook endpoint