Back to Documentation

Webhook Documentation

Receive real-time notifications when events occur in connected stores

Event Types

ZaLinkAI dispatches webhooks for the following events. Each event includes a JSON payload with the event type, timestamp, store ID, and event-specific data.

order.created

A new order has been placed

order.updated

An order status or details changed

order.completed

An order has been fulfilled and completed

order.cancelled

An order was cancelled by merchant or customer

product.created

A new product was added to the catalog

product.updated

Product details, price, or stock changed

product.deleted

A product was removed from the catalog

customer.created

A new customer account was created

customer.updated

Customer profile information changed

app.uninstalled

The merchant disconnected ZaLinkAI

Payload Examples

Select an event to see its payload schema.

{
  "event": "order.created",
  "timestamp": "2026-01-27T12:00:00Z",
  "storeId": "store_abc123",
  "data": {
    "orderId": "ord_789",
    "status": "pending",
    "total": 249.99,
    "currency": "SAR",
    "items": [
      { "productId": "prod_1", "name": "Wireless Headphones", "qty": 1, "price": 249.99 }
    ],
    "customer": { "id": "cust_456", "email": "customer@example.com" }
  }
}

Signature Verification

Every webhook request includes an X-ZaLink-Signature header containing an HMAC-SHA256 hex digest. Verify this signature to ensure the request originated from ZaLinkAI.

1

Get the raw request body as a string

2

Compute HMAC-SHA256 using your webhook secret

3

Compare the computed hash with X-ZaLink-Signature header

4

Use constant-time comparison to prevent timing attacks

Retry Policy

If your endpoint returns a non-2xx status code or times out (30s), ZaLinkAI retries with exponential backoff:

AttemptDelay
1st retry1 minute
2nd retry5 minutes
3rd retry30 minutes
4th retry2 hours
5th retry6 hours

After 5 failed attempts, the webhook is marked as failed and the merchant is notified via email.

Webhook Handler Examples

Complete webhook handler implementations with signature verification.

const crypto = require('crypto');

function verifyWebhook(payload, signature, secret) {
  const computed = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(computed)
  );
}

// Express handler
app.post('/webhooks/zalink', (req, res) => {
  const signature = req.headers['x-zalink-signature'];
  const isValid = verifyWebhook(
    JSON.stringify(req.body),
    signature,
    process.env.WEBHOOK_SECRET
  );
  if (!isValid) return res.status(401).send('Invalid signature');

  const { event, data } = req.body;
  switch (event) {
    case 'order.created':
      handleNewOrder(data);
      break;
    case 'product.updated':
      syncProduct(data);
      break;
  }
  res.json({ received: true });
});

Best Practices

Return a 200 response immediately, then process the event asynchronously

Implement idempotency using the event ID to avoid duplicate processing

Store the raw payload for debugging and audit purposes

Set up monitoring and alerts for webhook failures

Use HTTPS endpoints with valid TLS certificates