Skip to main content

Overview

Webhooks enable automated notifications for specific gateway events. Receive real-time updates about transaction processing, settlement status, recurring billing, chargebacks, and account activity without polling the API.
Webhooks allow your application to respond immediately to gateway events, improving automation and customer experience.

How Webhooks Work

1

Configure Webhook URL

Set up your webhook endpoint URL in the merchant control panel
2

Event Occurs

When a subscribed event occurs, the gateway sends an HTTP POST request
3

Receive Notification

Your server receives the webhook payload with event details
4

Respond with 200

Return HTTP 200 status to acknowledge receipt
5

Process Event

Process the event data and update your application

Configuration

Configure webhooks in the merchant control panel: Settings > Webhooks

Webhook Settings

SettingDescription
URLYour webhook endpoint (must be HTTPS)
EventsSelect which events to receive
SecretShared secret for signature verification
Retry LogicAutomatic retry on failure (up to 5 attempts)
Webhook URLs must use HTTPS. HTTP endpoints are not supported for security reasons.

Event Types

Notifications for transaction lifecycle events.

Sale Success

Triggered when a sale transaction is approved.
{
  "event": "transaction.sale.success",
  "transaction_id": "123456789",
  "amount": "99.99",
  "currency": "USD",
  "status": "approved",
  "timestamp": "2025-10-30T10:30:00Z"
}

Transaction Declined

Triggered when a transaction is declined.
{
  "event": "transaction.declined",
  "transaction_id": "123456790",
  "amount": "50.00",
  "decline_reason": "Insufficient funds",
  "timestamp": "2025-10-30T10:31:00Z"
}

Webhook Payload Structure

All webhook payloads follow this structure:
{
  "event": "event.type.name",
  "webhook_id": "WH123456789",
  "timestamp": "2025-10-30T10:30:00Z",
  "data": {
    // Event-specific data
  },
  "signature": "sha256_hash_of_payload"
}

Common Fields

FieldDescription
eventEvent type identifier
webhook_idUnique webhook delivery ID
timestampEvent occurrence time (ISO 8601)
dataEvent-specific payload
signatureHMAC signature for verification

Implementation Example

<?php
// webhook.php

// Get the raw POST body
$payload = file_get_contents('php://input');
$data = json_decode($payload, true);

// Verify signature
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'];
$calculated = hash_hmac('sha256', $payload, 'YOUR_WEBHOOK_SECRET');

if (!hash_equals($signature, $calculated)) {
    http_response_code(401);
    die('Invalid signature');
}

// Process the event
switch ($data['event']) {
    case 'transaction.sale.success':
        handleSuccessfulSale($data['data']);
        break;

    case 'subscription.added':
        handleNewSubscription($data['data']);
        break;

    case 'chargeback.received':
        handleChargeback($data['data']);
        break;

    default:
        error_log('Unhandled event: ' . $data['event']);
}

// Respond with 200
http_response_code(200);
echo 'OK';

function handleSuccessfulSale($transaction) {
    // Update order status
    $order_id = $transaction['order_id'];
    updateOrderStatus($order_id, 'paid');

    // Send confirmation email
    sendConfirmationEmail($transaction);
}
?>

Security

Signature Verification

Always verify webhook signatures to ensure authenticity:
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'];
$payload = file_get_contents('php://input');
$calculated = hash_hmac('sha256', $payload, 'YOUR_WEBHOOK_SECRET');

if (!hash_equals($signature, $calculated)) {
    http_response_code(401);
    die('Invalid signature');
}
Never process webhooks without signature verification. This prevents malicious requests from compromising your application.

Best Practices

Configure your webhook endpoint to use HTTPS. The gateway will not send webhooks to HTTP endpoints.
Always verify the HMAC signature before processing webhook data.
if (!hash_equals($expected, $actual)) {
    return 401;
}
Return HTTP 200 within 5 seconds. Process time-consuming operations asynchronously.
// Respond immediately
http_response_code(200);
echo 'OK';
fastcgi_finish_request(); // PHP

// Process in background
processWebhookAsync($data);
Track webhook IDs to prevent duplicate processing.
$webhook_id = $data['webhook_id'];
if (isProcessed($webhook_id)) {
    return 200; // Already processed
}
processWebhook($data);
markProcessed($webhook_id);
Log all received webhooks for debugging and audit purposes.
logWebhook([
    'webhook_id' => $data['webhook_id'],
    'event' => $data['event'],
    'timestamp' => time(),
    'payload' => $payload
]);

Retry Logic

The gateway implements automatic retry logic for failed webhook deliveries:
1

Initial Attempt

Webhook sent immediately when event occurs
2

Retry 1 (1 minute)

If no 200 response, retry after 1 minute
3

Retry 2 (5 minutes)

If still failing, retry after 5 minutes
4

Retry 3 (30 minutes)

Retry after 30 minutes
5

Retry 4 (2 hours)

Retry after 2 hours
6

Final Retry (24 hours)

Final retry attempt after 24 hours
After 5 failed attempts, the webhook is marked as failed. You can manually retry from the merchant control panel.

Testing Webhooks

Local Testing with ngrok

Use ngrok to test webhooks on your local machine:
# Start ngrok
ngrok http 3000

# Use the HTTPS URL in webhook configuration
https://abc123.ngrok.io/webhook

Manual Testing

Test your webhook endpoint manually:
curl -X POST https://yoursite.com/webhook \
  -H "Content-Type: application/json" \
  -H "X-Webhook-Signature: SIGNATURE_HERE" \
  -d '{
    "event": "transaction.sale.success",
    "webhook_id": "TEST123",
    "timestamp": "2025-10-30T10:30:00Z",
    "data": {
      "transaction_id": "123456789",
      "amount": "99.99"
    }
  }'

Test Mode Events

In sandbox mode, trigger test events: Merchant Control Panel > Webhooks > Test Events Send test webhooks for each event type to verify your implementation.

Monitoring

Monitor webhook delivery in the merchant control panel: Settings > Webhooks > Delivery Log View:
  • Delivery status (success/failure)
  • Response codes
  • Retry attempts
  • Payload details
  • Error messages

Common Issues

Possible causes:
  • Firewall blocking gateway IPs
  • HTTPS certificate issues
  • Webhook URL misconfigured
Solution: Check server logs, verify URL, ensure HTTPS
Possible causes:
  • Wrong webhook secret
  • Payload modified
  • Encoding issues
Solution: Verify secret, use raw payload for signature
Possible causes:
  • Retry logic triggered
  • Network issues
Solution: Implement idempotency using webhook_id
Possible causes:
  • Processing takes too long
  • Server overload
Solution: Respond quickly, process asynchronously

Next Steps