Webhooks

# Allowing Webhook Origins

To utilise webhooks, you need to whitelist HTTP origins of the application to which webhooks will be sent. This is done through the Enable Banking Control Panel by editing application properties, as shown in the screenshot below.

Allowed webhook origins

# Authorisation of Webhooks

Each webhook request contains Authorization header, which must be verified by the webhook handler to ensure authensity of webhook requests. The value of the Authorization header is the string starting with the authentication type Bearer followed by a space, and then the JSON Web Token (JWT).

JWT header is expected to contain the following parameters:

  • alg: Algorithm used for the JWT signature (always "RS256" as only RS256 is supported)
  • typ: Media type of the JWT (always "JWT")
  • x5u: URL pointing to the X.509 public key, which can be used to verify the JWT signature. When verifying the JWT, webhook handlers must ensure that the URL uses the HTTPS protocol and the host in the URL is the enablebanking.com domain or one of its subdomains, e.g. api.enablebanking.com.

JWT payload is expected to contain the following claims:

  • sub: ID of the application towards which the webhook has been triggered, which is concidered to be the principal that is the subject of the JWT
  • environment: Environment to which the application is registered, either PRODUCTION or SANDBOX
  • msgi: Base64 encoded SHA-256 digest of the webhook payload (i.e. the body of the webhook request) prefixed by the digest algorithm identifier: sha256-NuG6gBMSYMmLvPo3qFG4fxNle0A6lN+Z0rBcxIcZbYw=

Webhook handlers must check the JTW signature, the value of the x5u parameter of the JWT header, and the value of the msgi claim of the JWT payload.

# Acknowledgement of Webhooks

Endpoints receiving webhook requests are expected to respond within 10 seconds with one of the following response codes:

  • 102
  • 200
  • 201
  • 202
  • 204

In case the endpoint responds with any other code, the webhook is not acknowledged and will be retried. Unacknowledged webhooks will be retried for the next 24 hours (with the maximum retry time of 600 sec). When webhooks are retried their, their payload (the body of the webhook requests) remain the same, however the header (e.g. X-Request-ID and Authorization) may change.

# Payment Status Webhook

The Payment Status Webhook provides notifications about changes in the status of payments. To use the webhook, the webhook_url field is to be included in the request body for the POST /payments endpoint. The URL passed into the webhook_url field will be triggered whenever the status of the payment changes or when it is no longer expected to change.

The following table contains description of the fields of the JSON body of the webhook request.

Name Type Required Description
payment_id string(uuid) true Unique identifier for the payment
payment_status PaymentStatus true Current status of the payment
payment_updates_expected boolean true Indicates whether updates to the payment status are expected
webhook_id string true Unique identifier for the webhook event (the same value is used if the webhook is retried)
webhook_triggered string true Date and time when the webhook was triggered (ISO 8601 format)
payment_auth_status string false Current status of the payment authorisation performed by the end-user. The field can contain values FAILED, CANCELLED, FINALISED or PENDING. If payment authorisation is not yet started by the end-user, the field won't be set or may contain null value.

Example webhook request

POST https://example.com/webhooks/payment HTTP/1.1
Host: example.com
User-Agent: Python/3.10 aiohttp/3.9.1
Content-Length: 183
Accept: */*
Accept-Encoding: gzip, deflate, br
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsIng1dSI6Imh0dHBzOi8vZW5hYmxlYmFua2luZy5jb20vd2ViaG9vay1wcm9kdWN0aW9uLWF1dGgtcHVibGljLWtleS5wZW0ifQ.eyJzdWIiOiIwNjAyYWZiYi0yYTY0LTQ0YmYtOTZiOC04MzcyYTg1YWY0ZWUiLCJlbnZpcm9ubWVudCI6IlBST0RVQ1RJT04iLCJtc2dpIjoic2hhMjU2LU51RzZnQk1TWU1tTHZQbzNxRkc0ZnhObGUwQTZsTitaMHJCY3hJY1piWXc9In0.Qyb_qyFbleyoZ3StKaGZ-fY8Hs2IjIhkkCGEdg9QXcOPVBGaOA5vQF7jIunmX4u3CCBt0tkN0djEf8EvQn7yVgvqnJZq9wMZY3yBlvOybUKE01XPBWWXave4nVxGnvCRB1Nq_x1azeNnprrP2_f3Cmn9VtOXF6gPcsFo5d-ojGQlDPORwHrtrB37JHPhOrH1tdpbqzABQYoF6MgXCKzn1RsWHyXm29qjDJdMH_DgAfDrMD90DICZCgs1SOY110EAPOw10NipuySqCRzXt1IWelxjfwubDd3de-aPSOAWr_pURpEyWSynmJ9QrD8jupB88fulooGppjOFGprMeCj_NA
Content-Type: application/json
X-Request-Id: e736cc33-5ed9-4afe-b5a6-ddc51ba7e140
{"payment_id": "834ef801-18c1-49a4-a46a-fbc5928b7a81", "payment_status": "RJCT", "payment_updates_expected": false, "webhook_id": "cfb6b9e6-e386-4197-afb0-d368e555d5fd", "webhook_triggered": "2024-03-01T13:24:43.746344+00:00"}