Webhooks
Webhooks
Section titled “Webhooks”Handling webhook events across all SDKs.
Overview
Section titled “Overview”Webhooks deliver real-time events to your application.
TypeScript/JavaScript
Section titled “TypeScript/JavaScript”Express.js
Section titled “Express.js”import express from "express";import { IslamicOpenFinance } from "@iof/sdk";
const app = express();const iof = new IslamicOpenFinance({ apiKey: process.env.IOF_API_KEY });
app.post( "/webhooks", express.raw({ type: "application/json" }), async (req, res) => { const signature = req.headers["x-iof-signature"] as string;
try { const event = iof.webhooks.constructEvent( req.body, signature, process.env.WEBHOOK_SECRET!, );
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"); } catch (err) { console.error("Webhook error:", err); res.status(400).send("Invalid signature"); } },);Next.js
Section titled “Next.js”import { NextRequest, NextResponse } from "next/server";import { IslamicOpenFinance } from "@iof/sdk";
const iof = new IslamicOpenFinance({ apiKey: process.env.IOF_API_KEY });
export async function POST(req: NextRequest) { const body = await req.text(); const signature = req.headers.get("x-iof-signature")!;
try { const event = iof.webhooks.constructEvent( body, signature, process.env.WEBHOOK_SECRET!, );
// Handle event console.log("Received:", event.type);
return NextResponse.json({ received: true }); } catch (err) { return NextResponse.json({ error: "Invalid signature" }, { status: 400 }); }}Python
Section titled “Python”from flask import Flask, requestfrom iof import IslamicOpenFinance, WebhookSignatureError
app = Flask(__name__)iof = IslamicOpenFinance(api_key=os.environ["IOF_API_KEY"])
@app.route("/webhooks", methods=["POST"])def webhooks(): payload = request.get_data() signature = request.headers.get("X-IOF-Signature")
try: event = iof.webhooks.construct_event( payload, signature, os.environ["WEBHOOK_SECRET"] )
if event.type == "contract.created": handle_contract_created(event.data.object)
return "OK", 200 except WebhookSignatureError: return "Invalid signature", 400FastAPI
Section titled “FastAPI”from fastapi import FastAPI, Request, HTTPExceptionfrom iof import IslamicOpenFinance, WebhookSignatureError
app = FastAPI()iof = IslamicOpenFinance(api_key=os.environ["IOF_API_KEY"])
@app.post("/webhooks")async def webhooks(request: Request): payload = await request.body() signature = request.headers.get("X-IOF-Signature")
try: event = iof.webhooks.construct_event( payload, signature, os.environ["WEBHOOK_SECRET"] )
# Handle event return {"received": True} except WebhookSignatureError: raise HTTPException(status_code=400, detail="Invalid signature")import ( "github.com/Islamic-Open-Finance/iof-go/webhook")
func webhookHandler(w http.ResponseWriter, r *http.Request) { payload, _ := io.ReadAll(r.Body) signature := r.Header.Get("X-IOF-Signature")
event, err := webhook.ConstructEvent( payload, signature, os.Getenv("WEBHOOK_SECRET"), ) if err != nil { http.Error(w, "Invalid signature", http.StatusBadRequest) return }
switch event.Type { case "contract.created": var contract iof.Contract json.Unmarshal(event.Data.Raw, &contract) handleContractCreated(&contract) }
w.WriteHeader(http.StatusOK)}@PostMapping("/webhooks")public ResponseEntity<String> handleWebhook( @RequestBody String payload, @RequestHeader("X-IOF-Signature") String signature) { try { Event event = Webhook.constructEvent( payload, signature, System.getenv("WEBHOOK_SECRET") );
switch (event.getType()) { case "contract.created": handleContractCreated((Contract) event.getData().getObject()); break; }
return ResponseEntity.ok("OK"); } catch (SignatureVerificationException e) { return ResponseEntity.badRequest().body("Invalid signature"); }}Best Practices
Section titled “Best Practices”- Always verify signatures
- Return 200 quickly - Process async if needed
- Implement idempotency - Handle duplicate events
- Log event IDs - For debugging
- Use HTTPS - Secure endpoints only
Next Steps
Section titled “Next Steps”- Security Guide - Signature verification
- Webhooks Rail - Endpoint management