Webhooks
Send delivery status updates from NavYour to your website automatically.
Webhook Endpoint Settings
Event Subscriptions
Test Webhook
Webhooks let NavYour send delivery updates to your website automatically. Your website should return HTTP 200 quickly after receiving the webhook.
Add webhook URL first.
Delivery Logs
Developer Guide
Create an endpoint in this website backend:
POST /api/navyour/webhook
Rules:
- Use the raw request body for signature verification.
- Verify NavYour-Signature before trusting the payload.
- Return HTTP 200 quickly.
- Update our local order by event.order.orderReference or event.order.trackingCode.
- Do not create orders from webhooks. API order creation creates orders; webhooks only send updates.
Signature:
signature payload = timestamp + "." + rawJsonBody
signature = HMAC_SHA256(secret, signature payload)
Express example:
import express from "express";
import crypto from "crypto";
const app = express();
app.post("/api/navyour/webhook", express.raw({ type: "application/json" }), async (req, res) => {
const rawBody = req.body.toString("utf8");
const timestamp = req.header("NavYour-Timestamp") || "";
const signature = req.header("NavYour-Signature") || "";
const secret = process.env.NAVYOUR_WEBHOOK_SECRET || "";
const expected =
"sha256=" +
crypto
.createHmac("sha256", secret)
.update(`${timestamp}.${rawBody}`)
.digest("hex");
if (
expected.length !== signature.length ||
!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature))
) {
return res.status(401).send("Invalid signature");
}
const event = JSON.parse(rawBody);
switch (event.event) {
case "order.delivered":
await updateOrderStatus(event.order.orderReference, "delivered");
break;
case "driver.assigned":
await updateOrderStatus(event.order.orderReference, "assigned");
break;
case "order.picked_up":
await updateOrderStatus(event.order.orderReference, "picked_up");
break;
case "order.failed":
await updateOrderStatus(event.order.orderReference, "failed");
break;
default:
break;
}
return res.status(200).json({ received: true });
});
Next.js App Router example:
export async function POST(req: Request) {
const rawBody = await req.text();
const timestamp = req.headers.get("NavYour-Timestamp") || "";
const signature = req.headers.get("NavYour-Signature") || "";
const secret = process.env.NAVYOUR_WEBHOOK_SECRET || "";
// Verify HMAC using timestamp + "." + rawBody before JSON.parse(rawBody)
return Response.json({ received: true });
}Troubleshooting
Webhook test failed: check the URL is public, accepts POST, and returns HTTP 200. Localhost needs ngrok or cloudflared.
401 Invalid signature: use the correct secret and verify raw body, not parsed JSON.
Timeout: return 200 quickly and process heavy work after response.
404 Not found: check endpoint path.
500 Server error: check your website server logs.
If your endpoint is down or returns an error, NavYour will log the failure and retry. Webhook success does not create the order. API order creation creates the order. Webhook only sends updates back.
