Payout webhooks
Payout notifications sent to your webhook URI registered in Console, when a payout becomes executed or fails.
The Payments API sends webhooks for two of the statuses in the lifecycle of a payout: executed and failed. Learn about the other payout statuses, pending and authorized.
There are three different ways to specify the beneficiary of a payout: payouts to a payment source, payouts to an external account, and payouts to a business account. This guide includes webhook examples for payouts to each beneficiary type.
Validate webhooks
You must always verify the authenticity of incoming webhook requests. To do this, we recommend that you use the webhook signing library, allowing your application to confirm that the request originated from TrueLayer and has not been tampered with.
To allowlist TrueLayer calls, add a unique query parameter to your webhook URI for identification. For enhanced security, include a self-signed JWT token as a callback parameter, which you can then decode to verify its contents. For example: https://mywebhook.app?unique_param=x
Payout to payment source webhooks
Also called a closed-loop payout.
payout_executed
| Field | Type | Description |
|---|---|---|
type | string | Type of the event. In this case, it would be: payout_executed |
event_id | string | The UUID of that specific event. |
event_version | number | Version of the event |
payout_id | string | UUID of the payout for which the webhook is being sent |
executed_at | string | Timestamp of the event, in ISO8601 format |
beneficiary.type | string | Value would be payment_source.This indicates that the payout is made to the payment_source. |
beneficiary.payment_source_id | string | ID of the external account which has become a payment source. |
beneficiary.user_id | string | ID of the user that owns the external account. |
scheme_id | string | The id of the scheme used to execute the payout. Values are: - unknown- faster_payments_service- internal_transfer- sepa_credit_transfer- sepa_credit_transfer_instant |
merchant_account_id | string | The merchant account the payout was made from. |
current_balance_in_minor | number | The current balance of the merchant account in minor. |
available_balance_in_minor | number | The available balance of the merchant account in minor. |
metadata | string | Optional field for adding custom key-value data to a resource. This object can contain a maximum of 10 key-value pairs, each with a maximum key length of 40 characters and a maximum value length of 500 characters. |
{
"type": "payout_executed",
"event_version": 1,
"event_id": "b8d4dda0-ff2c-4d77-a6da-4615e4bad941",
"payout_id": "0cd1b0f7-71bc-4d24-b209-95259dadcc20",
"executed_at": "2021-12-25T15:00:00.000Z",
"beneficiary": {
"type": "payment_source",
"payment_source_id": "4a59c822-3bfb-42ba-9202-b6d89988a195",
"user_id": "a0977be8-c406-4f75-bb81-b5ca0689b29b",
},
"scheme_id": "faster_payments_service",
}
payout_failed
| Field | Type | Description |
|---|---|---|
type | string | Type of the event. In this case, it would be: payout_failed |
event_id | string | The UUID of that specific event |
event_version | number | The version of the event |
payout_id | string | UUID of the payout for which the webhook is being sent |
failed_at | string | Timestamp of the event, in ISO8601 format |
failure_reason | string | The reason of the payout failure |
beneficiary.type | string | Value would be payment_source.This indicates that the payout is made to the payment_source. |
beneficiary.payment_source_id | string | ID of the external account which has become a payment source. |
beneficiary.user_id | string | ID of the user that owns the external account. |
merchant_account_id | string | The merchant account the payout was made from. |
current_balance_in_minor | number | The current balance of the merchant account in minor. |
available_balance_in_minor | number | The available balance of the merchant account in minor. |
metadata | string | Optional field for adding custom key-value data to a resource. This object can contain a maximum of 10 key-value pairs, each with a maximum key length of 40 characters and a maximum value length of 500 characters. |
{
"type": "payout_failed",
"event_version": 1,
"event_id": "b8d4dda0-ff2c-4d77-a6da-4615e4bad941",
"payout_id": "0cd1b0f7-71bc-4d24-b209-95259dadcc20",
"failed_at": "2021-12-25T15:00:00.000Z",
"failure_reason": "insufficient_funds",
"beneficiary": {
"type": "payment_source",
"payment_source_id": "9ac7ab1f-6229-47db-9e17-81072d2dbdf3",
"user_id": "9775a22c-23c7-41c8-9e7c-1508997db9c0",
}
}
Payout to an external account webhooks
When you make a payout to an external account with its own specified account identifiers. This is also called an open-loop payout.
payout_executed
| Field | Type | Description |
|---|---|---|
type | string | Type of the event. In this case, it would be: payout_executed |
event_id | string | The UUID of that specific event |
event_version | number | The version of the event |
payout_id | string | UUID of the payout for which the webhook is being sent |
executed_at | datetime | Timestamp of the event, in ISO8601 format |
beneficiary.type | string | Value will be external_account |
beneficiary.account_holder_name_verification | string | An object that includes information about account holder verification performed on the beneficiary. Only applicable in EUR payouts. |
beneficiary.account_holder_name_verification.status | string | Includes the result of the verification attempt, plus any other information. Can be completed or failed. |
beneficiary.account_holder_name_verification.failure_reason | string | Details about why account holder verification failed. You only see this field alongside a status of failed.Possible failure reasons include: Bank unable to match: The bank account is closed, or could not be found, or another similar error.Party agent not part of scheme: This bank is not part of the verification scheme.VoP scheme provider error: There's a failure with one of the providers in the scheme. (We recommend retrying when you receive this error.) |
beneficiary.account_holder_name_verification.match_result | string | If the match is completed, this object includes the result of the account holder verification check and any additional information. |
beneficiary.account_holder_name_verification.match_result.type | string | Can be: - no_match - full_match - match_not_possible, where you also get a failure reason explaining what went wrong - partial_match, where you also get the name that the bank expects to see |
beneficiary.account_holder_name_verification.match_result.reason | string | The reason that the account holder's name and details couldn't be verified. You only see this field alongside a match result of match_not_possible |
beneficiary.account_holder_name_verification.match_result.account_holder_name | string | The name that the bank expects to see, if the name that your user provided partially but not completely matches the name on file at the bank.You only see this field alongside a match result of partial_match |
scheme_id | string | ID representing the payment scheme that the payout was made on. |
payout_failed
| Field | Type | Description |
|---|---|---|
type | string | Type of the event. In this case, it would be: payout_failed |
event_id | string | The UUID of that specific event |
event_version | number | The version of the event |
payout_id | string | UUID of the payout for which the webhook is being sent |
failed_at | string | Timestamp of the event, in ISO8601 format |
failure_reason | string | The reason of the payout failure |
beneficiary.type | string | Value will be external_account |
merchant_account_id | string | The merchant account the payout was made from. |
current_balance_in_minor | number | The current balance of the merchant account in minor. |
available_balance_in_minor | number | The available balance of the merchant account in minor. |
metadata | string | Optional field for adding custom key-value data to a resource. This object can contain a maximum of 10 key-value pairs, each with a maximum key length of 40 characters and a maximum value length of 500 characters. |
{
"type": "payout_executed",
"event_version": 1,
"beneficiary": {
"type": "external_account",
"account_holder_verification": {
"status": "completed",
"match_result": {
"type": "match"
}
}
},
"executed_at": "2021-12-25T15:00:00.000Z",
"scheme_id": "faster_payments_service",
"payout_id": "0cd1b0f7-71bc-4d24-b209-95259dadcc20",
"event_id": "b8d4dda0-ff2c-4d77-a6da-4615e4bad941"
}
{
"type": "payout_failed",
"event_version": 1,
"event_id": "24089aed-4fd4-9e13-f8b2-f458f30c836c",
"payout_id": "0a495e9f-2f41-4669-ba33-85407c0b26cb",
"failed_at": "2024-01-12T14:56:05.117850644Z",
"failure_reason": "insufficient_funds",
"beneficiary": {
"type": "external_account"
}
}
Verified payout webhooks
Webhooks for a verified payout contain more information.
payout_executed
| Field | Type | Description |
|---|---|---|
type | string | Type of the event. In this case, it would be: payout_executed |
event_id | string | The UUID for that specific event |
event_version | number | Version of the event |
payout_id | string | UUID of the payout for which the webhook is being sent |
executed_at | string | Timestamp of the event, in ISO8601 format |
merchant_account_id | string | The merchant account the payout was made from. |
current_balance_in_minor | number | The current balance of the merchant account in minor. |
available_balance_in_minor | number | The available balance of the merchant account in minor. |
metadata | string | Optional field for adding custom key-value data to a resource. This object can contain a maximum of 10 key-value pairs, each with a maximum key length of 40 characters and a maximum value length of 500 characters. |
beneficiary.type | string | The type of bank account you're paying out to. Can be external_account, payment_source, user_determined or business_account. |
beneficiary.account_holder_name_verification | string | An object that includes information about account holder verification performed on the beneficiary. |
beneficiary.account_holder_name_verification.outcome | string | An object inside account_holder_name_verification that includes the result of the verification attempt, plus any other information. |
beneficiary.account_holder_name_verification.outcome.type | string | The result of account holder name verification. Can be: - no_match- full_match- match_not_possible, where you also get a failure reason explaining what went wrong- partial_match, where you also get the name that the bank expects to see |
beneficiary.account_holder_name_verification.outcome.name | string | The name that the bank expects to see, if the name that your user provided partially but not completely matches the name on file at the bank.You only see this field alongside an outcome.type of partial_match |
beneficiary.account_holder_name_verification.outcome.failure_reason | string | Details about why account holder verification failed. You only see this field alongside an outcome.type of match_not_possible. |
beneficiary.user.id | string | A UUID that represents the user. |
beneficiary.provider_id | string | The provider_id that represents the bank the payout is being made to. |
beneficiary.account_holder_name | string | The name of the beneficiary. |
beneficiary.account_identifiers.type | string | Can be sort_code_account_number or iban. |
scheme_id | string | The id of the scheme used to execute the payout. Values are: - unknown- faster_payments_service- internal_transfer- sepa_credit_transfer- sepa_credit_transfer_instant |
{
"type": "payout_executed",
"event_version": 1,
"beneficiary": {
"type": "external_account",
"account_holder_name_verification": {
"outcome": {
"type": "partial_match",
"name": "John Sandbridge"
}
},
"user_id": "string"
},
"metadata": {
"prop1": "value1",
"prop2": "value2"
},
"event_id": "b8d4dda0-ff2c-4d77-a6da-4615e4bad941",
"payout_id": "0cd1b0f7-71bc-4d24-b209-95259dadcc20",
"executed_at": "2021-12-25T15:00:00.000Z",
"scheme_id": "faster_payments_service"
}
payout_failed
| Field | Type | Description |
|---|---|---|
type | string | Type of the event. In this case, it would be: payout_failed |
event_id | string | The UUID of that specific event |
event_version | number | Version of the event |
payout_id | string | UUID of the payout for which the webhook is being sent |
failed_at | string | Timestamp of the event, in ISO8601 format |
failure_reason | string | The reason of the payout failure |
merchant_account_id | string | The merchant account the payout was made from. |
current_balance_in_minor | number | The current balance of the merchant account in minor. |
available_balance_in_minor | number | The available balance of the merchant account in minor. |
metadata | string | Optional field for adding custom key-value data to a resource. This object can contain a maximum of 10 key-value pairs, each with a maximum key length of 40 characters and a maximum value length of 500 characters. |
{
"type": "payout_failed",
"event_version": 1,
"event_id": "f8a144dc-a550-4681-844b-4de231ec3764",
"payout_id": "f8a144dc-a550-4681-844b-4de231ec3764",
"failed_at": "2022-09-14T16:41:21.006718283Z",
"failure_reason": "insufficient_funds",
"beneficiary": {
"type": "user_determined",
"account_holder_name": "John Doe",
"account_identifier": {
"type": "sort_code_account_number",
"sort_code": "040075",
"account_number": "58114637"
}
},
"merchant_account_id": "a1b2c3d4-e5f6-7890-abcd-1234567890ef",
"current_balance_in_minor": 500000,
"available_balance_in_minor": 450000,
"metadata": {
"order_id": "12345",
"customer_id": "67890"
}
}
Payout to a business account
When you make a payout to the linked business account you specified during your onboarding with TrueLayer.
payout_executed
| Field | Type | Description |
|---|---|---|
type | string | Type of the event. In this case, it would be: payout_executed |
event_id | string | The UUID of that specific event. |
event_version | number | Version of the event |
payout_id | string | UUID of the payout for which the webhook is being sent |
executed_at | string | Timestamp of the event, in ISO8601 format |
beneficiary.type | string | Value would be business_account |
scheme_id | string | The id of the scheme used to execute the payout. Values are: - unknown- faster_payments_service- internal_transfer- sepa_credit_transfer- sepa_credit_transfer_instant |
merchant_account_id | string | The merchant account the payout was made from. |
current_balance_in_minor | number | The current balance of the merchant account in minor. |
available_balance_in_minor | number | The avilable balance of the merchant account in minor. |
metadata | string | Optional field for adding custom key-value data to a resource. This object can contain a maximum of 10 key-value pairs, each with a maximum key length of 40 characters and a maximum value length of 500 characters. |
{
"type": "payout_executed",
"event_version": 1,
"event_id": "b8d4dda0-ff2c-4d77-a6da-4615e4bad941",
"payout_id": "0cd1b0f7-71bc-4d24-b209-95259dadcc20",
"executed_at": "2021-12-25T15:00:00.000Z",
"beneficiary": {
"type": "business_account"
},
"scheme_id": "faster_payments_service",
}
payout_failed
| Field | Type | Description |
|---|---|---|
type | string | Type of the event. In this case, it would be: payout_failed |
event_id | string | The UUID of that specific event. |
event_version | number | Version of the event |
payout_id | string | UUID of the payout for which the webhook is being sent |
failed_at | string | Timestamp of the event, in ISO8601 format |
beneficiary.type | string | Value would be business_account. |
merchant_account_id | string | The merchant account the payout was made from. |
current_balance_in_minor | number | The current balance of the merchant account in minor. |
available_balance_in_minor | number | The available balance of the merchant account in minor. |
metadata | string | Optional field for adding custom key-value data to a resource. This object can contain a maximum of 10 key-value pairs, each with a maximum key length of 40 characters and a maximum value length of 500 characters. |
{
"type": "payout_failed",
"event_version": 1,
"event_id": "b8d4dda0-ff2c-4d77-a6da-4615e4bad941",
"payout_id": "0cd1b0f7-71bc-4d24-b209-95259dadcc20",
"failed_at": "2021-12-25T15:00:00.000Z",
"beneficiary": {
"type": "business_account"
}
}
{
"type": "payout_failed",
"event_version": 1,
"event_id": "b8d4dda0-ff2c-4d77-a6da-4615e4bad941",
"payout_id": "0cd1b0f7-71bc-4d24-b209-95259dadcc20",
"failed_at": "2021-12-25T15:00:00.000Z",
"beneficiary": {
"type": "business_account"
}
}
Updated 11 days ago
