Overview
Instead of polling for order status, you can configure Henry to push events directly to your server via webhooks. When an order transitions state - placed, completed, cancelled - Henry fires an HTTP POST to your endpoint with a signed payload. Webhooks are configured per-cart via thesettings.events array on cart.create.
How it works
1. Register a webhook endpoint
Go to the Henry Dashboard, open your app settings, and add a webhook endpoint URL. Henry will generate a webhook UUID and a webhook secret for that endpoint.- The UUID is used in cart settings to reference the webhook
- The secret is used to verify incoming requests (keep it private, like an API key)
2. Configure a cart with webhook events
Pass the webhook UUID insettings.events when creating a cart. Henry fires that webhook when the specified event occurs.
3. Receive and verify the webhook
Henry sends aPOST request with three important headers:
Always verify the signature before processing the payload.
Verification logic
Full server example (Node.js / Express)
Full server example (Bun)
Webhook payload structure
Henry sends a consistent envelope for all events. Each delivery is a single attempt with a 10-second timeout and is not retried.Example payload
Event types reference
Events follow a dot-notation hierarchy. Subscribing to a parent event fires for all child events - soorder.purchase also receives the legacy full / partial events, and one settled order produces more than one delivery.
Order events
A purchase settles once and fires exactly one oforder.purchase.complete (every item purchased), order.purchase.partially_complete (some items purchased) or order.purchase.failed (nothing purchased). After an item fails, the event can wait up to an hour before it fires, so it always reports the final outcome. Until then the order and that item read processing in every event payload, as they do when polled.
The full and partial events are kept for existing integrations. While the purchase is pending / processing they say whether every cart item was attempted together. Once it settles they follow the outcome: complete also fires order.purchase.full.complete, partially_complete also fires order.purchase.partial.complete and order.purchase.partial.failed, and failed also fires order.purchase.full.failed.
orderId is the same refId that cart.checkout.purchase returns. details.email, details.phone and details.shippingAddress are included only when the cart collects them. items[].recoveryUrl is a link back to the merchant for that item. On order.purchase.cancelled, results carries cancelledAt and reason instead of costs.
Points & tier events
Conditionals
Each event insettings.events accepts an optional conditional that filters when the trigger fires. Two types are supported:
Next steps
Polling
Prefer polling for product search and details jobs
Universal Cart
Configure webhook events when creating a cart