Migration guide: Payments v1 to v3 with merchant accounts

Everything you need to migrate from Payments v1 to the Payments API v3.

Scope of this document

Welcome to the TrueLayer v3 Payments migration guide.

This document provides information on the TrueLayer Payments v3 APIs and the migration process from the Payments v1 APIs to Payments v3 APIs.

🚧

Who this guide is for

This guide is for payments integrations that use a TrueLayer merchant account:

  • Pay-ins (deposits) into the merchant account using Payments v1 Legacy APIs
  • Payouts (withdrawals or refunds) from the merchant account with Payouts v1 Legacy APIs

Payments API v3 is the latest version of the TrueLayer Payments APIs and is a single interface to access all of TrueLayer's payments products in all supported geographies.

This includes:

In order to take advantage of these new features and ensure the best possible experience with our product, we strongly recommend that all users upgrade to this new version as soon as possible.

However, we understand that migrating to a new version can sometimes be a challenging process. That's why we've put together this guide to help you make the transition as smooth as possible.

We hope this guide will help you navigate the migration process and take full advantage of all the new features and improvements in the new version. If you have any questions or encounter any issues along the way, don't hesitate to reach out to our support team for assistance.

To summarise, the three benefits of v3 migrations are:

  • Out-of-the-box solutions (Mobile SDKs, hosted payment page, backend libraries) to support easier integration.
  • The same integration for all future coverage expansion and features for the next 3-5 years.
  • Building user interfaces to meet the differing requirements of European providers is complex. If you are interested in new geographies, we’ll reduce the barrier to entering these markets by extending the capabilities of our TrueLayer UI components.

Payments v3 APIs: introduction

🚧

Signing requests

Signing requests

It is now mandatory to sign all POST API requests, including both pay-ins and payouts. You must also include certain user data within payment creation requests.
Learn more about signing requests and get links to TrueLayer signing requests libraries.

Merchant account ID

You can find your merchant_account_id in Console > Payments > Merchant Account or via the /merchant-accounts endpoint.

Learn more about merchant accounts.

Requirements for v3

When migrating from a previous version, it’s important to acknowledge new requirements and concepts introduced in Payments v3.

  • It is now mandatory to sign all POST API requests, including both pay-ins and payouts.
  • It is required to include additional user information within payment creation requests.
  • Pay-in creation and authorisation are now two distinct concepts and are handled in two separate steps.

Each of those concepts is explained here in more detail.

Signing requests and validation of the received webhooks signature

All Payments API v3 requests must be signed (including both pay-ins/deposits and payouts).

Payments request signing with v3 is explained in more detail in our docs, for both pay-ins and payouts.

See our guide on how to create certificates, upload them to Console, and use backend signing libraries to help out with the signing process. We strongly recommend using our signing libraries for easier integration.

We also provide backend signing libraries to verify the Tl-Signature of received webhooks. Check our docs about this.

Additional ‘User’ data for pay-in and payout requests

As a regulated Financial/Payment Institution we have a regulatory requirement to screen all in/out transactions from/to the merchant accounts against sanctions lists.

The requirement applies to all transactions by clients who are not fully regulated and authorised financial services in the UK or EU.

TrueLayer conducts sanction and AML screening on all transactions to and from your merchant account. We double-check transactions made by end-users whose name matches an individual on a sanction list.

If a transaction is flagged by sanction and/or AML screening we will issue a Request for Information (RFI) to collect additional information required for us to investigate.

To reduce the number of RFIs raised due to sanctions investigations, the end user's date of birth and address need to be included in the API request.

Pay-In: the User object

{
  "user":  
    {  
      "id": "f61c0ec7-0f83-414e-8e5f-aace86e0ed35",  
      "name": "Jonathan Sandbridge",  
      "email": "[email protected]",  
      "phone": "+44123456789",  
      "date_of_birth": "1992-11-28",
      "address":  
        {  
          "address_line1": "1, Hardwick Street",  
          "address_line2": "Floor 1",  
          "city": "London",  
          "state": "London",  
          "zip": "EC1R 4RB",  
          "country_code": "GB"  
        }  
    }  
}

For each payment, you will be required to pass the following user information in the payment request:

Hash parameterDescription
Unique User IDRequired.

A unique identifier for the user. The field is optional. When left empty, represents a new user and a value will be generated by TrueLayer and returned in the response.

