Webhooks
Webhook functionality
Webhooks are the perfect way to create a scalable application by allowing you to get asynchronous updates on changes in the API. A webhook will be sent to your server url that you updated in the webhook-config
pertaining to your organization. Upon receiving a webhook, you should have your server respond back with a 200
response within 3 seconds to notify our server that you received the webhook successfully. The webhook config persists across all product stacks and APIs.
Consuming Webhooks
Because there is a limited response time, webhooks should be consumed by adding them to your own database table and immediately responding to the webhook server with a
200
code. From there, you can iterate on the webhooks from your own DB and also have a record of all the webhooks you've received.Webhooks will be retried at increasing time intervals if our webhook server does not receive a
200
response from you in time.
Setting up your Webhook-Config
Every Organization
is created with a webhook-config that is initially disabled. In order to enable the webhooks-config and select what events you want notifications for, you'll need to make a PATCH
call:
PATCH /api/organization/v1/current-organization/webhook-config
{
"url": "https://webhook.site/a5k730Q4", //Your receiving webhook server
"enabled": true,
"sharedSecret": "A7B6Fgl2KFI921gJ", //set a shared secret for webhook notification encryption
"webhookTypes": [
"payment", "kyc"
] // webhook types are "payment","transaction", "nft", "kyc", "document", "custodialAccount", "externalAccount", "identity", "asset", "wallet"
}
It's important to note that you'll only receive webhooks for the types that you have added to the webhookTypes
array.
Webhook structure
Here's an example of what a received webhook looks like:
{
"organizationId": "cbbb36e0-f507-40e8-a839-c8982de5c2da", //your integrator's organization
"action": "string", //
"id": "b3b3318e-fb35-49f6-a115-416f4e76c26c", //webhook id
"resourceId": "9c32c0d8-3e73-4896-8a7a-766c7428ac54", //API object's id to be referenced
"resourceType": "Payment", //API object that was either created or updated
"createdAtUtc": "2022-03-28T11:14:11.3704804+00:00", //webhook creation time
"changes": null //depending on the product suite, will either show "null" or key:value updates. Even a "null" value can have updates in the API but not present on the webhook object.
}
Whenever you receive a webhook, you should follow up with a GET
call in the api, targeting the resourceType
/resourceId
in the URL. You'll then be able to register the new object information in your DB/Front End, or make note of any changes to an existing object.
Webhook security
You might have noticed when updating your webhook-config that it asks for a sharedSecret
. The shared secret is hashed out with the contents of the webhook to create an encrypted value that is sent in the header of the webhook. This gives you confidence that the webhook did indeed come from our Fortress server. The verification formula looks like so:
Base64Encode(Hmac-Sha256(sharedSecret, webhookPayload))
The value of the encryption is to the key x-fortress-webhook-hmac
in the webhook header. Here's a sample curl response from a sent webhook.
curl -X 'POST' 'https://webhook.site/4de14c2c-9e4b-4a5a-b667-64a69f6da52f'
-H 'connection: close'
-H 'content-length: 266'
-H 'content-type: application/json; charset=utf-8'
-H 'traceparent: 00-317ed7516d09f1d424c95356ab4b377c-f194513ac07d6453-00'
-H 'request-id: |317ed7516d09f1d424c95356ab4b377c.f194513ac07d6453.'
-H 'request-context: appId=cid-v1:ec7b73c7-a50e-4e10-9be2-e81e0dd8abc2'
-H 'x-fortress-webhook-hmac: iM+cYc+/bpcBU2He+SBR+mIT1ngSre5cCx+rKSp+Nhk='
-H 'host: webhook.site'
-d $'{"organizationId":"083a1c85-0aed-4159-bf04-8b2a3f878f19","action":"create","id":"a7d247e2-9caf-42f0-b2a0-7cf55e09b954","resourceId":"cb822ebb-d273-4fd3-a0b4-622103fd6ab4","resourceType":"Transaction","createdAtUtc":"2022-05-25T21:21:55.0782343+00:00","changes":null}'
Updated 9 months ago