Business Portalactive

Webhooks

Send delivery status updates from NavYour to your website automatically.

Webhook Status
Not configured
Last Delivery
Never
Subscribed Events
10
Signing Secret
Not configured
Connection Test
Not tested

Webhook Endpoint Settings

Use the signing secret to verify that the webhook really came from NavYour. Never trust webhook payloads without verifying the signature.

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.