This should uniquely identify the user (must be in UUID format).
NameRequired for non-regulated customers.
Email addressRequired for non-regulated customers.
Phone numberRequired for non-regulated customers.
Date of birthRequired for non-regulated customers.
Physical addressRequired for non-regulated customers.

📘

Details of the end user who is making the payment are required. Whether or not all of these fields are required depends on the regulatory status of the customer initiating the payment. For detailed requirements, please confirm requirements with your Sales contact.

Integration options

TrueLayer offers different integration options for our Payments API v3 to suit your needs.

With Payments v3 pay-ins (deposits made into the merchant account), once the payment is created from the backend, there is a following step that consists in taking the end user to authorise the payment.

Basically, the payment creation is separated from the payment authorisation (that involves user bank selection and payment confirmation).

Coming from a v1 Payments integration, you might be leveraging the TrueLayer payment dialog pages.

Payment v3 also comes with desktop and mobile UX/UI components that can be used out of the box to implement the pay-in user flow for every supported provider and country.

Therefore, for payment authorisation steps, in general, we usually recommend using our embedded payment page (EPP) or the hosted payment page (HPP) as both will reduce the time and resources required since it is optimised for the best user experience.

Hosted Payment Page

Image showing what the HPP interface looks like. There are two screenshots in the image, one showing the bank selection screen and the other showing the payment confirmation screen.

Image showing what the HPP interface looks like. There are two screenshots in the image, one showing the bank selection screen and the other showing the payment confirmation screen.

Learn more about the hosted payment page.

  • TrueLayer’s localised hosted browser solution for both mobile and desktop which can be used for the bank selection and payment confirmation page (including QR code handoff option for desktop to mobile app flow).
  • This is built to handle the nuance of bank and country requirements across UK & Europe for you. This will increase the speed and efficiency of your country rollout if you are looking into expanding open banking payments in Europe. For German banks that have embedded flow approval processes, the HPP, EPP or SDK must be used if you wish to have the coverage of these banks (due to European regulations).
  • This can be configured to match the look and feel of your own website or app environment so that the customer journey reflects your brand colours.

Embedded Payment Page (EPP)

An example of the

An example of how the EPP can be displayed as either an overlay or an in-line element.

Learn more about the embedded payment page.

  • The embedded payment page enables you to quickly and simply add instant bank payments to your website, with a prebuilt user interface that speeds up the integration process.
  • The EPP acts as a modal in your web page environment. It offers enhanced customization functionality, QR code authentication and built in localisation covering local languages and authentication flows for a range of European countries.
  • This is built to handle the nuance of bank and country requirements across UK & Europe for you. This will increase the speed and efficiency of your country rollout if you are looking into expanding Open Banking payment solutions in Europe. For German banks that have embedded flow approval processes, the HPP, EPP or SDK must be used if you wish to have the coverage of these banks (due to European regulations).

Mobile SDKs for Android, iOS and React Native

1920

Image of what the native screens look like on an Android device. There are two screenshots in the image, one shows the bank selection screen and the other shows the payment confirmation screen.

Learn more about TrueLayer's mobile SDKs.

  • TrueLayer’s mobile SDK can be used to embed the bank selection and payment confirmation pages into your mobile app.
  • This can be configured to match the look and feel of your own mobile environment.

Direct API integration and keeping your custom white labelled frontend

In case you’ve done a completely white labelled frontend, you can still handle all the payment authorisation using TrueLayer APIs from the backend and keep your customised flow.

The next section in this guide will cover this case.

Please note that, as mentioned above, if you are going to operate eventually outside of the UK, you could have to handle more complex flows coming from additional bank-specific requirements (like banks with embedded flows). In this case we strongly recommend adopting our hosted payment pages or embedded payment pages. These will automatically handle all additional bank flow requirements out of the box.

TrueLayer Console and Payments V3

Console is our back office platform where you can find all the necessary credentials to start using our APIs in both sandbox and live environments. In Console, you can also check payments their statuses and run reports.

The page you see in Console before you upload your signing key.

The page you see in Console before you upload your signing key.

When you open an app in Console, the tab menu includes sub-sections for:

  • Payments, which displays a table of pay-ins to and payouts from your merchant account, and the ability to issue refunds.
  • Settings, such as webhook and redirect URIs, and your client ID and secret.
  • Merchant Account information, including available and historical balances.
  • UI customisation options for the HPP, EPP, and more.
The **Payments** view, where you can see a table of payments and issue refunds. The tab menu also displays the other options available to you.

