How to implement the TrueLayer Payments API within your UI
Background image

How to implement the TrueLayer Payments API within your UI

TrueLayer is known for the simplicity and flexibility of its APIs. We want to make it as easy as possible for customers to build a streamlined integration from day one.

In this guide, we cover the perfect integration process for our Payments API. We’ve found that when customers follow these steps, they get fewer errors, and customer conversion rates are higher.

Before we get started… 👇

Here are a few things you should know:
  • The TrueLayer APIs can’t be accessed from the front end of your application because of our CORS policy, so you should always implement our functionality on the server-side of your application. We’ve done this to protect you, as this would require you to expose your secrets to the world. 😶
  • Our authentication tokens aren’t unique to the payment being made, so you can use these until they expire, for as many payments and queries as you need.
  • Our providers’ endpoint lets you build out your own payments screen so that you can integrate with your existing designs — this is what we’ll cover in this article, but if you’d like a fast integration, then let us do the heavy lifting 💪with our payments dialog.

Important concepts 👀

  • The provider selection screen that you build should be populated by the providers' endpoint of the Payments API. You can display the assets we send you (i.e., Bank Logos), or you can display the bank’s name. You can then send us the provider ID when you create the payment to go straight to the bank.
  • The redirect URL that you send us with each payment needs to be added to the console, but it can’t have any parameters or state passed with it, we will return the user to this URL with a parameter “payment_id”.
  • Client IDs and Secrets are unique to the environment you are using. Our API has a sandbox and a production environment that you have access to; in the console, you can progress to the live area by clicking the ‘go live’ button in the sandbox area.
  • The beneficiary refers to the merchant accepting the payment; for instance, the beneficiary account number is the account to which you are sending the funds.
  • The remitter refers to your user making the payment; for instance, the remitter account number is the account from which you are taking the funds.

Key steps for creating a payment 👣

  1. Access our providers’ endpoint to get a list of banks and their logos to help your users identify their bank in your selection screen;
  2. Retrieve an access token from our authentication server;
  3. Use the provider ID from the bank selected by the user to create a payment;
  4. Redirect the user to the link returned in the “auth_link” parameter after creating a payment;
  5. Once the user has authorised the payment, they are sent to your redirect via TrueLayer with their payment ID in a parameter;
  6. Use the payment ID to query the payment state;
  7. When you see the state “Executed”, your payment is on its way! ✅ 🏁

Populating your provider selection screen

The first step is to create an interface that allows your user to tell you which bank they want to pay with. Luckily, TrueLayer provides you with everything you need to build this.If you’re using the live environment, you can find a list of providers at this endpoint: you’re using the sandbox environment, you can find a list of providers at this endpoint: endpoints return an array of providers (this is what we call each bank). Here is an example of a provider object:
  • The id variable returns you the provider ID to use when creating a payment;
  • The icon variable returns you a link to the icon of the bank;
  • The displayable_name variable returns you a name that you can use to identify the bank with the user, e.g. ob-barclays will return a displayable name of “Barclays”;
  • The main_bg_color variable returns you the hexcode of a colour that can be used to style your UI in the colour of the bank;
  • The supports_app_to_app variable returns a boolean indicating whether or not the returned link will redirect your user to an app or whether it will open a browser interface;
  • The divisions array variable returns you a list of available divisions for making a payment with e.g. Retail, Business or Corporate.
The great thing about using your own UI is you can store your user’s choice and give them a faster experience the next time they go to make a payment ⏩We recommend you query this endpoint every time a user wants to make a payment as the returned list will change depending on which banks are currently live. When a bank is misbehaving we remove them from this list so that your users don’t get redirected to a bank that isn’t operating correctly.

Authenticating to our API 🔐

To protect our API we have an authentication server that you will need to use to get an access token.This server is used for all our products. If you’ve already integrated into our Data API, you just need to update the scopes you’re requesting for your access token.Unlike our Data API, the access token doesn’t represent a user, it represents you — so you can use this for as many payments as you can fit into the time frame that the access token is valid for!There are 4 things you need to tell us to get a valid token:
  • The grant type — the answer to this is “client_credentials”;
  • Your client ID that can be found in the console;
  • Your client Secret that can be found in the console;
  • The scope — the answer to this is “payments”.
