Skip to main content

What are Webhooks?

Webhooks are HTTP callbacks that notify your server when events happen in Shoppex. Instead of polling the API, your server receives events automatically.

Setting Up Webhooks

Configure webhook endpoints in the Dashboard:
  1. Go to Settings → Webhooks
  2. Click Add Endpoint
  3. Enter your endpoint URL
  4. Select which events to receive
For local development, use a tunnel service like ngrok to expose your local server.

Webhook Payload

All webhooks follow this structure:
{
  "event": "order:paid",
  "data": {
    "uniqid": "abc123def456",
    "type": "PRODUCT",
    "status": "COMPLETED",
    "gateway": "STRIPE",
    "total": 49.99,
    "currency": "USD",
    "customer_email": "[email protected]"
  },
  "created_at": 1705318200
}
Timestamps are Unix timestamps (seconds since epoch), not ISO strings.

Headers

Each webhook request includes these headers:
HeaderDescription
Content-Typeapplication/json
User-AgentShoppex-Webhook/1.0
X-Shoppex-EventEvent type (e.g., order:paid)
X-Shoppex-SignatureHMAC-SHA512 signature
X-Shoppex-DeliveryUnique delivery ID for deduplication

Signature Verification

Always verify webhook signatures to ensure authenticity. Shoppex uses HMAC-SHA512:
import crypto from 'crypto';

function verifySignature(
  payload: string,
  signature: string,
  secret: string
): boolean {
  const expected = crypto
    .createHmac('sha512', secret)  // Note: SHA512
    .update(payload, 'utf8')
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

app.post('/webhooks/shoppex', (req, res) => {
  const signature = req.headers['x-shoppex-signature'] as string;

  if (!verifySignature(req.rawBody, signature, WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }

  const { event, data } = req.body;

  switch (event) {
    case 'order:paid':
      handleOrderPaid(data);
      break;
    case 'order:cancelled':
      handleOrderCancelled(data);
      break;
    case 'subscription:created':
      handleSubscriptionCreated(data);
      break;
  }

  res.status(200).send('OK');
});
Your webhook secret is available in Settings → Webhooks in the Dashboard. Keep it secure and never expose it in client-side code.

Testing Webhooks

Use the dashboard to send test events:
  1. Go to Settings → Webhooks
  2. Click on your endpoint
  3. Click Send Test Event
  4. Select an event type
For local development:
# Start a tunnel
ngrok http 3000

# Use the generated URL as your webhook endpoint
# e.g., https://abc123.ngrok.io/webhooks/shoppex

Best Practices

Process webhooks asynchronously. Return 200 OK immediately and handle the event in a background job.
Webhooks may be delivered more than once. Use the X-Shoppex-Delivery header to deduplicate.
Always verify webhook signatures in production to prevent spoofing.
Always use HTTPS endpoints in production for security.