The Payments view, where you can see a table of payments and issue refunds. The tab menu also displays the other options available to you.

Documentation quickstart guides and links

Get started with Payments v3

Try out the API endpoints with our Insomnia collection and use our Insomnia plugin for quickly signing requests. Follow the instructions in the page for how to setup Insomnia, import the TrueLayer signing plug-in and import the v3 collection.


Migrating from Payments v1 to v3

Introduction

With the Payments v1 APIs, you used TrueLayer payment dialogs to handle the bank selection screens, or pass the bank details (provider_id and sort_code-account_number) into the payment request calls.

With v3 this will still be possible. You can completely reuse your existing UX/UI flow, using a Direct API integration, or use one of TrueLayer UI and SDK components.

Payment token creation

Like with Payments v3 APIs, you will need to generate a Bearer access_token. This will be used to get info from your merchant account and to initiate API calls. Use your TrueLayer client_id and client_secret (found in your TrueLayer Console) to request an access_token from our auth server.

The /connect/token endpoint is the same. The scope must now be payments, which is used for both pay-ins (deposits) and payouts (withdrawals and refunds).

As with previous API versions, the generated access_token lasts for 1 hour and once expired, you need to generate a new one.

Example:

EnvironmentEndpoint
Livehttps\://auth.truelayer.com/connect/token
Sandboxhttps://auth.truelayer-sandbox.com/connect/token
curl -X POST  
    -d grant_type=client_credentials  
    -d client_id=${client_id}  
    -d client_secret=${client_secret}  
    -d scope=payments
https://auth.truelayer-sandbox.com/connect/token
{  
    "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjE0NTk4OUIwNTdDOUMzMzg0MDc4MDBBOEJBNkNCOUZFQjMzRTk1MTBSUzI1NiIsInR5cCI6ImF0K2p3dCIsIng1dCI6IkZGbUpzRmZKd3poQWVBQ291bXk1X3JNLWxSQSJ9.eyJuYmYiOjE2NjAyNDU0NzEsImV4cCI6MTY2MDI0OTA3MSwiaXNzIjoiaHR0cHM6Ly9hdXRoLnRydWVsYXllci1zYW5kYm94LmNvbSIsImF1ZCI6InBheW1lbnRzX2FwaSIsImNsaWVudF9pZCI6InNhbmRib3gtZGFyeWx0ZXN0LTc2YjkwOCIsImp0aSI6IkE0MTNERDhFOENENTJGQUQ5MjcwRTU3QjJCN0RFNjhFIiwiaWF0IjoxNjYwMjQ1NDcxLCJzY29wZSI6WyJwYXltZW50cyJdfQ.hV5Nuqi-X9PqNDOyVftnWZzHhuBIetsjM1zeK-64ZSJ9aTqPdwhqVGiM4zTqLEx0ZfT34MbUfY98cFu00X3SbgS4fV7_Mu2jV_5ofrLdlb_KoIFo82ZG5Y4SNd19vFI5sEIkYIL3KtYnvnjUwP4UZvxgl0siTg1K0kRqws8SqfeOwStgaHsBfYcTUi_w3Z5DSZTspR_G_FixOHGjTPFY48GPACO-wyfH5JZn_uMpARRUam-sadukUpe8yjxFrg1zQ8mqXBhuuBbk8PoG4DCkk5tY-lTjFx92P1NuElMP1RzvIJ_-1qDhdtnNJROLm09_D-l4YX1VIaxL29Wv9kudqQ",  
    "expires_in": 3600,  
    "scope": "payments",  
    "token_type": "Bearer"  
}

Merchant account

Docs

A merchant account is a bank account managed by TrueLayer on your behalf. As seen in the diagram above, the merchant account sits in the middle and enables the following flow of funds:

  • End-user payments from their bank account to the merchant account (Deposits)
  • Payments from the merchant account to the end user bank account (Payouts)
  • Funding of the merchant account from your corporate business account
  • Sweeping of funds from the merchant account to your corporate business account

Within the TrueLayer Console you will find the details to this bank account, including the merchant account holder name, account number, sort code, and IBAN. All payments coming into and out of this account will also be reflected in the TrueLayer Console.

Get Balances

Docs | API reference

Payments v3 endpoint | https://api.truelayer.com/merchant-accounts

The v3 response now includes more information, including sort_code and account_number (for UK currency) and the merchant account id, which is used to identify the merchant account to where closed-loop payouts are made, or where payouts are being sent from.

