Webhooks are notifications about events in our system that are sent to a configured HTTPS endpoint. This section describes all available webhook events and the data contained in them.
Integrating an IHD webhook into your solution will help you receive delivery events close to realtime and avoid polling to refresh the data.
Request verification
To verify that an incoming webhook request was not maliciously modified we include a digital signature as a part of the request headers. The signature must be validated to ensure no fraudulent event notification has occurred.
The IHD-Signature header is included in each signed event and contains a timestamp and one or more signatures. The timestamp is prefixed by t=, and each signature is "s", followed by an integer. Currently, the only valid live signature scheme is s1
X-Signature:
t=1492774577,
s1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd
IHD generates signatures using a hash-based message authentication code (HMAC) with SHA-256.
To verify webhook event signatures, you can use the following steps.
Step 1 Extraction
Extract the timestamp and signatures from the header
Split the IHD-Signature header, using the , character as the separator, to get a list of elements. Then split each element, using the = character as the separator, to get a prefix and value pair.
The value for the prefix t corresponds to the timestamp, and s1 corresponds to the signature. You can discard all other elements.
Step 2 Prepare the signed_payload string
The signed_payload string is created by concatenating:
The timestamp (as a string)
The character .
The actual JSON payload (that is, the request body)
Step 3 Determine the expected signature
Compute an HMAC with the SHA256 hash function. Use your CLIENT SECRET as the key, and use the signed_payload string as the message.
Step 4: Compare the signatures
Compare the signature (or signatures) in the header to the expected signature. For an equality match, compute the difference between the current timestamp and the received timestamp, then decide if the difference is within your tolerance.
To protect against timing attacks, use a constant-time string comparison to compare the expected signature to each of the received signatures.
Retries on failure
Once IHD webhook payload is posted to the target URL, any HTTP response code other than 2XX is considered a failure. In this case IHD will re-try to trigger the webhook notification 4 more times based on these intervals: 10 secs, 1 min, 5 mins, 10 mins.
Upon failure of the last try, IHD will send an email to the partner notifying them of the failure. Notification emails are sent once every hour in order to avoid sending too many failure emails.
Webhook notifications
The webhook payloads include 2 main properties:
- event_id: Unique id for the webhook trigger
- event_time: Unix timestamp for the webhook trigger
- event: Event name for the webhook trigger
- data: Data object that relates to triggered event
Delivery notifications
Triggered when an order transitions into another status (e.g. accepted -> pickup). The following are the delivery events:
delivery.new
delivery.update
delivery.rejected
delivery.canceled
delivery.delivered
delivery.returned
delivery.delayed.pickup
delivery.delayed.dropoff
delivery.refund.requested
delivery.refund.approved
delivery.refund.declined
billing.invoice.charged
billing.invoice.failed
Here's a sample response that you can expect. In this instance the order status has transitioned into delivered status.
{
"event_id": "<guid>",
"event_time": 1645329838,
"event": "delivery.delivered",
"data": {
"delivery": {
"id": "1232ea9c-e2a7-4a16-9327-977314913d4f",
"service_provider": "postmates",
"order_id": "del_224nBy6TS2fIGoa_8SNAQ",
"order_reference": "1",
"order_type": "delivery",
"status": "delivered",
"quote": null,
"pickup": {
"name": "Bob's Pizza",
"phone_number": "15552853000",
"address": "165 Jefferson st, San Francisco, CA, USA",
"notes": "Tell our staff that you are here to pick up an RTO Order",
"location": {
"lat": 37.8081966,
"lng": -122.41522974
},
"detailed_address": {
"city": "San Francisco",
"country": "US",
"state": "CA",
"street_address_1": "165 Jefferson St",
"street_address_2": "",
"sublocality_level_1": "",
"zip_code": "94133"
},
"verification": {
"picture": {
"image_url": ""
}
}
},
"dropoff": {
"name": "Terry G.",
"phone_number": "15558125337",
"address": "11 Benton Avenue, San Francisco, CA, USA",
"notes": "",
"location": {
"lat": 37.74254,
"lng": -122.43656
},
"detailed_address": {
"city": "SF",
"country": "US",
"state": "",
"street_address_1": "11 Benton Avenue",
"street_address_2": "",
"sublocality_level_1": "",
"zip_code": "94112"
},
"verification": {
"picture": {
"image_url": ""
}
}
},
"order_items": [
{
"name": "Mushroom pizza",
"quantity": 1,
"price": 2764
}
],
"distance": 2176,
"created_at": "2022-02-15 03:17:01",
"updated_at": "2022-02-15 04:55:52",
"pickup_at_ready": "2022-02-15 04:01:58",
"pickup_at_eta": "2022-02-15 04:48:13",
"live_pickup_at_eta": "2022-02-15 04:48:13",
"pickup_at": "2022-02-15 04:48:14",
"dropoff_at_eta": "2022-02-15 04:55:49",
"live_dropoff_at_eta": "2022-02-15 04:55:49",
"dropoff_at": "2022-02-15 04:55:49",
"customer_fee": 0,
"fee": 850,
"tip": 0,
"total": 0,
"currency": "usd",
"tax": 0,
"tracking_url": "https://www.ubereats.com/orders/12eef72c-10ba-4d2d-9f20-aa1affc48d01",
"courier": {
"name": "Junjie",
"rating": "4.95",
"vehicle_type": "car",
"phone_number": "+11283337624",
"location": {
"lat": 0,
"lng": 0
},
"img_href": ""
},
"location": {
"id": "167a94e0-010c-4419-8303-2210523c4201"
},
"requires_id": false,
"requires_signature": false,
"refund": null,
"manager_note": null,
"tags": null,
"attributes": {
"refundable": true
}
}
}
}
"refund": {
"status": "rejected",
"request_at": "2021-04-06 00:48:02",
"refund_note": "Refund Note",
"resolved_at": "2021-04-06 00:48:16",
"requester_id": "052b4d7c-0585-4a5a-a47e-cec6c0498648",
"refund_amount": 120,
"reject_reason": "N/A",
"requester_name": "Support Account"
},
