Webhooks
Webhooks push domain events to your HTTPS endpoint so you do not poll.
Subscribe
POST /v1/webhooks
Authorization: Bearer isk_live_...
Idempotency-Key: wh_create_orders_01
Content-Type: application/json
{
"url": "https://integrations.example.com/hooks/ioneshop",
"events": ["order.created", "order.paid", "inventory.changed"],
"description": "ERP bridge"
}
Response includes id, status, and a signing secret (shown once) — or the secret is managed in BO and never re-displayed.
Delivery request
POST /hooks/ioneshop HTTP/1.1
Host: integrations.example.com
Content-Type: application/json
X-IoneShop-Signature: <hex hmac sha256>
X-IoneShop-Timestamp: 1735689600
X-IoneShop-Delivery-Id: del_01J...
X-IoneShop-Event: order.paid
Body (canonical signed form):
{
"event": "order.paid",
"timestamp": "2026-08-01T12:00:00Z",
"payload": {
"id": "ord_01J...",
"status": "paid",
"total": { "amount": 4999, "currency": "EUR" }
}
}
Header branding note
Public contract headers use the X-IoneShop-* prefix. During platform cutover, deliveries may also send legacy aliases (x-ecom-signature, x-ecom-timestamp, x-ecom-delivery-id). Verifiers should accept either until Sunset is announced in the changelog.
Security
HMAC verification (required in production)
Canonical algorithm (only): HMAC-SHA256 over the exact raw HTTP request body (UTF-8 bytes as received), hex-encoded. Do not re-serialize JSON before verify.
- Read raw body bytes (disable JSON body parsers that consume the stream first)
- Compute
hex = HMAC_SHA256(webhook_secret, raw_body) - Compare with
X-IoneShop-Signatureusing a constant-time compare - Reject if
X-IoneShop-Timestampskew > 5 minutes (replay window) - Persist
X-IoneShop-Delivery-Idand ignore duplicates
Node.js sketch:
import { createHmac, timingSafeEqual } from "node:crypto";
function verify(secret, rawBody, signatureHex) {
const expected = createHmac("sha256", secret).update(rawBody, "utf8").digest("hex");
const a = Buffer.from(expected, "hex");
const b = Buffer.from(signatureHex, "hex");
return a.length === b.length && timingSafeEqual(a, b);
}
Endpoint requirements
- HTTPS only (TLS 1.2+; 1.3 preferred)
- Respond
2xxwithin 10 seconds - Do heavy work async after ack
- Optional Enterprise: IP allowlist for webhook egress
Retry policy
On non-2xx or timeout:
| Attempt | Delay after failure |
|---|---|
| 1 | 1 minute |
| 2 | 5 minutes |
| 3 | 30 minutes |
| 4 | 2 hours |
| 5 | 24 hours |
After exhausting retries → dead letter (dead). Merchant BO can replay. Enterprise may configure custom schedules.
Testing
- BO Send test event (when available in Merchant BO)
- Sandbox signed deliveries
- Local: forward with a tunnel; never disable signature verify in shared code paths
- Unit fixtures: Webhook HMAC test vectors
Event catalog
See Events.