Verified payouts

Learn how to verify user accounts for withdrawals and make your first withdrawal to a verified account.

📘

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

Our quickstart guide to payouts introduces verifying and paying out to an account in TrueLayer's sandbox environment using TrueLayer's account verification and PayDirect capabilities.

Set up configurations in Console

  1. Sign up to Console to get your client_id and client_secret.

  2. Enable PayDirect API for your test application in sandbox.

Note that the Data API is enabled for all clients by default. You can find guidance on certificate generation and examples of request signing in our GitHub.

Set up Insomnia

We offer Insomnia collections for our Verification API and PayDirect API as a helper to make
these requests. Follow our guide to setup Insomnia with our Verification API insomnia collection and PayDirect API insomnia collection. It contains sample requests so that you can start using the APIs straightaway.

📘

Check our page on request signing ] to learn how to sign POST requests to PayDirect API endpoints.

Make an initial payout to an account

You need to verify the user account before making a first payout to it. To do so:

  1. Generate a test authentication page.
  2. Exchange the code for an access token.
  3. Verify the user account.

Generate a test authentication page

To verify your user's account, you need to generate a test authentication link. The link creates an authentication page where the user can authenticate with their bank. The authentication page provides your application with permissions to view relevant information about their bank account.

To create an auth link in the Auth Link Builder of our Console:

  1. Go to the Providers tab and select Mock. This is the mock bank used in our sandbox for test purposes.

  2. In the Permissions tab, make sure info and accounts are selected. These scopes are
    required for account verification.

  3. Make sure the URI selected in the "Redirect URIs" tab is allow-listed in the App
    settings
    section of the Console.

  4. Select the Preview your Auth Dialog button to test your auth page.

  5. Select Mock Bank and use the following details when asked for input--this is a user
    within our sandbox mock bank:

    • Username: john
    • Password: doe
  6. You will now get a code which you can exchange for an access token to verify the accounts
    belonging to "john doe".

Exchange the code for an access token

Using the code from the previous step, call the Authentication API to get an access token which
allows you to read details about the user's account. This is the Exchange Code request in the
Insomnia collection.

export CLIENT_ID="your-client-id"
export CLIENT_SECRET="your-client-secret"
export CALLBACK_URI="your redirect uri"
export CODE="your-code"

curl -X POST -H "Content-Type: application/x-www-form-urlencoded" \
    "https://auth.truelayer-sandbox.com/connect/token" \
    --data-urlencode "grant_type=authorization_code" \
    --data-urlencode "client_id=${CLIENT_ID}" \
    --data-urlencode "client_secret=${CLIENT_SECRET}" \
    --data-urlencode "redirect_uri=${CALLBACK_URI}" \
    --data-urlencode "code=${CODE}"

You'll get a response with the access token:

{
  
    "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjE0NTk4OUIwNTdDOUMzMzg0MDc4MDBBOEJBNkNCOUZFQjMzRTk1MTBSUzI1NiIsInR5cCI6ImF0K2p3dCIsIng1dCI6IkZGbUpzRmZKd3poQWVBQ291bXk1X3JNLWxSQSJ9.eyJuYmYiOjE2MTUzODg2ODEsImV4cCI6MTYxNTM5MjI4MSwiaXNzIjoiaHR0cHM6Ly9hdXRoLnRydWVsYXllci",
    "expires_in": 3600,
    "token_type": "Bearer",
    "refresh_token": "B921073229D5B520F47EC1D8970982D77C8BAA06B818C357D281",
    "scope": "info accounts"
}

This access token will allow you to verify the user's account and will be valid for one hour.

Verify the user

Make a POST /v1/verification call and additionally include:
- access_token: The access token value obtained from the response of exchanging the code

curl -X POST -H "Authorization: Bearer ${access_token}" \
    -H "Content-Type: application/json" \
    "https://verification.truelayer-sandbox.com/v1/verification/" \
    -d '{"name": "John Doe"}'

The "verified": true field in the response validates that the given account
matches the provided account holder name John Doe. You'll also find further details of the user's account. You'll need the iban field as the beneficiary IBAN when creating a payout.

