Webhooks
Signed, retried, observable. Webhooks are how your backend learns an agent completed a checkout — and how you prove the integration is production-ready.
Register an endpoint
curl -X POST https://api.ordercore.ai/v1/webhooks/endpoints \
-H "X-API-Key: oc_live_..." -H "Content-Type: application/json" \
-d '{"url": "https://your-app.example/webhooks/ordercore", "events": ["checkout.completed"]}'The response returns a signing secret once — store it securely; it is never shown again. Primary event today: checkout.completed (event names are normalized to lowercase).
Verify signatures
Every delivery is signed with your endpoint secret. Verify the signature before trusting the payload — an unsigned or mis-signed request is not from OrderCore.
Each delivery carries three headers:
X-OrderCore-Event— the event name, e.g.checkout.completedX-OrderCore-Delivery-ID— identifies the delivery; every retry of it repeats the same valueX-OrderCore-Signature—sha256=followed by the hex HMAC-SHA256 of the raw request body, keyed with your endpoint secret
Compute it over the bytes as received, before any JSON parsing. Re-serialising the body changes it and the signature will not match.
import crypto from "node:crypto";
function verifyOrderCoreSignature(rawBody, header, endpointSecret) {
const expected = "sha256=" + crypto
.createHmac("sha256", endpointSecret)
.update(rawBody) // Buffer/string exactly as received
.digest("hex");
const a = Buffer.from(expected), b = Buffer.from(header ?? "");
return a.length === b.length && crypto.timingSafeEqual(a, b);
}Use a constant-time comparison (crypto.timingSafeEqual, hmac.compare_digest),
not ==.
The signature proves the delivery came from OrderCore and was not altered. It does not prove freshness: there is no timestamp in the signed material, so a captured delivery stays replayable.
Retries and idempotent consumption
Failed deliveries are retried automatically on retryable failures with backoff. Because deliveries can arrive more than once, consume idempotently: deduplicate on X-OrderCore-Delivery-ID, which a retry (or a replayed capture) repeats unchanged. Each registered endpoint gets its own delivery ID for the same event, so if several endpoints feed one receiver, deduplicate on the order id as well — exactly as agent-side retries use idempotency keys.
Observability: deliveries and metrics
Pending, failed, abandoned, and successful deliveries are exposed via the deliveries and metrics endpoints, so support (and your dashboards) can see webhook health per tenant. GET /v1/account/readiness includes webhook checks — an active checkout.completed endpoint, a recent successful delivery, and no abandoned deliveries in the last 24h — as part of the go-live checklist.
Webhook retries: a durable consumer and offline demo