Overview
Rather than polling the Yonne API for order status changes, webhooks let Yonne push updates to your server the moment something happens. This enables:- Real-time order tracking — update your OMS as soon as a driver is assigned or an order is delivered.
- Automated customer notifications — send SMS or email confirmations without polling.
- Fulfilment automation — trigger warehouse or logistics workflows the instant an order changes state.
Setting up your endpoint
1. Configure your webhook URL and secret
In your Yonne merchant dashboard, navigate to Settings → Webhooks and fill in two fields:| Field | Description |
|---|---|
webhook_url | Your publicly reachable HTTPS endpoint that accepts POST requests (e.g. https://yourapp.com/webhooks/yonne) |
webhook_secret | A secret string shared between Yonne and your server, used to sign and verify every request |
No webhook_url, no webhooks. If this field is not set for your merchant account, Yonne will not send any webhook notifications for your orders.
2. Expose your endpoint
Your endpoint must be reachable from the public internet. During development, use a tunnelling tool to expose your local server:3. Respond with 200 OK within 10 seconds
Yonne considers any response outside the 10-second window as a failure and will schedule a retry. Return 200 as fast as possible and process the event asynchronously (see Best Practices).
The webhook payload
Every event uses the same envelope structure:Key fields
| Field | Description |
|---|---|
event | The event type that triggered this delivery (see Event Catalog) |
created_at | ISO 8601 timestamp of when the event occurred |
data.order_id | Yonne’s internal order identifier |
data.merchant_reference_id | Your own order ID, echoed back from the create-order call — use this to look up the order in your system |
data.tracking_url | A public link you can forward directly to your customer so they can track their rider in real time |
data.courier | Driver details — null for events that fire before a driver is assigned (e.g. order.failed) |
data.metadata | Any custom key/value object you attached to the order at creation time, echoed back |
The signature header
Yonne signs every webhook request and includes the signature in theX-Yonne-Signature header:
webhook_secret as the key.
Verifying the signature
Always verify the signature before processing the payload. Reject any request where the signature does not match.Critical: read raw bytes first. Compute the HMAC over the exact raw bytes Yonne sent. If you parse the JSON body first and then re-serialize it, the byte sequence will differ and the signature will never match — even for legitimate requests.
Use constant-time comparison. Always usetimingSafeEqual(Node.js) orhmac.compare_digest(Python) /hash_equals(PHP) when comparing signatures. A regular string equality check is vulnerable to timing attacks.
Best practices
Fast ACKs — respond immediately, process asynchronously
Your endpoint must return any2xx status code within 10 seconds. Yonne does not use the response body. If your processing logic (database writes, sending notifications, calling third-party APIs) might take longer, acknowledge first and do the work in a background job:
Idempotency — handle duplicates gracefully
The same event can be delivered more than once (e.g. if your server returned200 but the network dropped before Yonne received the response). Use the combination of order_id + event as a deduplication key:
Delivery guarantees & retries
Yonne guarantees at-least-once delivery. If your endpoint is unavailable or returns a non-2xx status, Yonne will retry with exponential backoff:
| Attempt | Delay after failure |
|---|---|
| 1st retry | 1 minute |
| 2nd retry | 15 minutes |
| 3rd retry | 60 minutes |
| After 3rd failure | Marked failed — no further retries |
| Scenario | What happens |
|---|---|
Your endpoint returns 2xx | Marked delivered — no retries |
Your endpoint returns 4xx / 5xx | Retried up to 3 times with backoff |
| Your endpoint times out (> 10 s) | Treated as failure — retried |
| Yonne server restarts mid-delivery | Event stays pending in the database and is picked up on the next scheduler tick |
| All 3 retries exhausted | Marked failed — visible in your webhook event log for manual inspection |