If you’re using the sandbox then you can obtain your token from this link: you’re using the live environment then you can obtain your token from this link: is an example request:
After you’ve posted this, you will receive a response containing your access token and the time that it will be valid for:
Now store your token and you can use it for the next 60 minutes to create and query payments.

Creating a Payment 💸

The next step is to create a payment. At this stage, your user has told you what bank they want to pay from and you’ve obtained your access token.The endpoint we are using in the sandbox is here: endpoint we are using in the live environment is here: the header of the POST request you will need to include the following:
  • A valid access_token (you retrieved one in the previous step)
In the body of the POST request you will need to include the following:
  • The amount as an integer in pennies, e.g. 100 would be £1;
  • The currency as a string, right now we only accept “GBP”;
  • A remitter_reference that will appear in the bank statement of your user. See allowed characters here;
  • The beneficiary_name as specified on the end account;
  • The beneficiary_sort_code as a string, e.g. a sort code of 00–04–04 would be “000404”;
  • The beneficiary_account_number as a string;
  • A beneficiary_reference that will appear in your bank statement and should be used for reconciliation. See allowed characters here;
  • The remitter_provider_id that you captured in the first step;
  • Your redirect_uri as specified in the console.
Optionally, you can include the following fields in the body of your POST request if you want to mandate which account with the bank the payment comes from (many of our clients do this for AML reasons):
  • The remitter_sort_code as a string, e.g. a sort code of 00–04–04 would be “000404”
  • The remitter_account_number as a string
Here is an example request:
After you’ve posted this request, if successful, you will receive a response containing all the details needed for the next stage:
You should store the simp_id as you can use this to query the state of your payment.At this stage, you should be redirecting the user to the URI found in the auth_uri variable. This will launch a TrueLayer page that will instantly open the bank app or website of your user.Once the user has finished up with the bank, they will be redirected back to the redirect_uri that you specified in the body of the POST request with a payment_id variable that you can use to query the status of the payment.If you are implementing the Payments API inside a mobile app, we recommend you use a universal link as your redirect_uri — this gives the most seamless App2App integration, and the user won’t need to reopen your app. Instead, it will open automatically after making the payment.

Querying the status of a payment ❗️❓

After the user has returned to your application, you should query the state of the payment to see if it was successful.The endpoint we are using in the sandbox environment is here: endpoint we are using in the live environment is here: the endpoint, you are sending the GET request to include the payment ID in the URL and your access token in the header.Here is an example request:
The response to the GET request will give you all of the information about the payment specified, including its current state.
The status variable tells you what stage your payment is at and whether it was successful or not.
The states that you could receive are as follows:
  • New — this means the payment request was created but the user hasn’t yet followed through with their bank.
  • Cancelled — this means the user clicked a cancel button in the payment flow at some point and has chosen not to proceed with the payment.
  • Authorised — this means the user authenticated and approved the payment and was redirected back to TrueLayer but the payment is yet to be submitted to the bank.
  • Failed — this means the bank had an error that prevented the payment from being made, this error may have been seen by the user or it may have occurred when TrueLayer attempted to submit the payment.
  • Submitted — this means that TrueLayer has submitted the payment to the bank and the bank will attempt to execute in their next faster payments batch.
  • Rejected — this means the bank rejected the payment after the user authorised it. This is normally because of a lack of funds but can sometimes also be because of risk policies at the bank.
  • Executed — this means the payment has successfully been executed over the faster payments network and the money has the left the user’s bank account.
The following states are final:
  • Cancelled
  • Failed
  • Rejected
  • Executed
You should poll this endpoint for status until you see a final state.
After this, you’re done! 💪Ready to start building with TrueLayer? Head to our console to start testing our APIs, or contact us to learn more.

Written by

Profile Photo

Product lead
Multi-talented George is an entrepenuer, product manager & orchestra conductor. He joined TrueLayer in 2019, and soon led us through launching and scaling up our first open banking payments product.

Recent blog posts