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
- Go to your project at https://maes-platform.nuvoni.eu
- Open Webhooks tab
- Click "Configure Webhook"
- Enter your endpoint URL
- Select events to subscribe to
- Click "Save"
- 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
- Check the URL is publicly accessible
- Verify HTTPS is working
- Check firewall rules
- Review delivery history in dashboard
Signature Verification Failing
- Use the raw request body (not parsed JSON)
- Ensure you're using the correct secret
- Check for encoding issues
Missing Events
- Verify you've subscribed to the event type
- Check if webhook is enabled
- Review delivery history for failures