Webhooks Documentation

Learn how to integrate with our webhook system to receive real-time notifications about events in your account.

Overview

Webhooks provide a way for our system to notify your application when specific events occur. Instead of having to poll our API for changes, webhooks push data to your application as events happen. This allows you to build integrations that react to events in real-time.

Real-time Updates

Receive instant notifications when events happen in your account, eliminating the need for polling.

Secure Communications

All webhook payloads are signed, allowing you to verify they were sent by our system.

Flexible Configuration

Subscribe only to the events you care about and configure multiple endpoints.

Getting Started

To start receiving webhooks, you'll need to register a webhook endpoint in your account settings. Follow these steps to set up your first webhook:

  1. 1

    Create a webhook endpoint in your application

    Set up an endpoint in your application that can receive HTTP POST requests. Your endpoint should be accessible from the internet.

  2. 2

    Register your webhook in the dashboard

    Go to the Webhooks page in your dashboard and click on "Add Webhook". Enter a name and the URL of your endpoint.

  3. 3

    Select the events you want to receive

    Choose which events you want to be notified about. You can subscribe to all events or just specific ones.

  4. 4

    Implement signature verification

    Make sure your endpoint verifies the webhook signature to ensure the request came from our system. See the Security section for details.

  5. 5

    Test your webhook

    Use our Webhook Sandbox to send test events to your endpoint and ensure everything is working correctly.

Available Events

Our system can send webhooks for various events. Click on an event to see an example payload.

Account Events

account.created
Triggered when a new account is created
account.updated
Triggered when account details are updated

Mutations Events

mutations.created
Triggered when a new mutations is created
balance.updated
Triggered when an account balance changes

Payment Events

payment.created
Triggered when a new payment is created
payment.completed
Triggered when a payment is completed successfully
payment.expired
Triggered when a payment expires
payment.failed
Triggered when a payment fails

Security

All webhook requests include a signature in the X-Webhook-Signature header. This signature is generated using your webhook's secret and the request payload. You should verify this signature to ensure the webhook came from our system.

How to Verify Signatures

The signature is generated using HMAC-SHA256 with your webhook secret as the key and the JSON string of the data object as the message. Here's how to verify the signature:

javascript
// Webhook signature verification in Node.js
const crypto = require('crypto');
const express = require('express');
const app = express();

// Parse JSON bodies
app.use(express.json());

app.post('/webhook', (req, res) => {
  const signature = req.headers['x-webhook-signature'];
  const payload = req.body;
  const webhookSecret = 'your_webhook_secret'; // Get this from your dashboard
  
  // Verify the signature
  const isValid = verifySignature(payload.data, signature, webhookSecret);
  
  if (!isValid) {
    console.log('Invalid signature');
    return res.status(401).json({ error: 'Invalid signature' });
  }
  
  // Process the webhook based on event type
  const eventType = req.headers['x-webhook-event'] || payload.type;
  console.log('Received valid webhook:', eventType);
  
  // Return a 200 response
  res.json({ received: true });
});

function verifySignature(data, signature, secret) {
  // Compute the expected signature
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(data))
    .digest('hex');
  
  // Compare the signatures
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

app.listen(3000, () => {
  console.log('Webhook server running on port 3000');
});

Implementation

This section provides examples of how to implement webhook handlers in different languages. Each example shows how to receive, verify, and process webhook events.

Webhook Handler Structure

A typical webhook handler should follow these steps:

  1. 1

    Receive the webhook request

    Set up an HTTP endpoint that can receive POST requests from our servers.

  2. 2

    Verify the webhook signature

    Check the X-Webhook-Signature header to ensure the request is authentic.

  3. 3

    Identify the event type

    Check the X-Webhook-Event header or the type field in the payload.

  4. 4

    Process the webhook data

    Handle the event according to your application's needs.

  5. 5

    Return a 2xx response

    Always return a 200 or 202 status code to acknowledge receipt of the webhook.

Complete Implementation Examples

Express.js Implementation

A complete example of a webhook handler in Express.js

javascript
// server.js
const express = require('express');
const crypto = require('crypto');
const app = express();

