Skip to main content

Overview

Webhooks allow your application to receive real-time notifications when events occur in Superbank. Instead of polling the API, Superbank pushes events to your endpoint.

How Webhooks Work

  1. An event occurs (e.g., payment completed)
  2. Superbank sends a POST request to your webhook URL
  3. Your application processes the event
  4. Return 200 OK to acknowledge receipt

Setting Up Webhooks

Create a Webhook Endpoint

curl -X POST https://api-sandbox.superbank.com/v1/webhooks \
  -H "X-Api-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhooks/superbank",
    "events": ["payment.completed", "payment.failed"]
  }'

Response

{
  "id": "wh_abc123",
  "url": "https://your-app.com/webhooks/superbank",
  "events": ["payment.completed", "payment.failed"],
  "secret": "whsec_xyz789...",
  "status": "ACTIVE",
  "created_at": "2024-01-15T10:00:00Z"
}
Store the secret securely - it’s only shown once and is required for signature verification.

Event Types

Payment Events

EventDescription
payment.createdPayment was created
payment.processingPayment transfer started
payment.completedPayment successfully completed
payment.failedPayment failed
payment.expiredPayment expired before notification

Account Events

EventDescription
account.balance.lowAccount balance dropped below threshold

Webhook Payload

All webhooks follow this structure:
{
  "id": "evt_abc123",
  "type": "payment.completed",
  "created_at": "2024-01-15T10:05:30Z",
  "data": {
    "id": "pay_xyz789",
    "type": "LIQUIDITY",
    "status": "COMPLETED",
    "amount": 100.00,
    "currency_code": "USDC",
    "chain": "SOLANA",
    "destination_wallet": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
    "transaction_hash": "5wHu1qwD7q4..."
  }
}
FieldDescription
idUnique event identifier
typeEvent type
created_atWhen the event occurred
dataEvent-specific payload

Signature Verification

Every webhook includes a signature header for verification. Always verify signatures to ensure the webhook came from Superbank.

Signature Header

X-Superbank-Signature: t=1705312530,v1=5d4c...
The header contains:
  • t: Timestamp when the webhook was sent
  • v1: HMAC-SHA256 signature

Verification Process

import crypto from 'crypto';

function verifyWebhook(payload, signature, secret) {
  const parts = signature.split(',');
  const timestamp = parts[0].split('=')[1];
  const receivedSig = parts[1].split('=')[1];

  // Compute expected signature
  const signedPayload = `${timestamp}.${payload}`;
  const expectedSig = crypto
    .createHmac('sha256', secret)
    .update(signedPayload)
    .digest('hex');

  // Compare signatures
  if (!crypto.timingSafeEqual(
    Buffer.from(receivedSig),
    Buffer.from(expectedSig)
  )) {
    throw new Error('Invalid signature');
  }

  return true;
}

Handling Webhooks

Best Practices

  1. Return 200 quickly: Process asynchronously if needed
  2. Verify signatures: Always validate webhook authenticity
  3. Handle duplicates: Use event IDs for idempotency
  4. Process in order: Events may arrive out of order

Example Handler

app.post('/webhooks/superbank', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-superbank-signature'];
  const payload = req.body.toString();

  try {
    verifyWebhook(payload, signature, process.env.WEBHOOK_SECRET);
  } catch (err) {
    return res.status(400).send('Invalid signature');
  }

  const event = JSON.parse(payload);

  // Handle event asynchronously
  handleEvent(event).catch(console.error);

  // Acknowledge receipt immediately
  res.status(200).send('OK');
});

async function handleEvent(event) {
  switch (event.type) {
    case 'payment.completed':
      await processCompletedPayment(event.data);
      break;
    case 'payment.failed':
      await handleFailedPayment(event.data);
      break;
  }
}

Retry Policy

If your endpoint doesn’t respond with 2xx, Superbank retries with exponential backoff:
AttemptDelay
1Immediate
21 minute
35 minutes
415 minutes
51 hour
61 day
72 days
84 days
91 week
102 weeks
After 10 failed attempts, the webhook is marked as failed. Check the Dashboard for failed deliveries.

Managing Webhooks

List Endpoints

curl https://api-sandbox.superbank.com/v1/webhooks \
  -H "X-Api-Key: your-api-key"

Update Endpoint

curl -X PATCH https://api-sandbox.superbank.com/v1/webhooks/wh_abc123 \
  -H "X-Api-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "events": ["payment.completed", "payment.failed", "payment.expired"]
  }'

Delete Endpoint

curl -X DELETE https://api-sandbox.superbank.com/v1/webhooks/wh_abc123 \
  -H "X-Api-Key: your-api-key"

Testing Webhooks

Local Development

Use Svix Play to test webhooks during development. It provides a unique URL to receive and inspect webhook payloads without exposing your local server.
  1. Go to play.svix.com
  2. Copy your unique webhook URL
  3. Use it as your webhook endpoint in Superbank
  4. View incoming webhooks in real-time

Test Events

From the Dashboard, you can send test events to verify your endpoint is working correctly.

Next Steps