Withdrawals [PayDirect]

Pay out to your users with PayDirect.

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

📘

Note

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

To make a closed-loop withdrawal request to /v1/users/withdrawals, 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 appears 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, so the currency also denotes which merchant account you will pay out from.
amount_in_minorintegerThe amount to send to the account holder in the smallest denomination of the currency you're paying in.
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 withdrawal 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 this:

{
   "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",
   }
 }

Open-loop withdrawal

📘

Note

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

An open-loop withdrawal is a payout to a bank account that hasn't already been used to make a deposit. For this, we'll need the beneficiary's IBAN. Follow our guide on verified payouts to collect your user's bank account details and verify that they own the account before making withdrawals.

📘

Note

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. Since you have a different merchant account for each currency, this also 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. For example, if payments are in GBP, this will be in pennies.
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,
}' \
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 withdrawal 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 this:

{
   "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",
   }
 }

Withdrawal Statuses

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, but has not yet been authorised and sent to the payment scheme for execution.
authorisedNoWe've performed a funds check and confirmed that there are enough funds in your account to make the transaction.
submittedNoWe've submitted the withdrawal to the payment scheme for execution.
settledYesThe scheme has notified us that the withdrawal has settled into the beneficiary 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 enough money in it to make the withdrawal.
server_errorWe encountered a technical issue when authorising the payment. Try again later.