Skip to main content

What are Webhooks?

Webhooks are HTTP callbacks that notify your server when events happen in Shoppex — a paid order, a new subscription, a dispute. Instead of polling the API, your server receives events in real time.
This page covers normal Shoppex event webhooks. dynamic_webhook for DYNAMIC products is a separate fulfillment callback contract. See Dynamic Product Delivery.

Setting Up Webhooks

Configure webhook endpoints in the Dashboard:
1

Open webhook settings

Go to Settings → Webhooks
2

Add a new endpoint

Click Add Endpoint
3

Enter your URL

Enter your endpoint URL
4

Select events

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,
    "total_display": 49.99,
    "currency": "USD",
    "exchange_rate": 1,
    "crypto_exchange_rate": 0,
    "crypto_gateway": null,
    "apm_method": "CARD",
    "customer_email": "[email protected]"
  },
  "created_at": 1705318200
}
Dashboard test deliveries use the same event / data / created_at envelope as live deliveries. The payload values are synthetic examples, but Shoppex signs the raw JSON body the same way as a real delivery.
Top-level webhook created_at is a Unix timestamp. Nested timestamps inside data can be ISO 8601 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

Open webhook settings

Go to Settings → Webhooks
2

Select your endpoint

Click on your endpoint
3

Send a test event

Click Send Test Event
4

Choose an event type

Select an event type
Test order:* deliveries include the main live fields you usually integrate against, for example gateway, total, total_display, currency, exchange_rate, crypto_gateway, apm_method, customer_email, and product context.
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

Retry Policy

If your endpoint returns an error (non-2xx status) or times out, Shoppex retries automatically:
DeliveryDelay
Initial attemptImmediate
Retry 12 minutes
Retry 24 minutes
Retry 38 minutes
Retry 416 minutes
After the 5th failed attempt, the webhook is marked as failed. You can manually retry from the dashboard.
Your endpoint must respond within 30 seconds or the request will timeout and count as a failure.

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.

Next Steps

Webhook Events

Full list of event types and payload examples

Dynamic Delivery

Deliver digital products in real-time