Subscription
Unit uses webhooks to notify your application when an event occurs.
Example events: Application denied
, Customer created
, Transaction created
. See Events for the full list.
New event types are continuously added to the platform. It is up to you to decide which events you want to process and how, but your implementation of the event listener must be able to handle new event types without breaking.
When one of those events occurs, an HTTP POST request is sent to the webhook's configured URL, allowing you to act upon it.
Unit highly recommends that you make your webhook handlers Idempotent, to ensure events are only handled once on your end.
Use Unit's Dashboard or API to create and manage your webhooks.
Unit sends POST requests to your webhook's URL from one of the following IP addresses:
Unit IPs
Environment | IP Addresses |
---|---|
Sandbox | 54.81.62.38 35.169.213.205 3.234.105.75 |
Live | 3.209.193.26 54.156.65.95 54.165.224.37 |
Please note that these IP addresses are subject to change.
Webhooks that were unresponsive for 7 days will change status to Unavailable
and will cease to receive events until they are re-enabled.
Include Resources
When creating the webhook through the API or the Dashboard, you may specify whether you would like events to include the the full resource that is associated with the event.
When this option is being used every webhook that is related to a specific resource will have the full resource included in the payload of the event - for instance, the customer.created
event will include the full customer
resource.
Delivery method
Unit supports two methods of delivery attempts for the webhook subscriptions:
- At most once (single)
- At least once (batched)
When creating the webhook, you can specify this in the dashboard (or programmatically via the API).
When using At most once, an attempt will be made to deliver a single webhook event to the specified URL. If the delivery fails for any reason (timeout or HTTP response code other than 200), the event will not be retried. An event will be fired as soon as it is created but only after a response for the last event has been received (therefore delays might occur when a large number of events are triggered at the same time or if responses from the client's webhook server are delayed).
When using At least once, multiple events will be batched in a single payload (in the form of an array of multiple event ids) and will be delivered to the specified URL, retrying delivery in case of a timeout, or a non-successful HTTP POST. Events will be fired as soon as they are created but only after a response for the last batch has been received. The maximum number events for a single batch is 64.
It is recommended to use 'OnlyAuthorizationRequest' in case of implementing Programmatic authorization of card use with 'AtMostOnce' deliveryMode due to the sensitive nature of this flow.
To avoid processing the retried events more than once when using the At least once delivery mode, make sure to implement idempotence using the eventId
as the key.
When using the At least once delivery, retrying is performed using the Fibonacci backoff algorithm, with up to 1 hour between retries.
Securing your webhooks
Ensure your server is only receiving the expected Unit requests.
Once your server is configured to receive payloads, it'll listen for any payloads sent to the endpoint you configured.
For security reasons, you probably want to verify that the payloads are coming from Unit.
To verify the payloads when creating a webhook you can set up a secret token which Unit will use to sign the payloads.
Setting up your secret token
You'll need to set up your secret token in two places: Unit dashboard and your server. To set your token in Unit Dashboard:
- Navigate to Webhooks on the top menu under Developer section.
- Click on create and fill up the token field.
Verifying payloads from Unit
If your secret token is set, Unit will use it to create a hash signature with the entire body of the webhook request.
This hash signature, encoded with base64 is passed along with each request in the headers as X-Unit-Signature.
Unit uses an HMAC SHA1 to compute the hash.
const express = require('express')
var crypto = require('crypto')
const app = express()
const port = 4000
app.post('/my-webhook', (request, response) => {
response.send('request passed signature validation...')
})
app.use(express.json());
app.use(express.urlencoded({
extended: true
}));
app.use((request, response, next) => {
var signature = request.header("x-unit-signature")
var hmac = crypto.createHmac('sha1', <your secret>)
hmac.update(JSON.stringify(request.body))
if(hmac.digest('base64') == signature) {
next()
}
else {
response.status(500).send("Signatures didn't match!")
}
})
app.listen(port, (err) => {
console.log(`server is listening on ${port}`)
})
Subscription types
We have 3 subscription types:
- 'All' - subscribe to all events
- 'OnlyAuthorizationRequest' - subscribe only to authorization request
authorizationRequest.pending
,authorizationRequest.approved
,authorizationRequest.declined
- 'NotAuthorizationRequest' - subscribe to events except for authorization requests
Testing
To test the Webhook functionality you can use https://webhook.site. This site will let you generate a unique URL to use for your Webhook and then capture incoming requests, allowing you to examine the event's contents.
Another alternative is to use https://ngrok.com which enables you to expose a port on your development machine to the internet.
Create Webhook
Creates a webhook.
Verb | POST |
Url | https://api.s.unit.sh/webhooks |
Required Scope | webhooks-write |
Data Type | webhook |
Timeout (Seconds) | 5 |
Attributes
Name | Type | Description |
---|---|---|
label | string | A label describing the webhook. |
url | string | The URL of the webhook endpoint. |
token | string | The secret token (see Securing your webhooks). |
contentType | string | The type of content you wish to receive. Either Json or JsonAPI . |
deliveryMode | string | The attempted delivery mode of the webhook. Either AtMostOnce or AtLeastOnce . |
includeResources | boolean | Optional. Default: false. Indicates whether to include full resource in events payload. |
subscriptionType | string | Optional. specify the subscription type. Default: All. Either 'All' or 'OnlyAuthorizationRequest' or 'NotAuthorizationRequest'(see Subscription types) . |
curl -X POST 'https://api.s.unit.sh/webhooks'
-H 'Content-Type: application/vnd.api+json'
-H 'Authorization: Bearer ${TOKEN}'
--data-raw '{
"data": {
"type": "webhook",
"attributes": {
"label": "some label",
"url": "https://webhook.site/81ee6b53-fde4-4b7d-85a0-0b6249a4488d",
"token": "MyToken",
"contentType": "Json",
"deliveryMode": "AtLeastOnce",
"includeResources": false,
"subscriptionType": "OnlyAuthorizationRequest"
}
}
}'
Get by Id
Get a webhook resource by id.
Verb | GET |
Url | https://api.s.unit.sh/webhooks/{id} |
Required Scope | webhooks |
Timeout (Seconds) | 5 |
Response
Response is a JSON:API document.
200 OK
Field | Type | Description |
---|---|---|
data | Webhook | The requested resource after the operation was completed. |
curl -X GET 'https://api.s.unit.sh/webhooks/10' \
-H "Authorization: Bearer ${TOKEN}"
List
List webhook resources. Paging can be applied.
Verb | GET |
Url | https://api.s.unit.sh/webhooks |
Required Scope | webhooks |
Timeout (Seconds) | 5 |
Query Parameters
Name | Type | Default | Description |
---|---|---|---|
page[limit] | integer | 100 | Optional. Maximum number of resources that will be returned. Maximum is 1000 resources. See Pagination. |
page[offset] | integer | 0 | Optional. Number of resources to skip. See Pagination. |
filter[since] | RFC3339 Date string | (empty) | Optional. Filters the results that occurred after the specified date. e.g. 2020-01-13T16:01:19.346Z |
filter[until] | RFC3339 Date string | (empty) | Optional. Filters the results that occurred before the specified date. e.g. 2020-01-02T20:06:23.486Z |
filter[fromId] | Integer | (empty) | Optional. Filters the results that have an id that is higher or equal to the specified id. e.g. 17421 |
filter[toId] | Integer | (empty) | Optional. Filters the results that have an id that is lower or equal to the specified id. e.g. 17432 |
curl -X GET 'https://api.s.unit.sh/webhooks?page[limit]=20&page[offset]=10' \
-H "Authorization: Bearer ${TOKEN}"
Response
Response is a JSON:API document.
200 OK
Field | Type | Description |
---|---|---|
data | Array of Webhook | Array of webhook resources. |
{
"data": [
{
"type": "webhook",
"id": "1",
"attributes": {
"createdAt": "2021-02-03T08:17:28.010Z",
"label": "111",
"url": "https://webhook.site/81ee6b53-fde4-4b7d-85a0-0b6249a4488c",
"status": "Disabled",
"contentType": "Json",
"token": "",
"subscriptionType": "OnlyAuthorizationRequest"
}
},
{
"type": "webhook",
"id": "2",
"attributes": {
"createdAt": "2021-02-09T14:54:42.612Z",
"label": "some label",
"url": "https://webhook.site/81ee6b53-fde4-4b7d-85a0-0b6249a4488d",
"status": "Enabled",
"contentType": "Json",
"token": "MyToken",
"subscriptionType": "NotAuthorizationRequest"
}
}
]
}
Update
Update a webhook.
Verb | PATCH |
Url | https://api.s.unit.sh/webhooks/:id |
Required Scope | webhooks-write |
Timeout (Seconds) | 5 |
Attributes
Name | Type | Description |
---|---|---|
label | string | The label of the webhook. To modify or add specify the new label. |
url | string | The URL of the webhook endpoint. To modify or add specify the new URL. |
contentType | string | The content type of the webhook. To modify or add specify the new content type. |
token | string | The secret token of the webhook. To modify or add specify the token. |
includeResources | boolean | Indicates whether to include full resource in events payload. |
subscriptionType | string | Optional. specify the subscription type (see Subscription types). |
Response
Response is a JSON:API document.
200 OK
Field | Type | Description |
---|---|---|
data | Webhook | The requested resource after the operation was completed. |
{
"data": {
"type": "webhook",
"attributes": {
"label": "some label",
"contentType": "Json",
"includeResources": true,
"subscriptionType": "OnlyAuthorizationRequest"
}
}
}
Enable
Enable a webhook.
Verb | POST |
Url | https://api.s.unit.sh/webhooks/:id/enable |
Required Scope | webhooks-write |
Timeout (Seconds) | 5 |
Response
Response is a JSON:API document.
200 OK
Field | Type | Description |
---|---|---|
data | Webhook | The requested resource after the operation was completed. |
curl -X POST 'https://api.s.unit.sh/webhooks/7/enable' \
-H "Authorization: Bearer ${TOKEN}"
Disable
Disable a webhook. Webhooks that have been disabled or become Unavailable
due to inactivity may be enabled.
Verb | POST |
Url | https://api.s.unit.sh/webhooks/:id/disable |
Required Scope | webhooks-write |
Timeout (Seconds) | 5 |
Response
Response is a JSON:API document.
200 OK
Field | Type | Description |
---|---|---|
data | Webhook | The requested resource after the operation was completed. |
curl -X POST 'https://api.s.unit.sh/webhooks/7/disable' \
-H "Authorization: Bearer ${TOKEN}"