Webhooks
A quick overview of webhooks at Modern Dropship, formerly Convictional.
Heads up!
Webhooks do not currently support:
- manual retrying, cancelling or queuing of requests
- seeing a list of events or the status of individual events
- authentication
Stability is high but not guaranteed.
Events are currently dispatched every minute.
Webhooks are intended as a way to simplify the implementation of an API integration. It is important to recognize that there is a limit to the guarantees we can make. For example, we can guarantee that there will be at least one delivery attempt per event. There may be instances of multiple delivery attempts from a webhook, it is important to monitor the UUIDs of the events to determine what has been processed. Furthermore, for any data that is critical there must be additional API integration to reconcile data at regular intervals.
Currently if you configure a webhook, our system will send that endpoint the affected piece of data; as well as an "event type" that describes what happened to that data.
For example, a order.fulfilled
event denotes that a fulfillment was added to an order.
Limitations of Modern Dropship Events
Events are still subject to the syncing intervals of the platforms from where they came. This means that you will not get inventory updates or fulfillments as they happen but rather a burst of events when our workers run and sync new values from integrated platforms.
For a list of when these workers run please see this table.
Configuring webhooks
There are currently no self-serve methods to configure webhooks exposed by the Modern Dropship API. In order to start using webhooks you must reach out to [email protected] and our Technical Engagement team can work with you to ensure that your desired event types are supported and enter configuration information into our system.
All you need to get started with webhooks currently is:
1. An endpoint that accepts HTTP POST requests
2. Idea of what data changes you want to subscribe to
3. A secret key used for payload validation
You can have a single webhook endpoint receive one or more event types and you can have as many different endpoints as you like.
You can also configure rate and burst limits for your webhooks if necessary.
Hosting Webhook Receivers
Currently webhook receivers must be publicly accessible endpoints using HTTPS.
Supported events
Since the list of supported events is changing rapidly so if you're interested in finding out more about this please email [email protected]
Request data model
Each request dispatched to your webhook listener function must accept the following data model.
Property | Data Type | Notes | Example |
---|---|---|---|
id | string | Internal UUID of the event. Useful for communicating with support in case of issues. | 626ca583-e709-4e1a-a876-0bd47c609a40 |
type | string | Type of the event. This basically tells you what happened and what the data means. | product.selected |
created | string | This is the Date-Time stamp of when the event was created. This is not the time at which the request was sent. | 2021-10-19T14:48:22.544+00:00 |
data | object | This is the attached data to the event. Usually this will be the same data model that is exposed through our RESTful API. For example, the product.selected event will attach the same model as returned by this endpoint. | Please see the API Documentation to see what data would be attached here. |
Example:
{
id: "616e45ce25ecfe1c81de6c02",
type: "product.selected",
created: "2021-10-19T14:48:22.544+00:00",
data: {...}
}
Retrying requests and dealing with outages
While we do not guarantee delivery or only-once delivery we do have a truncated, exponential backoff retry mechanism in case there is an outage, network error or internal error.
Internally we use the following formula to figure out when a request should be retried in case it fails:
Min(2^n + random, max backoff)
where max backoff
is currently capped at 24 hours. This means that worst case scenario events will be retried once a day. The random
part is a value between 0 and 1000 milliseconds that is used to avoid excessive bursting.
Retrying limitations
We will only retry webhooks for a maximum of 3 days from the creation of the event.
If you experienced an outage for longer than 3 days you can reach out to [email protected] and request for older events to be resent.
Security
Verifying Request
It is up to your webhook consumer to verify the authenticity of the webhook request.
Each webhook request that sent will have a Convictional-Signature
HTTP Header that will contain a hash value used to verify that the payload of the event and the request itself are authentic.
The attached Convictional-Signature
header contains a UNIX timestamp and a hash for every active secret you have configured delimited by commas.
Rotating webhook secrets
In order to support no-outage secret rotations we support the ability to have more than one active secret at a time with automatic deactivation at a given time. A hash will be generated for each secret and appended to the header string.
The signature hash is generated by using combining the timestamp
supplied in the header earlier with the string of the body separated by a period.
To avoid automatic escaping or parsing of escape sequences we must take the raw body buffer of the request body.
Then you must use SHA256
to encode the timestamp
and requestBody
delimited by a period and signed with the secret.
For example, if you configured a webhook with a secret of mySecret
Your function receives the following event:
{
"id": "616e45ce25ecfe1c81de6c02",
"type": "message.hello",
"created": "2021-10-19T14:48:22.544+00:00",
"data": {
"message": "hello world"
}
}
with the following header:
Convictional-Signature: 1634751311,e93fbf11ce896938c6a42b55205bbbf38baec4658b05efc8dc1b6fa59e873f63
You can split that by ,
to get the timestamp, 1634751311
, and the hash e93fbf11ce896938c6a42b55205bbbf38baec4658b05efc8dc1b6fa59e873f63
To validate that you must combine the body with the timestamp delimited by a period.
1634751311.{
"id": "616e45ce25ecfe1c81de6c02",
"type": "message.hello",
"created": "2021-10-19T14:48:22.544+00:00",
"data": {
"message": "hello world"
}
}
Then generated a hash using the SHA256
algorithm signed with your secret.
If the signature you generate is the same one that is attached to the header then you know that this is a valid request that has not been tampered with and you can proceed to process that information.
You can use this tool to play around with SHA256
encodings: https://www.devglan.com/online-tools/hmac-sha256-online
Troubleshooting
Signatures don't match
If you're running into issues where your program is not generating the same signatures as the ones in the header try using the a raw byte representation of the request body to generate the signature with. Some web frameworks (e.g., Node) will automatically clean, interpret and unescape payloads which can influence the hash generation step.
Sample Code
More Info
If you are looking for more information on Webhooks with Modern Dropship, we also have support documentation here.
Updated about 2 months ago