Payments API webhook reference

Set up webhooks to get updates on payments or mandates in our Payments API v3.

Webhooks are JSON-format notifications you receive when any event occurs within the Payments API v3. You can use these to trigger processes within your backend or integration. This is especially useful for asynchronous events, such as a user authorising a payment.

In order to receive webhooks, you must specify a Webhook URI for them to be sent to on the Settings page in Console.

What webhooks can tell you

We recommend that you use webhooks in all integrations. They inform you when events take place within a payment's lifecycle, including when a payment, mandate, payout or refund transitions between statuses. For example, webhooks inform you about:

  • when a payment changes to a new status in the authorisation process
  • whether a payment has succeeded or failed
  • more details about why and when a payment failed
  • when your merchant account is approaching or below a certain amount of funds, and when it has just been topped up
  • when you can consider a payment to be creditable, even if it hasn't settled
  • when the settlement of a payment has stalled for a defined period of time

When we add new webhooks, they are added to the list on this page, in the relevant webhook documentation, and also the API reference.

Webhook categories

There are a variety of webhooks, split into categories for each type of payment. Click a category to see a full list of webhooks for that payment type with examples. Alternatively, see the table on this page that contains a full list of possible webhooks.

Payment webhooks apply to all payments, including:

  • pay-ins to your merchant account (closed-loop payments)
  • payments to an external account (open-loop payments)
  • payments on a mandate

There are a variety of payment webhooks, which you receive when a payment transitions to each possible status. Additionally, there are extra webhooks you receive that confirm when a payment is creditable, when a payment has stalled, or when you receive a payment from an external account.

There are only two webhooks for payouts, payout_executed and payout_failed. However, the content of these webhooks varies based on the type of payout, which can be:

  • a payout to a source that paid in (closed-loop payout)
  • a payout to an external account (open-loop payout)
  • a payout to the business account linked to your merchant account

As such, there are six possible webhook formats for payouts.

You receive two webhooks for refunds, one when a refund is executed, or one when a refund fails.

Mandate webhooks relate specifically to payment mandates, which determine the constraints that apply to a mandate, and whether it is currently authorised and valid.

For variable recurring payments made over a mandate, you receive payment webhooks with a payment_method.type of mandate.

Merchant account webhooks apply specifically to your merchant account and their associated client_id.

There is currently one merchant account webhook, which informs you when your merchant account balance is approaching a value you specify with us.

There are two webhooks for payment links. One that tells you when a payment is created by a user through a payment link, and one that tells you when a payment link expires.

Notably, the payment_linked_payment_created webhook contains a payment id. You should use that payment id to track the progress of the payment through payment webhooks.

Possible webhooks

The Payments API v3 currently supports the following webhooks. Click a webhook to see more information about it within the appropriate area of the documentation.

WebhookDescription
payment_authorizedThe payment was authorised by the user with their bank.
payment_executedThe payment was executed.
payment_failedThe payment failed.
payment_settledThe payment has settled.
payment_creditableYou can consider the payment to have settled.
payment_settlement_stalledThe payment did not reach settled status after a specified amount of time.
external_payment_receivedThe external payment has settled.
mandate_authorizedThe mandate was authorized.
mandate_failedThe mandate creation failed.
mandate_revokedThe mandate was revoked.
payment_link_payment_createdA payment was created through a payment link.
payment_link_disabledThe payment link was disabled.
payout_executedThe payout was executed. Notification structure differs between closed-loop, open-loop or business account payouts.
payout_failedThe payout failed. Notification structure differs between closed-loop, open-loop or business account payouts.
refund_executedThe refund was executed.
refund_failedThe refund failed.
balance_notificationAn update on when a merchant account balance hits 100%, 150% or 200% of a specified threshold.

Webhook structure

All our webhooks include the following two headers:

FieldTypeDescription
X-TL-Webhook-TimestampISO-8601 TimestampTime that the webhook was sent to you. This is in this format:

2020-05-18T10:17:47Z
TL-SignaturestringJSON web signature with a detached payload of the form:

{HEADER}..{SIGNATURE}

All incoming webhook requests must have their signatures verified, otherwise you risk accepting fraudulent payment status events. Learn more about how to validate received webhook signatures.

All webhook bodies are encoded in JSON format with the following fields:

FieldTypeDescription
typestringThe type of the webhook. This can be any of the Payments API webhooks.
event_idstringA UUID for the webhook event.
event_versionstringThe version of the webhook event. Currently, this can only have a value of 1.

However, each type of event contains other fields. See the documentation for different categories of webhook for more information and examples.

🚧

Handling duplicated webhooks

TrueLayer can't guarantee that you’ll only receive a single webhook notification for each payment status. As such, your integration should have logic that can handle receiving multiple webhooks for a given payment status.

For example, imagine TrueLayer sends a payment_executed webhook, but doesn't receive a 200 response due to network issues from the recipient. In this case, TrueLayer sends an extra executed webhook as it cannot confirm the previous one was received, regardless of the current status of the payment.

We make sure that the event_id is the same for duplicated webhooks, but check the payment_id or payout_id as well.