Webhooks
webhooks documentation
WEBHOOKS
Webhooks are event notifications we send you through HTTP/HTTPS requests. The webhooks requests are composed of three important parts:
- URL
- Signature
- Payload
URL
The URL is the HTTP/HTTPS address where we send you the request. You indicate the URL when you create a new webhook through our App, see Webhook Creation section.
Signature
Each webhook request is signed using a secret or key, the payload and the timestamp. The webhook request headers contain the signature and the timestamp in a custom header called Mono-Signature
.
The header Mono-Signature
is like the following example:
Mono-Signature: t=1672328528,v1=662255ca79c4b21914894d32da10189a1482cd0fee56b2765a8b472662ce55ac
t is the timestamp, You can use it to validate if the request is not in your desired time range, see more at replay attacks.
The v1 is the signature version, and its value is the signature. You can use it to validate if the webhook request was sent from our system. You can see more information in the verifying signatures manually section.
Note: currently, we only use the signature version v1
Payload
The webhook request payload is JSON data containing the event's information. The main schema is like the following example:
{
"event": {
"data": {...},
"type": "event_type_or_name"
},
"timestamp": "2022-12-29T15:42:08.325158Z"
}
For more information about the specific data by each event see webhook events section.
Attempts
When a webhook request fails, the system retries this request. Each attempt is executed X seconds after the previous attempt,
if the last attempt is executed and it fails the webhook request will not be sent anymore.
The following table describes how the request will be retried:
attempt | time |
---|---|
1 | immediately |
2 | 30 seconds |
3 | 1.5 minutes |
4 | 3.5 minutes |
5 | 7.5 minutes |
6 | 15.5 minutes |
7 | 31.5 minutes |
8 | 1.06 hours |
9 | 2.13 hours |
10 | 4.26 hours |
These times are an approximation. The system executes a maximum of ten attempts in 8.4 hours.
Webhook events
When a webhook is created or registered the following events will be associated to it:
Accounts
Bank transfers
- bank_transfer_approved
- bank_transfer_rejected
- bank_transfer_fallback_routing
- batch_canceled
- batch_sent
- batch_duplicated
Card transactions
Collection intents
Webhooks creation
Webhook creation is done through the user interface. Below you will find a detailed step by step.
- Go to settings.
- Click on Personal.
- Click on API.
- Click new webhook.
- Insert the HTTPS/HTTP URL that you had configured to listen the events.
- Click on save.
If everything is working as expected, there will be an alert indicating that we were successfully created your webhook, and you should be able to see the URL listed on the page.
Considerations
Webhook urls
are unique, meaning that you can only create one webhook for the same url
. If for some reason you want to create a new webhook for an existing URL in your account, you should delete the previous one and create the new one pointing to the previously deleted URL, a new secret for that url
will be generated.
Always verify that you are receiving information from the webhook in your systems.
URL restrictions:
- It can not be blank / Do not leave it blank
- The url should start with and http or https prefix.
- The host can not be 127.0.0.1 or localhost.
- Must be a valid HTTP/HTTPS URL.
Detail view of the webhook
To access this view click on the arrow at the end of the column where your URL is displayed.
The detailed webhook view of the webhook contains the secret that is visually hidden. Click on the show/hide eyeball to see the whole secret.
Once revealed you should be able to use it, to verify that we are the ones that send you the payload. BE CAREFUL secret sharing is discouraged.
Verifying signatures manually
Step 1 Extract the timestamp and signatures from the headers
Split the header using the ,
character as the separator, to get a list of elements
t=1672328528
v1=662255ca79c4b21914894d32da10189a1482cd0fee56b2765a8b472662ce55ac
Step 2 prepare the signed_payload
string
signed_payload
stringthe string should be as follow
<timestamp>.<payload_rawbody>
Step 3 check the expected signature
Compute an HMAC with the SHA256 hash function. Use the endpoint’s signing secret as the key, and use the signed_payload string as the message.
an example in ruby
require 'openssl'
timestamp = 1672774221
raw_payload = '{"respose_body": "example"}'
signed_payload = "#{timestamp}.#{raw_payload}"
secret="whsec_example" #grab this secret from the page
hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), secret, signed_payload)
hmac
652fdc1742906b4b23ce2a5f4ac417b52c264fea0207920a5e76330a87239924
the last number should be the one that you check against the one that came in the payload.
Step 4 Checking signatures
Compare the signature in the header to the expected signature. Compute the difference between the current timestamp and the received timestamp, then decide if the difference is within your time tolerance range.
To protect against timing attacks, use a constant-time string comparison to compare the expected signature to the received signatures.
Money fields
Fields that specify money values are defined in two key value pairs, one for the currency, and other for the amount. In these fields the money is represented in the minimum unit, which is cents.
For example:
240000 = 2400,00
160 = 1,60
Money fields that come with decimal units represent the original value. This is the case of the fx_rates field, where
"2400,32" = 2400,32
Updated 5 months ago