Skip to main content

Setup and Verify Webhooks

This guide shows you how to set up a webhook endpoint, register it with NextAPI, and verify incoming signatures.

Step 1: Create Your Endpoint

Your webhook endpoint must:

  • Accept POST requests
  • Return a 2xx status within 30 seconds
  • Be accessible via HTTPS
const express = require('express');
const crypto = require('crypto');

const app = express();
app.use('/webhooks/nextpay', express.raw({ type: 'application/json' }));

const WEBHOOK_SECRET = process.env.NEXTPAY_WEBHOOK_SECRET;

app.post('/webhooks/nextpay', (req, res) => {
const signature = req.headers['x-nextpay-signature'];
const payload = req.body;

// Verify signature
const expected = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(payload)
.digest('hex');

if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
return res.status(401).send('Invalid signature');
}

// Parse and handle the event
const event = JSON.parse(payload);
console.log(`Received event: ${event.type}`);

switch (event.type) {
case 'payout_request.completed':
// Handle completed payout
break;
case 'payout_request.failed':
// Handle failed payout
break;
case 'payment_intent.paid':
// Handle successful payment
break;
}

res.status(200).send('OK');
});

app.listen(3000);

Step 2: Register Your Webhook

Use the API to register your endpoint URL and select which events to receive:

curl -X POST "https://api.partners.nextpay.world/v2/webhooks" \
-H "Content-Type: application/json" \
-u "YOUR_CLIENT_ID:YOUR_CLIENT_SECRET" \
-d '{
"url": "https://your-domain.com/webhooks/nextpay",
"events": [
"payout_request.completed",
"payout_request.failed",
"payment_intent.paid"
]
}'

The response includes your webhook id and the secret used for signature verification. Store the secret securely — it is only shown once.

Step 3: Handle Deduplication

Webhook events may be delivered more than once. Use the event id to prevent duplicate processing:

const processedEvents = new Set();

function handleEvent(event) {
if (processedEvents.has(event.id)) {
return; // Already processed
}

// Process the event...

processedEvents.add(event.id);
}

In production, store processed event IDs in your database rather than in-memory.

Step 4: Test Locally

Use a tunneling tool like ngrok to expose your local server for testing:

ngrok http 3000

Then register the ngrok URL as your webhook endpoint in the sandbox environment.

Troubleshooting

IssueSolution
401 UnauthorizedCheck your webhook secret and signature verification logic
Timeout errorsAcknowledge quickly, process async. Return 200 before heavy work.
Missing eventsVerify your webhook is registered for the correct event types
Duplicate eventsImplement deduplication using event IDs