Receive real-time notifications when events happen in your Hisab account. Build reactive integrations with webhook events.
Webhooks allow your application to receive real-time HTTP notifications when events occur in your Hisab account. Instead of polling the API for changes, webhooks push data to your server as events happen.
Configure a URL in your Hisab dashboard where you want to receive webhook events. Your endpoint must use HTTPS.
Choose which events you want to receive notifications for (e.g., invoice.finalized, customer.created).
When an event occurs, Hisab sends an HTTP POST request to your endpoint with the event data. Verify the signature and process the event.
Use services like webhook.site or ngrok to test webhooks during development. You can also use the test webhook feature in your Hisab dashboard to send sample events.
Subscribe to the events that matter to your integration. Each event represents a specific action that occurred in your Hisab account.
invoice.createdWhen a new invoice is created (draft status)
invoice.updatedWhen an invoice is modified
invoice.finalizedWhen an invoice is finalized and assigned an official number
invoice.sentWhen an invoice is sent to the customer via email
invoice.paidWhen an invoice is marked as paid
invoice.voidedWhen an invoice is voided/cancelled
customer.createdWhen a new customer is added
customer.updatedWhen customer information is modified
customer.deletedWhen a customer is deleted
All webhook payloads follow a consistent structure. The data field contains the event-specific information.
POST /webhooks/hisab HTTP/1.1
Host: your-app.com
Content-Type: application/json
X-Hisab-Signature: a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0
X-Hisab-Timestamp: 1732713000000
X-Hisab-Event: invoice.finalized
X-Hisab-Delivery-ID: del_abc123
User-Agent: Hisab-Webhook/1.0{
"id": "evt_1234567890",
"type": "invoice.finalized",
"created": "2025-11-27T14:30:00Z",
"data": {
"id": "inv_abc123",
"invoice_number": "INV-2025-00042",
"status": "finalized",
"customer_id": "cus_xyz789",
"customer_name": "ACME Corporation",
"currency": "MAD",
"subtotal": "5000.00",
"total_tax": "1000.00",
"total": "6000.00",
"issue_date": "2025-11-27",
"due_date": "2025-12-27",
"finalized_at": "2025-11-27T14:30:00Z",
"items": [
{
"description": "Web Development Services",
"quantity": "10",
"unit_price": "500.00",
"tax_rate": "20",
"total": "6000.00"
}
]
},
"organization_id": "org_123456"
}idstringUnique identifier for this eventtypestringThe type of event (e.g., invoice.finalized)createdstringISO 8601 timestamp when the event was createddataobjectThe event data containing the relevant objectorganization_idstringYour organization IDEvery webhook request includes a signature in the X-Hisab-Signature header. Always verify this signature to ensure the webhook came from Hisab and hasn't been tampered with.
Never skip signature verification in production. Without it, malicious actors could send fake webhook events to your endpoint.
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload, 'utf8')
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
// Express.js example
app.post('/webhooks/hisab', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-hisab-signature'];
const timestamp = req.headers['x-hisab-timestamp'];
const payload = req.body.toString();
// Verify timestamp is recent (within 5 minutes)
const timestampAge = Date.now() - parseInt(timestamp);
if (timestampAge > 300000) {
return res.status(400).send('Timestamp too old');
}
// Verify signature
const signedPayload = `${timestamp}.${payload}`;
if (!verifyWebhookSignature(signedPayload, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(payload);
// Handle the event
switch (event.type) {
case 'invoice.finalized':
handleInvoiceFinalized(event.data);
break;
case 'invoice.paid':
handleInvoicePaid(event.data);
break;
// ... handle other events
}
res.status(200).send('OK');
});If your endpoint doesn't respond with a 2xx status code, Hisab will retry the webhook delivery using an exponential backoff strategy.
Return a 2xx status code within 30 seconds to acknowledge receipt
HTTP 2xx4xx, 5xx responses or timeouts will trigger automatic retries
HTTP 4xx, 5xx, timeoutValidate the X-Hisab-Signature header on every request to ensure authenticity and prevent spoofing attacks.
Return a 2xx response within 30 seconds. Process the event asynchronously if needed to avoid timeouts.
Store processed event IDs to handle duplicate deliveries gracefully. The same event may be delivered multiple times.
For complex processing, acknowledge the webhook immediately and add the event to a background job queue.
Use HTTPS only. Optionally add IP whitelisting or additional authentication for extra security.