Skip to main content

Setting Up Webhooks

Webhooks notify your application in real-time when events occur, eliminating the need for polling.

Step 1: Create a Webhook Endpoint

Create an endpoint in your application to receive webhook events:

Express.js

import express from 'express';
import { MaesClient, MaesWebhookSignatureError } from '@nuvoni/maes-sdk';

const app = express();
const client = new MaesClient({ apiKey: process.env.MAES_API_KEY! });

// Use raw body for signature verification
app.post(
'/webhook/maes',
express.raw({ type: 'application/json' }),
(req, res) => {
try {
const event = client.webhooks.verifySignature(
req.body.toString(),
req.headers['x-webhook-signature'] as string,
process.env.WEBHOOK_SECRET!,
);

// Handle the event
handleWebhookEvent(event);

// Respond quickly with 200
res.status(200).send('OK');
} catch (error) {
if (error instanceof MaesWebhookSignatureError) {
console.error('Invalid signature:', error.message);
return res.status(401).send('Invalid signature');
}
throw error;
}
},
);

async function handleWebhookEvent(event) {
console.log(`Received event: ${event.event}`);

switch (event.event) {
case 'card.enabled':
console.log('Card enabled:', event.data.card_id);
break;
case 'card.disabled':
console.log('Card disabled:', event.data.card_id);
break;
case 'card.activated':
console.log('Card activated:', event.data.card_id);
break;
case 'sync.completed':
console.log('Sync completed');
break;
}
}

app.listen(3000);

Step 2: Deploy Your Endpoint

Your webhook endpoint must be:

  • Publicly accessible (not localhost)
  • HTTPS only (required)
  • Fast response (< 30 seconds)

For local testing, you can use:

# Using ngrok
ngrok http 3000

Step 3: Register the Webhook

Via Dashboard

  1. Go to your project at https://maes-platform.nuvoni.eu
  2. Open Webhooks tab
  3. Click "Configure Webhook"
  4. Enter your endpoint URL
  5. Select events to subscribe to
  6. Click "Save"
  7. Copy the secret — shown only once!

Step 4: Test Your Webhook

Send a Test Event

Use the dashboard to send a test event, or use the API:

// The test event will be sent to your configured webhook URL
// Check the Webhooks tab in the dashboard for delivery status

Handling Events

Event Structure

interface WebhookEvent {
id: string;
event: string;
created_at: string;
data: {
card_id?: string;
card_number?: string;
status?: string;
// ... other fields
};
}

Idempotency

Events may be delivered more than once. Use event.id for deduplication:

const processedEvents = new Set<string>();

async function handleWebhookEvent(event) {
if (processedEvents.has(event.id)) {
console.log(`Already processed event ${event.id}`);
return;
}

processedEvents.add(event.id);

// Process the event...
}

For production, store processed event IDs in a database.

Webhook Signature Verification

The SDK handles signature verification for you:

import { MaesClient, MaesWebhookSignatureError } from '@nuvoni/maes-sdk';

const client = new MaesClient({ apiKey: 'sk_live_xxxxx' });

try {
const event = client.webhooks.verifySignature(
rawBody, // Raw request body as string
signatureHeader, // X-Webhook-Signature header
webhookSecret, // Your webhook secret
);

// Event is verified and safe to process
console.log('Verified event:', event.event);
} catch (error) {
if (error instanceof MaesWebhookSignatureError) {
// Invalid signature - reject the request
console.error('Invalid signature');
}
}

Troubleshooting

Webhook Not Receiving Events

  1. Check the URL is publicly accessible
  2. Verify HTTPS is working
  3. Check firewall rules
  4. Review delivery history in dashboard

Signature Verification Failing

  1. Use the raw request body (not parsed JSON)
  2. Ensure you're using the correct secret
  3. Check for encoding issues

Missing Events

  1. Verify you've subscribed to the event type
  2. Check if webhook is enabled
  3. Review delivery history for failures