Home / Webhooks / Creating Custom Webhooks

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