Webhooks
Subscribe to events from a merchant store and receive signed HTTP callbacks at your endpoint.
How it works
When something interesting happens in a store — an order is paid, a product is updated, a plugin is configured — Aeonzap dispatches an event. You subscribe to the events you care about and we POST a JSON payload to your URL. Every request is signed so you can verify it came from us.
Subscribing
You can subscribe inside your plugin manifest, or call the subscriptions endpoint directly with a project token.
curl -X POST https://api.aeonzap.com/v1/webhooks \
-H "Authorization: Bearer $AEONZAP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://hooks.acme.dev/aeonzap",
"events": ["order.paid", "order.fulfilled", "product.updated"],
"secret": "whsec_change_me"
}'Event list
| Event | Fires when |
|---|---|
order.created | A draft or live order is first persisted |
order.paid | Payment confirmed by the gateway |
order.fulfilled | All line items have shipped |
order.cancelled | Order moves to cancelled state |
order.refunded | Any partial or full refund is issued |
customer.created | New customer record |
customer.updated | Customer profile changes |
customer.deleted | Customer is hard-deleted |
product.created | Product is published |
product.updated | Title, price, variants, or media change |
product.inventory.updated | Stock count crosses any threshold |
plugin.installed | A merchant installs your plugin |
plugin.configured | Plugin settings change |
plugin.uninstalled | Merchant removes the plugin |
Payload shape
{
"id": "evt_01HM6X9R2K8QA3T9V2BR8YGZN1",
"type": "order.paid",
"created_at": "2026-05-07T14:22:11.420Z",
"store": { "id": "store_4f2a", "domain": "acme.aeonzap.shop" },
"data": {
"order": { "id": "ord_8821", "total": 1499, "currency": "INR" }
}
}HMAC verification
Every request includes the headers X-Aeonzap-Timestamp and X-Aeonzap-Signature. Reject any request whose timestamp is more than 5 minutes off, then verify the signature using the secret you supplied at subscription time.
import crypto from 'node:crypto';
export function verify(req: { headers: Record<string, string>; rawBody: string }, secret: string) {
const ts = req.headers['x-aeonzap-timestamp'];
const sig = req.headers['x-aeonzap-signature'];
if (!ts || !sig) return false;
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
const expected = crypto
.createHmac('sha256', secret)
.update(`${ts}.${req.rawBody}`)
.digest('hex');
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig));
}Retries
A delivery is considered successful when your endpoint returns a 2xx within 10 seconds. We retry any other response with exponential backoff: 1m, 5m, 30m, 2h, 6h, 24h. After 6 failures the subscription is paused and you receive an email.
Replay
Failed events are kept for 30 days. You can replay any event from the developer console or via POST /v1/webhooks/{id}/replay.