Webhook API
Best Practices

Best Practices

Pro Tip: Following these best practices ensures reliable webhook processing and optimal performance.

1. Endpoint requirements

  • HTTPS Only: Webhook endpoints must use HTTPS for security
  • Response Time: Respond within 5 seconds to avoid timeouts
  • Status Codes: Return 2xx status codes to acknowledge receipt
  • Error Handling: Return 4xx/5xx status codes to trigger retry mechanism

2. Idempotency

Webhooks may be resent if no acknowledgment is received. Implement idempotency using:

// Use webhookId to prevent duplicate processing
const processedWebhooks = new Set();
 
app.post('/webhook', (req, res) => {
  const {webhookId} = req.body;
  
  if (processedWebhooks.has(webhookId)) {
    return res.status(200).send('Already processed');
  }
  
  // Process webhook...
  processedWebhooks.add(webhookId);
  res.status(200).send('OK');
});

3. Async processing

For long-running processes, respond immediately and queue for background processing:

app.post('/webhook', async (req, res) => {
  // Respond immediately
  res.status(200).send('OK');
  
  // Queue for background processing
  await addToQueue('webhook-processing', req.body);
});

4. Error monitoring

Implement proper logging and monitoring:

app.post('/webhook', (req, res) => {
  try {
    // Verify HMAC
    if (!verifyWebhook(req.body, req.headers['x-joy-loyalty-hmac-sha256'], SECRET_KEY)) {
      console.error('Invalid HMAC signature', {
        headers: req.headers,
        body: req.body
      });
      return res.status(401).send('Invalid signature');
    }
    
    // Process webhook
    processWebhook(req.body);
    res.status(200).send('OK');
    
  } catch (error) {
    console.error('Webhook processing error', {
      error: error.message,
      stack: error.stack,
      body: req.body
    });
    
    // Still return 200 to prevent retries for application errors
    res.status(200).send('Error logged');
  }
});

5. Testing

Test your webhook endpoints thoroughly:

# Test webhook endpoint with sample payload
curl -X POST "https://your-server.com/webhook/points" \
  -H "Content-Type: application/json" \
  -H "X-Joy-Loyalty-Hmac-Sha256: your_test_signature" \
  -H "X-Joy-Loyalty-Topic: points/earned" \
  -d '{
    "webhookId": "test_webhook_123",
    "triggeredAt": "2024-01-15T10:30:00.000Z",
    "customer": {
      "email": "test@example.com",
      "name": "Test Customer",
      "shopifyCustomerId": "gid://shopify/Customer/123"
    }
  }'

Product
Install AppWebsiteBook a Demo
Developers
JavaScript SDKREST API v2Webhook API
Company
Avada GroupHelp CenterContact
© 2026 Joy Loyalty by Avada Group. All rights reserved.