Webhooks
Webhooks provide a way for your application to respond to real-time data. You can subscribe to any number of webhooks made available by the Squarepay system.
If your application is not ready to receive webhooks but you wish to understand how they works. You may use https://webhook.site to forward webhooks to, alternatively you may use a tool like https://ngrok.com/ to forward webhooks to your local development machine.
Webhook event types
Webhooks event types are formatted as <resource>.<action>
, for example payto_payment.cleared
will fire once a PayTo Payment has been successful (funds cleared). Webhook payload formatting is resource dependent, a payto_agreement
will be formatted as a PayTo Agreement, payto_payment
as a PayTo Payment, etc...
Event Type | Description |
---|---|
direct_debit.cleared | A direct debit (Payment) has settled. |
direct_debit.failed | A direct debit (Payment) has failed. |
disbursement.cleared | A disbursement has settled. |
disbursement.failed | A disbursement has failed. |
disbursement.change_rails | The initial disbursement channel has failed and the disbursement has automatically switched to attempt the payment using the next available channel. |
disbursement.cancelled | A disbursement has been cancelled. |
payid.activated | A Pay ID has been activated. |
payid.failed | A Pay ID has failed to be activated. |
payid.disabled | A Pay ID has been disabled. |
payid.deregistered | A Pay ID has been registered. |
payto_agreement.activated | Customer has accepted the agreement. |
payto_agreement.declined | Customer has declined the agreement. |
payto_agreement.expired | The agreement has expired. |
payto_agreement.failed | The agreement has failed (FI error). |
payto_agreement.cancelled | The pending agreement has been cancelled before acceptance. |
payto_agreement.reactivated | The agreement has been reactivated by the Customer. |
payto_agreement.suspended | The agreement has been cancelled by the Customer or Debtor. |
payto_agreement.amended | The agreement has been amended by the Debtor. |
payto_payment.cleared | A payto payment has settled. |
payto_payment.failed | A payto payment has failed. |
payto_payment.under_investigation | A payto payment is being manually reviewed. |
receivable.cleared | A receivable payment has settled to a Pay ID destination. |
Subscribing to events
You may subscribe to any numbers of events by using our API.
IMPORTANT
See our API reference on Webhook subscriptions.
Webhook delivery guarantees
Webhooks can fail to be sent due to a number of reasons, such as:
- Timeouts - We didn't receive a
2xx
response within 10 seconds of sending the webhook. - Unauthorised access - Server authorisation is required, however invalid authentication details were provided.
- The request was redirected - We don't follow any HTTP redirects, therefore we treat these as webhook failures.
We will try to deliver a webhook for up to 1 hour every 5 minutes. In sandbox webhooks will only be retried once.
IMPORTANT
See our API reference on Listing webhooks and Retrying webhooks.
Webhook security
There are several approaches to ensure webhooks are secure. All webhook endpoints in production required HTTPS and a valid SSL certificate to operate. To further safeguard webhooks the following security measures may be taken below:
IP Whitelisting
Environment | Description |
---|---|
Sandbox | Not specified |
Production | 13.54.231.91 |
URL Obfuscation
When creating a webhooks endpoint, consider using a URL that cannot be easily guessed. Keep in mind security via obscurity will only get you so far.
Source of truth
Instead of trusting the payload sent through the webhook, instead use the event as a signal to request the resource from our API (the source of truth) to get the fresh state of the object.
Webhook Signatures
Make use of webhook signatures, this is the slightly more complicated means of security but will ensure the request truly came from the expected sender. This method is further explained in Webhook signing below.
Webhook Signing
When a webhook subscription is created a shared secret will be generated to be used to sign the webhook to verify the authenticity. It is important that the shared secret is remains a secret and stored securely. Each created webhook subscription has a unique secret.
To assist with the signature verification we provide two headers in the request, X-Signature-SHA256
and X-Signature-Timestamp
. The X-Signature-Timestamp
is a unix timestamp and the X-Signature-SHA256
is the result of calculating a HMAC of the raw body and timestamp concatenated using the SHA-256 hash function and secret.
A webhook may be validated following the process below:
1. Extract the signature and timestamp
Extract both the signature
(X-Signature-SHA256
) the base64 encoded hmac and timestamp
(X-Signature-Timestamp
) unix timestamp from the http request headers.
2. Extract the payload Construct the signed payload literal**
Extract the payload
(raw JSON request body) from the http request.
3. Construct the signed_payload
string
Concatenate the following:
timestamp
- The character
.
(dot). payload
For example if the timestamp
was 1626226200
and the payload
was {"data":{"some_key":"some_payload"}}
then the resulting signed_payload
string will be 1626226200.{"data":{"some_key":"some_payload"}}
.
4. Compute the expected_signature
Compute a HMAC using the SHA256 hash function using your secret
and the signed_payload
, the resulting hash may need to be converted to a base64 encoded string.
The following input
s (secret
, signed_payload
) can be used to compute the expected output
(expected_signature
)
Input | Type | Value |
---|---|---|
secret | input | some-super-secret |
signed_payload | input | 1626226200.{"data":{"some_key":"some_payload"}} |
expected_signature | output | LfqR8ybCT0ZIINMMZVc2KBfei8t3JXnGzu8f+3suvSw= |
5. Compare signature
Compare both the extracted signature
from the headers and the calculated expected_signature
. If they are a match the webhook is considered verified.
TIP
Please reach out to us if you need assistance in your chosen framework for verifying signatures.