Webhooks
Webhooks allow your application to receive real-time notifications when events occur in your Mando account.
Overview
Section titled “Overview”Instead of polling the API, configure webhook endpoints to receive HTTP POST requests when:
- Sales are completed
- Products are updated
- Stock levels change
- Customers are created or modified
Setting Up Webhooks
Section titled “Setting Up Webhooks”- Log in to your Mando admin panel
- Navigate to Settings → Webhooks
- Click Add Webhook
- Enter your endpoint URL
- Select the events you want to receive
- Save the configuration
Available Events
Section titled “Available Events”| Event | Description |
|---|---|
sale.created | New sale completed |
sale.voided | Sale was voided |
product.created | New product added |
product.updated | Product details changed |
product.deleted | Product removed |
stock.updated | Stock level changed |
stock.low | Stock fell below threshold |
customer.created | New customer added |
customer.updated | Customer details changed |
businessday.opened | Business day started |
businessday.closed | Business day ended |
Webhook Payload
Section titled “Webhook Payload”All webhooks use a consistent payload structure:
{ "id": "evt_abc123", "type": "sale.created", "created": "2024-01-15T10:30:00Z", "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "total": 45.50, "items": [...] }}| Field | Description |
|---|---|
id | Unique event identifier |
type | Event type |
created | ISO 8601 timestamp |
data | Event-specific payload |
Verifying Webhooks
Section titled “Verifying Webhooks”Each webhook request includes a signature header for verification:
X-Mando-Signature: sha256=abc123...Verify the signature to ensure the request came from Mando:
TypeScript
Section titled “TypeScript”import crypto from 'crypto';
function verifyWebhook( payload: string, signature: string, secret: string): boolean { const expected = crypto .createHmac('sha256', secret) .update(payload) .digest('hex');
return crypto.timingSafeEqual( Buffer.from(signature.replace('sha256=', '')), Buffer.from(expected) );}
// Express middlewareapp.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => { const signature = req.headers['x-mando-signature'] as string; const isValid = verifyWebhook(req.body, signature, process.env.WEBHOOK_SECRET!);
if (!isValid) { return res.status(401).send('Invalid signature'); }
const event = JSON.parse(req.body); // Process event...
res.status(200).send('OK');});Python
Section titled “Python”import hmacimport hashlib
def verify_webhook(payload: bytes, signature: str, secret: str) -> bool: expected = hmac.new( secret.encode(), payload, hashlib.sha256 ).hexdigest()
return hmac.compare_digest( signature.replace('sha256=', ''), expected )
# Flask example@app.route('/webhook', methods=['POST'])def handle_webhook(): signature = request.headers.get('X-Mando-Signature') is_valid = verify_webhook( request.data, signature, os.environ['WEBHOOK_SECRET'] )
if not is_valid: return 'Invalid signature', 401
event = request.json # Process event...
return 'OK', 200Handling Events
Section titled “Handling Events”Process events based on their type:
app.post('/webhook', (req, res) => { const event = req.body;
switch (event.type) { case 'sale.created': handleNewSale(event.data); break; case 'stock.low': sendRestockAlert(event.data); break; case 'customer.created': syncToMailingList(event.data); break; }
res.status(200).send('OK');});Retry Policy
Section titled “Retry Policy”If your endpoint returns an error (non-2xx status), Mando retries the webhook:
| Attempt | Delay |
|---|---|
| 1 | Immediate |
| 2 | 1 minute |
| 3 | 5 minutes |
| 4 | 30 minutes |
| 5 | 2 hours |
After 5 failed attempts, the webhook is marked as failed and disabled.
Best Practices
Section titled “Best Practices”- Respond quickly - Return 200 within 5 seconds; process asynchronously
- Handle duplicates - Use
event.idfor idempotency - Verify signatures - Always validate incoming webhooks
- Use HTTPS - Webhook URLs must use HTTPS
- Log everything - Keep records for debugging
- Set up monitoring - Alert on failed webhook deliveries
Testing Webhooks
Section titled “Testing Webhooks”Use the webhook test feature in the admin panel:
- Go to Settings → Webhooks
- Click Test next to your endpoint
- Select an event type
- Review the test payload delivery
For local development, use tools like ngrok to expose your local server.