{
  "verified": true,
  "account_holder_name": "John Doe",
  "match_score": 100,
  "report": [
    {
      "verifiable": true,
      "currency": "GBP",
      "provider_id": "mock",
      "account_type": "CURRENT",
      "account_holders": [
        {
          "name": "John Doe",
          "verified": true,
          "match_score": 100
        }
      ],
      "display_name": "TRANSACTION ACCOUNT 1",
      "iban": "GB08CLRB04066800003435",
      "swift_bic": "CPBKGB00",
      "account_number": "10000000",
      "sort_code": "01-21-31"
    },
    ...
  ]
}

Once you have verified the account, you can make a payout to the account. To do so:

  1. Get an access token to use PayDirect.
  2. Make a payout to the user's account.

Get PayDirect access token

You must provide a valid Bearer access token when calling the PayDirect API. It will be used to
authenticate your application before initiating the payout.

Use your client_id and client_secret to generate an access token. You'll have to include these fields
within the Bearer token header in future requests. We have a Generate PayDirect Token Insomnia
request for this.

curl -X POST \
    -d grant_type=client_credentials \
    -d client_id=${client_id} \
    -d client_secret=${client_secret} \
    -d scope=paydirect \
    https://auth.truelayer-sandbox.com/connect/token

You'll get a response like the following:

{
  "access_token": "JWT-ACCESS-TOKEN-HERE",
  "expires_in": 3600,
  "token_type": "Bearer",
  "scope": "paydirect payments"
}

Make an initial payout

We can then use the POST /v1/withdrawals endpoint in the PayDirect API to initiate a payout to the
user's account using the iban as the beneficiary IBAN. Learn more about open-loop withdrawals.

curl -X POST \
     -H "Authorization: Bearer ${access_token}" \
     -H "X-TL-Signature: ${signature}" \
     --data '{
        "transaction_id": "<UUID>"
        "beneficiary_name": "John Doe",
        "beneficiary_iban": "GB08CLRB04066800003435",
        "beneficiary_reference": "Payouts Quickstart",
        "currency": "GBP",
        "amount_in_minor": 10,
        "context_code": "withdrawal"
}' \
https://paydirect.truelayer-sandbox.com/v1/withdrawals

We can query the status of the withdrawal using GET v1/withdrawals/<transaction_id>.

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": "4cee2e78-4213-4a83-8ef7-50b5207e5eaf",
    "authorised_at": "2021-09-09T16:54:18.051837Z",
    "submitted_at": "2021-09-09T16:54:18.431168Z",
    "settled_at": "2021-09-09T16:54:20.117Z",
    "rejected_at": null,
    "failed_at": null,
    "beneficiary_name": "John Doe",
    "beneficiary_iban": "GB08CLRB04066800003435",
    "beneficiary_reference": "Payouts Quickstart",
    "amount_in_minor": 1,
    "currency": "GBP",
    "status": "settled",
    "context_code": "withdrawal"
  }
}

The initial payout process is complete when the status reaches settled.

Payout to a verified account

Once you've verified a user account, you can make payouts to it without verifying it again. If the user wants to use a different bank account, you'll need to follow the steps to make an initial verified payout again.

If you've already verified a user's bank account and stored their details in your system, you can get an access token and initiate new payouts using their IBAN. We call this an x-loop withdrawal.

curl -X POST \
     -H "Authorization: Bearer ${access_token}" \
     -H "X-TL-Signature: ${signature}" \
     --data '{
        "transaction_id": "<UUID>"
        "beneficiary_name": "John Doe",
        "beneficiary_iban": "GB08CLRB04066800003435",
        "beneficiary_reference": "Payouts Quickstart",
        "currency": "GBP",
        "amount_in_minor": 10,
        "context_code": "withdrawal"
}' \
https://paydirect.truelayer-sandbox.com/v1/withdrawals

We can query the status using the GET v1/withdrawals/<transaction_id> endpoint.

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": "4cee2e78-4213-4a83-8ef7-50b5207e5eaf",
    "authorised_at": "2021-09-09T16:54:18.051837Z",
    "submitted_at": "2021-09-09T16:54:18.431168Z",
    "settled_at": "2021-09-09T16:54:20.117Z",
    "rejected_at": null,
    "failed_at": null,
    "beneficiary_name": "John Doe",
    "beneficiary_iban": "GB08CLRB04066800003435",
    "beneficiary_reference": "Payouts Quickstart",
    "amount_in_minor": 1,
    "currency": "GBP",
    "status": "settled",
    "context_code": "withdrawal"
  }
}

Go live

Before you go live, check out the guides on account verification and PayDirect for more information.


Did this page help you?