// Your webhook secret from the dashboard
const WEBHOOK_SECRET = 'your_webhook_secret'; // Get this from your dashboard

// Parse JSON bodies
app.use(express.json());

// Verify webhook signature
function verifySignature(data, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(data))
    .digest('hex');

  console.log('Expected Signature:', expectedSignature);
  console.log('Provided Signature:', signature);

  return signature === expectedSignature;
}

app.post('/webhook', (req, res) => {
  const signature = req.headers['x-webhook-signature'];
  const eventType = req.headers['x-webhook-event'];

  console.log('Received webhook:', {
    eventType,
    signature,
    payload: req.body,
  });

  // The signature is calculated on the data object only, not the entire payload
  const data = req.body.data;
  
  // Verify signature
  if (!verifySignature(data, signature, WEBHOOK_SECRET)) {
    console.log('Invalid signature');
    return res.status(400).json({ error: 'Invalid signature' });
  }

  console.log('Signature verified successfully!');

  // Handle different event types
  switch (req.body.type) {
    case 'payment.completed':
      const { paymentId, status, transaction } = req.body.data;
      console.log('Payment completed:', {
        paymentId,
        status,
        amount: transaction.amount,
        transactionId: transaction.id,
        transactionDate: transaction.createdAt,
      });
      
      // Update your database, send notifications, etc.
      // This should be handled asynchronously or with a job queue for production
      
      break;

    case 'payment.expired':
      console.log('Payment expired:', req.body.data);
      // Handle expired payment logic
      break;
      
    case 'account.created':
      // Handle new account logic
      break;
      
    // Handle other event types
    default:
      console.log('Unhandled event type:', req.body.type);
  }

  // Return 200 to acknowledge receipt
  res.json({ received: true });
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Webhook server running on port ${PORT}`);
});

Best Practices

Return 200 Status Code Quickly

Always return a 200 status code as quickly as possible, even if you process the webhook asynchronously. Our system will retry webhooks that receive non-2xx responses, which could lead to duplicate processing.

Implement Idempotency

Make your webhook handlers idempotent so they can safely receive the same webhook multiple times without causing issues. Check if you've already processed a webhook with the same ID.

Process Asynchronously

For complex processing, queue the webhook for asynchronous processing after verifying the signature. This allows you to return a 200 response quickly and process the webhook in the background.

Log Everything

Log webhook requests, responses, and processing for debugging and audit purposes. This helps troubleshoot issues when webhooks aren't being processed correctly.

Test with the Sandbox

Use our webhook sandbox to test your implementation with various event types before relying on it in production. This helps catch issues early.

Use HTTPS Endpoints

Always use HTTPS for your webhook endpoints to ensure data is encrypted in transit. This protects sensitive information in webhook payloads.

Troubleshooting

Common Issues

Here are solutions to common webhook issues you might encounter.

Signature Verification Failing

  • Make sure you're using the correct webhook secret from your dashboard.
  • Check that you're verifying the signature against the data object, not the entire payload.
  • Ensure you're serializing the data object to JSON in the same way we do (with no whitespace).
  • Verify that you're using HMAC-SHA256 for signature generation.

Webhooks Not Being Received

  • Check that your webhook endpoint is publicly accessible.
  • Verify that your server is running and can receive HTTP requests.
  • Make sure your firewall allows incoming connections to your webhook endpoint.
  • Check the webhook status in your dashboard to see if there are delivery failures.

Duplicate Webhook Processing

  • Implement idempotency by tracking processed webhook IDs.
  • Make sure you're returning a 200 status code even if processing fails.
  • Verify that your processing logic is idempotent and can safely handle duplicates.

Testing Tools

Tools to help test and debug your webhook implementation.

  • Test your webhook endpoint with simulated events from our dashboard.

  • A third-party tool for inspecting and debugging webhook requests.

  • Create secure tunnels to localhost for testing webhooks during development.

Need Help?

If you're still having issues with webhooks, don't hesitate to reach out to our support team. We're here to help you get your integration working smoothly.

Ready to implement webhooks?

Get started by creating your first webhook endpoint.