Withdrawals

You need funds in your account to create withdrawals. The PayDirect API supports two types of withdrawal:

📘

You need to sign POST requests to /v1/users/withdrawals. Check our page on request signing to learn how to sign POST requests to PayDirect API endpoints.

Closed-loop withdrawal

Make a closed-loop withdrawal request to /v1/users/withdrawals, and include:

FieldTypeDescription
user_iduuidThe unique id of the user you would like to pay out to. For more information, see Deposits.
account_iduuidThe unique id of the user's account you would like to pay out to.
transaction_iduuidThe unique id of the withdrawal you want to create. If two POST /withdrawal requests are submitted with the same transaction_id only the first one will be processed. transaction_id can therefore be used to ensure idempotency for withdrawal creation.
beneficiary_referencestringAn 18 character reference that will appear on the account holder's bank statement.
currencyISO 4217 Currency Code StringThe currency you are sending the payment in. Each currency is associated with its own account, therefore the currency denotes which account the funds will be sent from.
amount_in_minorintegerThe amount to send to the account holder in the smallest denomination of the currency specified. e.g. if transacting in GBP this will be in pennies.
curl -X POST \
     -H "Authorization: Bearer ${access_token}" \
     -H "X-TL-Signature: ${signature}" \
     --data '{
        "user_id": "<UUID>",
        "account_id": "<UUID>",
        "transaction_id": "<UUID>",
        "beneficiary_reference": "Withdrawal 204",
        "currency": "GBP",
        "amount_in_minor": 10000
}' \
https://paydirect.truelayer-sandbox.com/v1/users/withdrawals

You'll get an HTTP 202 response for a successful request.

Retrieve closed-loop withdrawal

📘

This feature is in private beta and is currently available to a limited number of clients. To join our private beta, contact Client Care.

You can query the status of a closed-loop deposit using the v1/users/{user_id}/accounts/{account_id}/withdrawals/{transaction_id} endpoint. Make sure to include the user_id, account_id and transaction_id used in creating the closed-loop withdrawal.

curl -H "Authorization: Bearer ${access_token}" \
 https://paydirect.truelayer-sandbox.com/v1/users/${user_id}/accounts/${account_id}/withdrawals/${transaction_id}

You'll get a response like the following:

{
   "result": {
     "transaction_id": "32ca16ba-3eea-4494-a105-49586cb293a8",
     "authorised_at": "2021-09-08T12:45:59.969503Z",
     "submitted_at": "2021-09-08T12:46:00.252166Z",
     "settled_at": "2021-09-08T12:46:01.927Z",
     "rejected_at": null,
     "failed_at": null,
     "beneficiary_name": "John Smith",
     "beneficiary_iban": "GB33BUKB20201555555555",
     "beneficiary_reference": "Test Withdrawal",
     "amount_in_minor": 10000,
     "currency": "EUR",
     "status": "settled",
     "context_code": "withdrawal"
   }
 }

Open-loop withdrawal

📘

This feature is in private beta and is currently available to a limited number of clients. To join our private beta, contact Client Care.

You can make withdrawals to a bank account that hasn't been used to make a deposit before. For this, we'll need the beneficiary's IBAN. You can follow our guide on verified payouts to collect your user's bank account details and verify their account ownership before making withdrawals.

📘

You need to sign POST requests to /v1/withdrawals. Check our page on request signing ] to learn how to sign POST requests to PayDirect API endpoints.

Make an open-loop withdrawal request to /v1/withdrawals, and include:

FieldTypeDescription
transaction_iduuidThe unique id of the withdrawal you want to create. If two POST /withdrawal requests are submitted with the same transaction_id only the first one will be processed. transaction_id can therefore be used to ensure idempotency for withdrawal creation.
beneficiary_namestringThe name of the account holder you are sending funds to. This name must match the name associated with the account, otherwise the withdrawal will fail validation. It must be at most 18 characters long.
beneficiary_ibanstringThe full IBAN of the account holder you are sending funds to. The IBAN must be accessible by the Faster Payments Scheme if transacting in GBP.
beneficiary_referencestringAn 18 character reference that will appear on the account holder's bank statement.
currencyISO 4217 Currency Code StringThe currency you are sending the payment in. Each currency is associated with its own account, therefore the currency denotes which account the funds will be sent from.
amount_in_minorintegerThe amount to send to the account holder in the smallest denomination of the currency specified. e.g. if transacting in GBP this will be in pennies.
context_codestringThe code to describe why you are making the withdrawal.
curl -X POST \
     -H "Authorization: Bearer ${access_token}" \
     -H "X-TL-Signature: ${signature}" \
     --data '{
        "transaction_id": "<UUID>"
        "beneficiary_name": "John Smith",
        "beneficiary_iban": "GB33BUKB20201555555555",
        "beneficiary_reference": "Withdrawal 204",
        "currency": "GBP",
        "amount_in_minor": 10000,
        "context_code": "withdrawal"
}' \
https://paydirect.truelayer-sandbox.com/v1/withdrawals

You'll get an HTTP 202 response for a successful request.

Retrieve open-loop withdrawal

You can query the status of an open loop deposit using the v1/withdrawals/{transaction_id} endpoint. Make sure to include the transaction_id used in creating the open-loop withdrawal.

curl -H "Authorization: Bearer ${access_token}" \
 https://paydirect.truelayer-sandbox.com/v1/withdrawals/{transaction_id}

You'll get a response like the following:

{
   "result": {
     "transaction_id": "dfbec5cf-567a-4ebe-aa2a-7aa71de654f5",
     "authorised_at": "2021-09-07T16:25:23.315517Z",
     "submitted_at": "2021-09-07T16:25:23.607579Z",
     "settled_at": "2021-09-07T16:25:25.043Z",
     "rejected_at": null,
     "failed_at": null,
     "beneficiary_name": "John Smith",
     "beneficiary_iban": "GB33BUKB20201555555555",
     "beneficiary_reference": "Test Withdrawal",
     "amount_in_minor": 10000,
     "currency": "EUR",
     "status": "settled",
     "context_code": "withdrawal"
   }
 }

Withdrawal Statuses

📘

This feature is in private beta and is currently available to a limited number of clients. To join our private beta, contact Client Care.

A withdrawal can be in a number of different states. If it is a closed-loop withdrawal, you can query the status of your withdrawal using the GET v1/users/{user_id}/accounts/{account_id}/withdrawals/{withdrawal_id} endpoint. PayDirect will send webhook notifications for status transitions (including open-loop withdrawals).

StateTerminalDescription
newNoThe withdrawal has been created with TrueLayer but has not yet been authorised and sent to the payment scheme for execution.
authorisedNoTrueLayer has performed a funds check and there are sufficient funds to make the transaction.
submittedNoTrueLayer has submitted the withdrawal to the payment scheme for execution.
settledYesThe scheme has notified TrueLayer that the withdrawal has settled into the end account.
failedYesThe withdrawal failed, this may be because of an internal error or an error with the payment scheme. This state can occur at any stage before settled.
rejectedYesThe withdrawal was rejected, this can be because of a lack of funds or a risk check. This state can occur at any stage before settled.

Withdrawal rejection codes

CodeDescription
insufficient_fundsYour account does not have sufficient funds required to make the withdrawal.
server_errorWe encountered a technical issue when authorising the payment. Please try again later.

Next steps

Learn more about verified withdrawals to user accounts:

Did this page help you?