Skip to content

Webhook Setup Guide

Integrate webhook to receive updates about your live order.

Webhooks let you receive real-time updates whenever a certificate file is created or updated.
Follow these steps to set up and handle webhooks securely.


  1. Go to your Organisation Dashboard.
  2. Navigate to Accounts & Support → API.
  3. Register your Webhook URL.
  4. Copy your Webhook Secret (you’ll need it for verification).

Whenever a certificate file is created or updated, we’ll send a POST request to your webhook URL with the following JSON body:

{
"url": "https://example.com/certificates/12345.pdf",
"name": "certificate.pdf",
"orderId": "abc123", // the documentId of your live order
"orderFulfillmentId": "xyz789" // the documentId of your live order fulfillment
}

To ensure that webhook requests are authentic and untampered, you must verify the
x-signature header included with every webhook request.

  1. Receive Webhook

    • Your server receives a POST request with JSON body.
    • Request contains a header:
      x-signature: <hex-string>
  2. Extract Raw Body

    • Get the raw (unparsed) request body exactly as received.
    • ⚠️ Using parsed JSON may lead to mismatches.
  3. Compute HMAC SHA256

    • Use your WEBHOOK_SECRET (from dashboard).
    • Compute:
      HMAC_SHA256(raw_body, WEBHOOK_SECRET) → hex digest
  4. Compare Signatures

    • Compare computed digest with x-signature header.
    • If they match → ✅ request is authentic.
    • If they don’t match → ❌ reject request (possible spoofing or tampering).
  5. Process Payload

    • Once verified, you can trust the request and safely handle the payload.
Terminal window
import express from "express";
import crypto from "crypto";
const app = express();
const PORT = process.env.PORT || 3000;
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET || "your_webhook_secret_here";
app.use(
express.json({
verify: (req, res, buf) => {
req.rawBody = buf; // keep raw body for signature verification
},
})
);
function verifySignature(req) {
const signature = req.headers["x-signature"];
if (!signature) return false;
const computedSig = crypto
.createHmac("sha256", WEBHOOK_SECRET)
.update(req.rawBody)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature, "utf8"),
Buffer.from(computedSig, "utf8")
);
}
app.post("/webhook", (req, res) => {
if (!verifySignature(req)) {
return res.status(401).send("Invalid or missing signature");
}
const { url, name, orderId, orderFulfillmentId } = req.body;
console.log("✅ Certificate:", url, name, orderId, orderFulfillmentId);
res.send("Webhook received and verified");
});
app.listen(PORT, () => {
console.log(`🚀 Server running on http://localhost: ${PORT}`);
});