What are Webhooks?

Webhooks are real-time server-to-server (S2S) notifications that EximPe sends to your backend when important events occur. Unlike browser redirects that can be interrupted, webhooks ensure reliable delivery of payment status updates directly to your server.

Reliable Delivery

Notifications sent directly to your server with automatic retries

Real-time Updates

Instant notification of payment events as they happen

No User Dependency

Works even if customer closes the browser or loses connection

Secure Communication

Encrypted and signed for authenticity and data integrity


Supported Events

EximPe sends webhooks for these key events:

Payment Successful

When: Customer completes payment
Use Case: Update order status, send confirmation

Payment Failed

When: Payment attempt fails
Use Case: Retry payment, notify customer

Payment Refunded

When: Refund is processed
Use Case: Update inventory, notify customer

Merchant Approved

When: Merchant account activated
Use Case: Enable payment collection

Settlement Completed

When: Funds transferred to merchant
Use Case: Update accounting records


🛠️ Setup Guide

Step 1: Prepare Your Endpoint

Ensure your server has a public HTTPS URL accessible from the internet, a POST endpoint that can receive webhook data, 200 OK response capability, and support for application/json.

Step 2: Configure Webhook URL

1

Dashboard Configuration (Recommended)

  1. Log into your EximPe Dashboard
  2. Navigate to Developer Section
  3. Enter your webhook URL
  4. Save configuration
  5. Whitelist EximPe IP addresses - Configure your firewall to only accept webhooks from EximPe’s IP ranges (found in Developer Section)
2

Manual Setup

  1. Contact EximPe Support with your webhook URL
  2. Provide your server’s IP address
  3. EximPe will whitelist your endpoint
  4. You’ll receive EximPe’s IP range for firewall configuration
  5. Whitelist EximPe IP addresses - Configure your firewall to only accept webhooks from EximPe’s IP ranges

Step 3: Test Your Integration

Log Requests

Log all incoming requests on your server to monitor webhook delivery

Test Payment

Make a test payment in sandbox environment to trigger webhooks

Verify Receipt

Verify webhook receipt and processing in your logs

Check Response

Ensure your endpoint returns 200 OK response codes


🔐 Security & Verification

EximPe signs each webhook with an HMAC signature to ensure authenticity:

Verification Steps

1

Extract the signature

Extract the signature from the X-Webhook-Signature header in the request

2

Get your API key

Get your Encryption key

3

Recreate the signature

Recreate the signature using HMAC-SHA256:

  • Use your API key as the secret
  • Use the raw JSON body as the message
  • Important: If reconstructing from JSON object, ensure consistent serialization using json.dumps() with sort_keys=True and separators=(",", ":") to match EximPe’s format
  • Generate HMAC-SHA256 hash
  • Convert to hexadecimal string
4

Compare signatures

Compare signatures - they should match exactly

Code Examples

const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, apiKey) {
  // Create HMAC using your API key
  const hmac = crypto.createHmac('sha256', apiKey);
  
  // Update with the raw JSON body
  hmac.update(payload, 'utf8');
  
  // Generate the expected signature
  const expectedSignature = hmac.digest('hex');
  
  // Compare signatures
  return crypto.timingSafeEqual(
    Buffer.from(signature, 'hex'),
    Buffer.from(expectedSignature, 'hex')
  );
}

function generateSignatureFromObject(webhookData, apiKey) {
  // If you need to recreate signature from a JSON object
  // Use the same serialization as EximPe
  const payloadJson = JSON.stringify(webhookData, Object.keys(webhookData).sort());
  
  const hmac = crypto.createHmac('sha256', apiKey);
  hmac.update(payloadJson, 'utf8');
  return hmac.digest('hex');
}

// Usage in Express.js
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-webhook-signature'];
  const payload = req.body.toString();
  
  if (!verifyWebhookSignature(payload, signature, process.env.API_KEY)) {
    return res.status(401).send('Invalid signature');
  }
  
  // Process webhook
  const webhookData = JSON.parse(payload);
  console.log('Webhook verified:', webhookData);
  
  res.status(200).send('OK');
});

⏰ Retry Logic & Delivery

EximPe implements an automatic retry mechanism to ensure reliable webhook delivery. If your endpoint doesn’t respond with a 200 OK status code, we’ll retry the webhook delivery according to the following schedule:

Retry Schedule: 1st attempt is immediate, followed by retries at 1 minute, 5 minutes, 15 minutes, and finally 1 hour. After 5 failed attempts, EximPe will stop retrying.


Security Best Practices:

  • 🔐 Never expose your encryption key publicly
  • 📝 Always verify webhook signatures
  • 🛡️ Use HTTPS endpoints only
  • 📊 Log webhook events for audit trails

Next Steps:

  • Review the API Reference for detailed webhook payload specifications
  • Test your webhook integration in the sandbox environment
  • Monitor webhook delivery in your EximPe dashboard