Verified payouts [PayDirect]

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

📘

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.

You can verify and pay out to an account in TrueLayer's sandbox environment using the Verification API and PayDirect.

Follow this guide to test a verified payout in the sandbox environment.

Set up configurations in Console

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

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

The Data API is enabled for all customers 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 and PayDirect APIs. Follow our guide to set up Insomnia with our Verification API and PayDirect API collections. They contain sample requests so that you can start using the APIs straight away.

📘

Signing your requests

View our guide on request signing to learn how to sign POST requests to PayDirect API endpoints.

Make an initial payout to an account

First, you need to verify a user account. Then you can make a payout to that account.

Start by authenticating:

  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 a user account, you need to generate a test authentication link. This link creates an authentication page where the user can authenticate with their bank. The authentication page also provides your application with permissions to view relevant information about your user's bank account.

To create an auth link, go to 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.

  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 these example credentials:

    • Username: john
    • Password: doe
  6. You will receive a code. Copy it to your clipboard, or store it.

Exchange the code for an access token

Using the code from the previous step, go to the Exchange Code request in the
Insomnia collection. This will call the Authentication API, getting you an access token which
allows you to see details of the user's account.

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. It will be valid for one hour.

Verify the user's account

Make a POST /v1/verification call. 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 more details about the user's account. You'll need their IBAN (in the iban field) when creating a payout, to include in the beneficiary_iban field.

{
  "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 a PayDirect access token

You must provide a valid 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. 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 this:

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

Make an initial payout

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 this:

{
  "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.

Pay out to a verified account

Once you've verified a user account, you can make payouts to the same account 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.

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 open-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

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 this:

{
  "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, have a look at our guides on account verification and PayDirect.