Webhooks Overview
Webhooks enable real-time notifications when events occur in your Azotte account, allowing you to build responsive integrations.
How Webhooks Work
Azotte Platform Your Server
│ │
[Event Occurs] │
│ │
│─── HTTP POST ──────▶│
│ (Event Data) │
│ │
│◀─── 200 OK ────────│
│ │
Common Event Types
Subscription Events
subscription.created- New subscription activatedsubscription.updated- Subscription details changedsubscription.cancelled- Subscription cancelledsubscription.renewed- Billing cycle renewedsubscription.trial_ending- Trial period ending soon
Payment Events
payment.succeeded- Payment processed successfullypayment.failed- Payment attempt failedpayment.refunded- Refund issuedpayment.disputed- Chargeback initiated
Customer Events
customer.created- New customer registeredcustomer.updated- Customer information changedcustomer.deleted- Customer account removed
Webhook Configuration
Setting Up Endpoints
- Create an endpoint on your server
- Add the endpoint URL in Azotte Portal
- Select which events to receive
- Test the webhook configuration
Endpoint Requirements
- HTTPS only for security
- Return 200 status to confirm receipt
- Process within 30 seconds to avoid timeout
- Idempotent handling for duplicate events
Event Structure
Standard Event Format
{
"id": "evt_1234567890",
"type": "subscription.created",
"created": 1678886400,
"data": {
"object": {
"id": "sub_1234567890",
"customer": "cus_1234567890",
"status": "active",
"current_period_start": 1678886400,
"current_period_end": 1681564800
}
},
"request": {
"id": "req_1234567890",
"idempotency_key": null
}
}
Security
Webhook Signatures
// Verify webhook signature
const crypto = require('crypto');
function verifySignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return signature === `sha256=${expectedSignature}`;
}
Best Practices
- Always verify webhook signatures
- Use HTTPS for webhook endpoints
- Implement proper error handling
- Log webhook events for debugging
Handling Webhooks
Basic Webhook Handler
const express = require('express');
const app = express();
app.post('/webhooks/azotte', express.raw({type: 'application/json'}), (req, res) => {
const signature = req.headers['azotte-signature'];
const payload = req.body;
// Verify signature
if (!verifySignature(payload, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(payload);
// Handle the event
switch (event.type) {
case 'subscription.created':
handleSubscriptionCreated(event.data.object);
break;
case 'payment.failed':
handlePaymentFailed(event.data.object);
break;
default:
console.log(`Unhandled event type: ${event.type}`);
}
res.status(200).send('OK');
});
Retry Policy
Automatic Retries
- First retry: 1 minute after failure
- Second retry: 5 minutes after first retry
- Third retry: 15 minutes after second retry
- Final retry: 1 hour after third retry
Failure Handling
- Non-2xx responses trigger retries
- Timeouts (>30 seconds) trigger retries
- Connection errors trigger retries
- After final retry, webhook is marked as failed
Testing Webhooks
Local Development
# Use ngrok to expose local server
ngrok http 3000
# Use the ngrok URL in webhook configuration
# https://abc123.ngrok.io/webhooks/azotte
Test Events
# Send test webhook from Azotte Portal
# Or use API to trigger test events
curl -X POST https://api.azotte.com/v1/webhooks/test \
-H "x-api-key: sk_dev_..." \
-H "x-tn: tenant_..." \
-d '{"type": "subscription.created"}'
Monitoring
Webhook Logs
- Delivery attempts and status
- Response codes and timing
- Error messages and retries
- Success/failure rates
Alerting
- Failed webhook deliveries
- High error rates
- Endpoint timeouts
- Signature verification failures
Next Steps
- Learn about Event Types
- Understand Webhook Security
- Explore Retry Policy