{  
    "items":  
    [  
        {  
            "id": "68e11e56-1062-4529-8cc7-e5c291948db7",  
            "currency": "GBP",  
            "account_identifiers":  
            [  
                {  
                    "type": "sort_code_account_number",  
                    "sort_code": "040668",  
                    "account_number": "00001719"  
                },  
                {  
                    "type": "iban",  
                    "iban": "GB71CLRB04066800001719"  
                }  
            ],  
            "available_balance_in_minor": 4039,  
            "current_balance_in_minor": 4039,  
            "account_holder_name": "Federico Casali"  
        },  
        {  
            "id": "dc75c4c0-85c9-489d-8394-09854f651d4e",  
            "currency": "EUR",  
            "account_identifiers":  
            [  
                {  
                    "type": "iban",  
                    "iban": "FR7630006000011234567890189"  
                }  
            ],  
            "available_balance_in_minor": 9835,  
            "current_balance_in_minor": 9835,  
            "account_holder_name": "Federico Casali"  
        }  
    ]  
}

Get Transactions

Docs | API reference

Payments v3 endpoint | https://api.truelayer.com/merchant-accounts

Set up Sweeping

Docs | API reference

To set up or change automated VRP sweeping settings, the endpoint is different, and the merchant account ID also needs to be passed as part of the endpoint URI.

Payments v3 endpoint | https://api.truelayer.com/merchant-accounts/<merchant_account_id>/sweeping

Pay-ins (Deposits)

Create deposits into the merchant account.

Docs | API reference

Step 1: Pay-In creation call

The Payments API call needs to be initiated from the backend, including the Bearer access_token we got in the previous step.

📘

Request signing

Learn more about request signing for Payments v3.

You can find your merchant_account_id in Console > Payments > Merchant Account or via GET /merchant-accounts

Using v1 APIs, you created a pay-in into your merchant account by making an API call request to the https://pay-api.truelayer.com/single-immediate-payments endpoint.


The two examples below show how to convert v1 payments creation calls to v3. There are two examples, one where the remitter information isn't passed, and one where it is passed.

See below an example of a payment creation call with v1 and its corresponding v3 version:

Here is an example where remitter data is also being passed in the request, and the corresponding v3 version:

This is an example of a Payments v3 closed-loop payout request to https://api.truelayer.com/payouts:

{  
    "merchant_account_id": "01829515-3525-4812-a6c0-6d9e195c947e",  
    "amount_in_minor": 1000,  
    "currency": "GBP",  
    "beneficiary":  
    {  
        "type": "payment_source",  
        "user_id": "4d9af4be-f75b-4ca7-be9b-b842bf7237c1",  
        "payment_source_id": "1c928e0e-6dc9-497c-8154-83dce43b2377",  
        "reference": "Payout0001"  
    },  
    "metadata":  
    {  
        "brand": "optional metadata"  
    },  
}

In this request:

  • beneficiary.payment_source_id is returned from the pay-in webhook (or GET status) once the payment has been settled.
  • beneficiary.user_id is the same user.id used for pay-in creation, and then also returned from the pay-in webhook (or GET status) once the payment has been settled.

This is an example of the Payments v3 response for this request:

{  
        "id": "5016c85d-de28-406d-9866-0a3ed85af3b1"  
}

See our Payments v3 closed-loop payout documentation for more details about Payments v3 closed-loop payouts.

Open-loop payout

Docs | API reference

ProductEndpoint
Payouts v1https://payouts.truelayer-sandbox.com/v1/payouts
Payments v3https://api.truelayer.com/payouts

With v3 payouts, you can still also make payouts to any supported bank account by using the beneficiary type external_account and submitting the relevant account details.

Note: With the Payouts API v1, you passed the beneficiary name and IBAN in the request, also for UK banks. With v3, if you are in the UK, you can now use sort_code and account_number as beneficiary account_identifier data.

Of course, you can still be using IBAN if you wish: set the account_identifier.type to iban, and include account_identifier.iban .

v1 payoutPayments v3 open-loop payout
beneficiary_namebeneficiary.account_holder_name
beneficiary_ibanEither:

beneficiary.account_identifier.sort_code
and
beneficiary.account_identifier.account_number

or

beneficiary.account_identifier.iban
beneficiary_referencebeneficiary.reference
transaction_idNo longer required
Sender merchant account automatically retrieved based on the currency.A merchant_account_id, relative to the ID of the Merchant Account from where the payment will come from, has to be passed in the request.

