v1.0

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

  1. 1An event occurs in your Vexutopia account (e.g., payment succeeds)
  2. 2Vexutopia creates an event object with details about what happened
  3. 3Vexutopia sends an HTTP POST request to your configured webhook URL
  4. 4Your server processes the event and returns a 200 response

Event Object

Each webhook delivery contains an event object:

JSON
{
  "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",
      ...
    }
  }
}
Event Attributes
ParameterTypeDescription
idstringUnique identifier for the event
objectstringAlways "event"
typestringType of event (e.g., payment.succeeded)
created_atstringWhen the event occurred
data.objectobjectThe full object related to the event

Event Types

Subscribe to the events you need:

EventDescription
payment.createdA new payment was created
payment.succeededA payment completed successfully
payment.failedA payment failed to process
payment.refundedA payment was refunded
customer.createdA new customer was created
customer.updatedA customer was updated
customer.deletedA customer was deleted

Receiving Webhooks

Create an endpoint on your server to receive webhook events:

Node.js / Express
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

  1. Get the raw request body as a string
  2. Compute HMAC-SHA256 of the body using your webhook secret
  3. Compare the computed signature with the header value
  4. 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:

cURL
# 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/vexutopia

Next Steps

Configure webhooks in your dashboard and start receiving events: