Webhooks
Webhooks allow you to receive real-time notifications when events occur in your Vexutopia account, such as successful payments or failed transactions.
How Webhooks Work
- 1An event occurs in your Vexutopia account (e.g., payment succeeds)
- 2Vexutopia creates an event object with details about what happened
- 3Vexutopia sends an HTTP POST request to your configured webhook URL
- 4Your server processes the event and returns a 200 response
Event Object
Each webhook delivery contains an event object:
{
"id": "evt_1234567890",
"object": "event",
"type": "payment.succeeded",
"created_at": "2026-01-19T10:30:00Z",
"data": {
"object": {
"id": "pay_abc123",
"object": "payment",
"amount": 2000,
"currency": "usd",
"status": "succeeded",
...
}
}
}| Parameter | Type | Description |
|---|---|---|
id | string | Unique identifier for the event |
object | string | Always "event" |
type | string | Type of event (e.g., payment.succeeded) |
created_at | string | When the event occurred |
data.object | object | The full object related to the event |
Event Types
Subscribe to the events you need:
| Event | Description |
|---|---|
payment.created | A new payment was created |
payment.succeeded | A payment completed successfully |
payment.failed | A payment failed to process |
payment.refunded | A payment was refunded |
customer.created | A new customer was created |
customer.updated | A customer was updated |
customer.deleted | A customer was deleted |
Receiving Webhooks
Create an endpoint on your server to receive webhook events:
import express from 'express';
import crypto from 'crypto';
const app = express();
app.use(express.json());
const WEBHOOK_SECRET = process.env.VEXUTOPIA_WEBHOOK_SECRET;
app.post('/webhooks/vexutopia', (req, res) => {
const signature = req.headers['x-vexutopia-signature'];
const payload = JSON.stringify(req.body);
// Verify the signature
const expectedSignature = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(payload)
.digest('hex');
if (signature !== expectedSignature) {
return res.status(401).send('Invalid signature');
}
const event = req.body;
// Handle the event
switch (event.type) {
case 'payment.succeeded':
const payment = event.data.object;
console.log('Payment succeeded:', payment.id);
// Fulfill the order, send confirmation email, etc.
break;
case 'payment.failed':
const failedPayment = event.data.object;
console.log('Payment failed:', failedPayment.id);
// Notify the customer, retry the payment, etc.
break;
default:
console.log('Unhandled event type:', event.type);
}
// Return 200 to acknowledge receipt
res.status(200).send('OK');
});
app.listen(3000);Signature Verification
Every webhook includes a signature in the X-Vexutopia-Signature header. Always verify this signature to ensure the webhook is authentic.
Security Warning
Never process webhook events without verifying the signature. Attackers could send fake events to your endpoint.
Verification Steps
- Get the raw request body as a string
- Compute HMAC-SHA256 of the body using your webhook secret
- Compare the computed signature with the header value
- Only process the event if signatures match
Retry Logic
If your endpoint doesn't return a 2xx response, Vexutopia will retry the delivery:
Retry Schedule
- • Attempt 1: Immediate
- • Attempt 2: 5 minutes later
- • Attempt 3: 30 minutes later
- • Attempt 4: 2 hours later
- • Attempt 5: 24 hours later
After 5 failed attempts, the event is marked as failed and no more retries are attempted.
Best Practices
Return 200 quickly
Respond with 200 immediately, then process the event asynchronously. Long-running handlers may cause timeouts and unnecessary retries.
Handle duplicates
Webhook events may be delivered more than once. Use the event ID to deduplicate and ensure idempotent handling.
Log everything
Log all received events with their IDs. This helps with debugging and auditing.
Use HTTPS
Always use HTTPS for your webhook endpoint. We won't send events to HTTP URLs in production.
Testing Webhooks
During development, you can use tools like ngrok to expose your local server:
# Start your local server
npm run dev
# In another terminal, expose it via ngrok
ngrok http 3000
# Use the ngrok URL as your webhook endpoint
# https://abc123.ngrok.io/webhooks/vexutopiaNext Steps
Configure webhooks in your dashboard and start receiving events: