Skip to content

Webhooks

Real-time event notifications for your application.

Webhooks deliver events to your application as they happen:

sequenceDiagram
autonumber
participant IOF as 🏛️ Islamic Open Finance™
participant Server as 🖥️ Your Server
Note over IOF,Server: Webhook Delivery Flow
IOF->>+Server: 📤 POST /webhooks
Note right of Server: 🔐 Verify HMAC signature
Note right of Server: ✅ Process event data
Server-->>-IOF: 📨 200 OK
Note over IOF: ✅ Delivery confirmed
EventDescription
contract.createdNew contract created
contract.activatedContract activated
contract.payment.receivedPayment received
contract.maturedContract reached maturity
contract.closedContract closed
EventDescription
kyc.submittedKYC submission received
kyc.verifiedKYC verified
kyc.rejectedKYC rejected
kyc.expiredKYC expired
EventDescription
compliance.alertCompliance alert triggered
compliance.review.requiredManual review needed
{
"id": "evt_abc123",
"type": "contract.created",
"created": "2024-01-15T10:30:00Z",
"data": {
"object": {
"id": "contract_xyz",
"type": "MURABAHA",
"status": "draft"
}
},
"metadata": {
"workspaceId": "ws_123",
"tenantId": "tenant_456"
}
}
const endpoint = await iof.webhooks.createEndpoint({
url: "https://yourapp.com/webhooks",
events: ["contract.*", "kyc.verified"],
secret: process.env.WEBHOOK_SECRET,
});
app.post("/webhooks", async (req, res) => {
// Verify signature
const isValid = iof.webhooks.verify(
req.rawBody,
req.headers["x-iof-signature"],
process.env.WEBHOOK_SECRET,
);
if (!isValid) {
return res.status(401).send("Invalid signature");
}
const event = req.body;
switch (event.type) {
case "contract.created":
await handleContractCreated(event.data.object);
break;
case "kyc.verified":
await handleKycVerified(event.data.object);
break;
}
res.status(200).send("OK");
});

Failed deliveries are retried with exponential backoff:

AttemptDelay
1Immediate
21 minute
35 minutes
430 minutes
52 hours