🚧

User details

As TrueLayer conducts sanction and AML screening on all transactions to and from your merchant account, and to reduce the number of RFIs raised due to sanctions investigation, the additional fields: address and date_of_birth must be included in the API request.

This is an example of a Payments v3 open-loop payout request to https://api.truelayer.com/payouts:

{  
    "merchant_account_id": "c6ba13f2-35ef-4556-a99e-a6afd6275044",  
    "amount_in_minor": 100,  
    "currency": "GBP",  
    "beneficiary":  
    {  
        "type": "external_account",  
        "reference": "Withdrawal",  
        "account_holder_name": "John Smith",  
        "account_identifier":  
        {  
            "type": "sort_code_account_number",  
            "sort_code": "<sort code>",  
            "account_number": "<account number>"  
        },  
        "date_of_birth": "1992-08-03",  
        "address":  
        {  
            "address_line1": "1 Hardwick St",  
            "address_line2": "Clerkenwell",  
            "city": "London",  
            "state": "London",  
            "zip": "EC1R 4RB",  
            "country_code": "GB"  
        }  
    },  
    "metadata":  
    {  
        "prop1": "value1",  
        "prop2": "value2"  
    }  
}

This is an example of the response to a successful request:

{  
        "id": "f5a6c87e-446a-4dcc-a91e-a74e3e4e0875"  
}

Refund

If you need to issue refunds, with Payments v3 a dedicated /payments/{id}/refunds endpoint is available to specifically make it easier to handle refunds.

Refunds with the Refunds API are basically closed-loop payouts. The differences are:

  • The maximum amount refundable is the pay-in amount being refunded.
  • The pay-in payment_id is the only piece of information required for the Create a refund API call.
  • It is possible to issue multiple refunds for the same pay-in.

Learn more about refunds with the Payments API v3.

Visual summary of Payments v1 to v3 Closed-Loop + Refunds API and v3 webhook.

 Consume Payouts webhooks and payment statuses

StatusDescriptionNotification method
pendingThe payout has been created with TrueLayer's API but it has not yet been authorized and sent to the payment scheme for execution.Status only via
/GET /payouts/{payment_id}
authorizedThe payout has been created via TrueLayer's API and has been sent to the payment scheme for execution.Status only via
/GET /payouts/{payment_id}
payout_executedThe payout was executed. The payout amount has been deducted from your merchant account.Status via
/GET /payouts/{payment_id}

Webhook sent to your endpoint
payout_failedThe payout failed. The payout amount has not been deducted from your Merchant Account.Status via
/GET /payouts/{payment_id}

Webhook sent to your endpoint

Webhook examples (Payout)

🚧

We recommend developers to use our signing libraries to verify the Tl-Signature of the received webhooks.

You must set your Webhook URI in Console to recieve webhook notifications.

This block contains examples of the webhooks you receive for executed and failed payouts.

{  
    "type": "payout_executed",  
    "event_id": "1b712c55-6bc4-487c-8a5b-2107623fe3bf",  
    "event_version": 1,  
    "payout_id": "5016c85d-de28-406d-9866-0a3ed85af3b1",  
    "executed_at": "2022-09-14T16:39:50.593Z",  
    "beneficiary":  
    {  
        "type": "payment_source",  
        "user_id": "4d9af4be-f75b-4ca7-be9b-b842bf7237c1",  
        "payment_source_id": "1c928e0e-6dc9-497c-8154-83dce43b2377"  
    },  
    "metadata":  
    {  
        "brand": "TL Casino"  
    }  
}
{  
    "type": "payout_failed",  
    "event_id": "f8a144dc-a550-4681-844b-4de231ec3764",  
    "event_version": 1,  
    "payout_id": "f8a144dc-a550-4681-844b-4de231ec3764",  
    "failed_at": "2022-09-14T16:41:21.006718283Z",  
    "failure_reason": "insufficient_funds",  
    "beneficiary":  
    {  
        "type": "payment_source",  
        "user_id": "4d9af4be-f75b-4ca7-be9b-b842bf7237c1",  
        "payment_source_id": "1c928e0e-6dc9-497c-8154-83dce43b2377"  
    },  
    "metadata":  
    {  
        "brand": "TL Casino"  
    }  
}

Learn how to migrate from our legacy APIs to the Payments API v3.