Receive status updates on your resources

Status updates for a payment are received via webhooks. A webhook is an HTTP request sent by Truelayer, everytime a status change occurs for a payment. You can configure the URI for this webhook in your Console.

You can find out more about console configuration.

Truelayer payment APIs will send only three of the statuses in the lifecycle of a payment. Failed, Executed and Settled. For more information about statuses, check out our page on payment statuses.

Header structure of the requests:

FieldTypeDescription
X-TL-Webhook-TimestamptimestampTime that the webhook was sent to you. This will be in the following format: 2020-05-18T10:17:47Z.
TL-SignaturestringJSON web signature with a detached payload of the form {HEADER}..{SIGNATURE}

More detailed information about the fields in the JSON body of the webhook request is as following:

Field

Type

Description

type

string

Type of the event.
Possible values:
payment_executed
payment_failed
payment_settled

event_id

string

Unique event UUID

payment_id

string

UUID of the payment for which the webhook is being sent

event_version

number

Version of the event

executed_at

string

Time of the event if the event is payment_executed

settled_at

string

Time of the event if the event is payment_settled

failed_at

string

Time of the event if the event is payment_failed

payment_source

json object

Source of the payment for which the event is being sent

user_id

string

UUID of the user associated to the payment

Some example requests

Executed

{
  "type": "payment_executed",
  "event_version": 1,
  "event_id": "b8d4dda0-ff2c-4d77-a6da-4615e4bad941",
  "payment_id": "60c0a60ed8d7-4e5b-ac79-401b1d8a8633",
  "executed_at": "2021-12-25T15:00:00.000Z",
  "payment_source": {
    "account_identifiers": [],
    "id": "string",
    "account_holder_name": "string"
  }
}

Failed

{
  "type": "payment_failed",
  "event_version": 1,
  "event_id": "b8d4dda0-ff2c-4d77-a6da-4615e4bad941",
  "payment_id": "60c0a60ed8d7-4e5b-ac79-401b1d8a8633",
  "failed_at": "2021-12-25T15:00:00.000Z",
  "failure_stage": "authorizing",
  "failure_reason": "provider_rejected"
}

Settled

{
  "type": "payment_settled",
  "event_version": 1,
  "event_id": "b8d4dda0-ff2c-4d77-a6da-4615e4bad941",
  "payment_id": "60c0a60ed8d7-4e5b-ac79-401b1d8a8633",
  "settled_at": "2021-12-25T15:00:00.000Z",
  "payment_source": {
    "account_identifiers": [
      {
        "type": "sort_code_account_number",
        "sort_code": "111111",
        "account_number": "00000111"
      },
      {
        "type": "iban",
        "iban": "GB11CLRB01011100000111"
      }
    ],
    "id": "1f111d3c-9427-43be-1111-1111219d111c",
    "account_holder_name": "HOLDER NAME"
  },
  "user_id": "ec01ece1-1dbe-48f1-82b2-bce8cfa44d08"
}

Validate the received webhook signature

We recommend developers to use our signing libraries to verify the signatures of the received webhooks.

📘

For the best development experience, use our signing libraries to verify signatures.

Verifying the signature manually

In order to verify that the webhook is coming from Truelayer (to prevent spoof attacks), you should validate the signature that comes with the webhook in the headers.

The value of the TL-Signature header contains a JSON Web Signature (JWS) with a detached payload. It takes the form {HEADER}..{SIGNATURE}.

The JWS header contains the following values:

FieldTypeDescription
algstringThe algorithm used to sign the webhook. We currently use the ES512 algorithm.
jkustringThe URI of the JSON Web Key Set (JWKS), a hosted page where a list of public keys owned by TrueLayer can be found.
kidstringThe ID of the key used to sign the webhook, used to retrieve the correct key from the JWKS.

The steps for verifying the signature are as follows:

1. Verify the jku field in the token header matches the expected value as listed below. If not, the signature should be rejected as invalid.
- Sandbox: https://webhooks.truelayer-sandbox.com/.well-known/jwks
- Production: https://webhooks.truelayer.com/.well-known/jwks
2. Use the jku value to retrieve the JWKS. This may be cached for some time, but if verification fails, the JWKS must be retrieved again to ensure that all keys are up-to-date. TrueLayer may rotate or revoke keys at any time.
3. Retrieve the relevant public key by using the kid to look up the relevant value from the JWKS.
4. Use a JWT library to verify the JWS headers combined with the payload.

Here is how to create the content for which you need to verify the signature

  • The HTTP VERB (capitalized), followed by a space, then the absolute path (without trailing slashes)
    Example: POST /webhook-endpoint, followed by a newline character \n
  • For each header specified in tl_headers, in the same order (and with the same casing):
    - The header name, followed by a colon, a space, then the header value, for example:
    content-type: application/json, followed by a newline character \n
  • The serialized HTTP request body (if sending a body)

The following example shows what a JWS payload might look like:

POST /webhook-endpoint
content-type: application/json
x-tl-webhook-timestamp: 2022-02-16T16:21:14Z    
{
  "type": "payment_executed",
  "event_version": 1,
  "event_id": "373920a2-61b0-438e-a525-48d3bfcf2762",
  "payment_id": "7f97fcbb-44b6-44bc-ae96-955d6e94cfd9",
  "executed_at": "2022-02-16T16:21:14.503Z"
}

Did this page help you?