Android SDK

Learn how to use the Android version of our mobile SDK to quickly integrate our Payments product into your app.

With the TrueLayer SDK for Android, you can quickly add open banking payments to your app. Our Android SDK integrates with TrueLayer's Payments API, making it simple to get up and running.

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

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.

The Android SDK presents native screens that allows your users to select their bank and consent to the payment. Then, it redirects them to their banking app or website to authorise the payment. It also handles network requests and errors and gives you some options to customise the user interface.

Compatibility

The SDK is designed to work with Android 7.0 (API level 24) and above. It is currently optimised for the UK, Ireland, Spain, the Netherlands and Lithuania. Beta testers can also use the Android SDK for banks in Portugal. The user interface can be displayed in English, Spanish, French, German, Dutch, Portuguese and Lithuanian.

Payment journey

  1. The user selects Pay By Bank.
  2. Your app creates creates a payment on the backend side.
  3. Your backend integration creates a payment and gets a payment resource back.
  4. Your app gets the payment_id and resource_token back and initialises the SDK.
  5. Your user selects and confirms their bank on the screen of the mobile SDK.
  6. The mobile SDK redirects your user to their bank's website or app.
  7. Your user authorises the payment in their bank's website or app.
  8. Once the authorisation is complete, the bank redirects the user to your redirect_url.
Image containing a diagram that shows the payment journey with mobile SDK integration.Image containing a diagram that shows the payment journey with mobile SDK integration.

Image containing a diagram that shows the payment journey with mobile SDK integration.

Before you begin

Before you can use the SDK, you have to:

  1. Create a payment using the Payments API v3.
  2. Register a redirect_uri from our developer console. Use at the end of the payment journey to redirect back to your website or application.

Step 1: Install the SDK

Before you add the SDK to our project, make sure that your build.gradle configuration is configured to support minSdk 24 or higher as well the packagingOptions below:

android {
    defaultConfig {
        applicationId "com.example.myapp"
        minSdk 24 // Sdk 24 or higher supported
    }


    packagingOptions {
        resources {
            pickFirsts += ['META-INF/LICENSE-MIT']
        }
    }
}

To add the SDK to your project, simply include TrueLayer Payments SDK to your dependencies. The SDK is hosted on the TrueLayer Artifactory server, so follow the instructions below to add it to your project repository list.

// Add to your projects `build.gradle`.
implementation "com.truelayer.payments:ui:1.0.0-beta04"

In your main Gradle file (root project settings.gradle) you need to add the TrueLayer Artifactory. You have two options for how to do this:

Option 1: Use local.properties file

// below is an example of `dependencyResolutionManagement` block that you may
// have in your settings.gradle file
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    
    // this is the TrueLayer specific part that needs to be added
    // in order to read values from `local.properties` file
    def localProperties = new Properties()
    try {
        localProperties.load(new FileInputStream("local.properties"))
    } catch(Exception e) {
        // local properties only required to pull artifacts from
        // truelayer.jfrog.io. At the moment this will only be done
        // on developers machines but not on CI.
        println("File local.properties is not available. Fetching from truelayer.jfrog.io" +
                " will not be possible.")
    }
   
    repositories {
        // this is the TrueLayer specific part that needs to be added
        // to instruct gradle where to fetch TrueLayer libraries from 
        maven {
            url 'https://truelayer.jfrog.io/artifactory/maven-public'
            credentials {
                username "${localProperties['artifactory.username']}"
                password "${localProperties['artifactory.apikey']}"
            }
            content {
                // this repository *only* contains artifacts with group "com.truelayer"
                includeGroupByRegex "com\\.truelayer.*"
            }
        }

        google()
        mavenCentral()
    }
}

Then in your local.properties file, add the following lines:

[email protected]
artifactory.apikey=Your-Artifactory-API-Key

Option 2: Store the username and apikey directly in the settings.gradle file

// below is an example of `dependencyResolutionManagement` block that you may
// have in your settings.gradle file
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    
    repositories {
        // this is the TrueLayer specific part that needs to be added
        // to instruct gradle where to fetch TrueLayer libraries from 
        maven {
            url 'https://truelayer.jfrog.io/artifactory/maven-public'
            credentials {
                username "[email protected]"
                password "Your-Artifactory-API-Key"
            }
            content {
                // this repository *only* contains artifacts with group "com.truelayer"
                includeGroupByRegex "com\\.truelayer.*"
            }
        }

        google()
        mavenCentral()
    }
}

Step 2: Initialise the SDK

To use the SDK, you have to first initialise it before invoking any other SDK method. The following code sample is an example of initialising the SDK:

import com.truelayer.payments.core.domain.configuration.Environment
import com.truelayer.payments.core.domain.configuration.HttpConnectionConfiguration
import com.truelayer.payments.core.domain.configuration.HttpLoggingLevel
import com.truelayer.payments.ui.TrueLayerUI

// Initialize the SDK with your application context.
TrueLayerUI.init(context = applicationContext) {
    // optionally choose which environment you want to use: PRODUCTION or SANDBOX
    environment = Environment.PRODUCTION
    // Make your own custom http configuration, stating custom timeout and http request logging level
    httpConnection = HttpConnectionConfiguration(
        timeoutMs = 5000,
        httpDebugLoggingLevel = HttpLoggingLevel.None
    )
}

Step 3: Process a payment

Depending on your preferred approach, you can choose to integrate the SDK into your payment process with either AndroidX Activity, with the older Android Activity or with Jetpack Compose.

In both cases, you'll need the paymentId and the resourceToken obtained from the backend. The fields mentioned earlier will be passed to the SDK via PaymentContext. There is little more to know about this object. The following kdoc explains all available parameters:

/**
 * Payment context to identify payment to be processed
 *
 * @property paymentId payment identifier obtained from create payment API
 * @property resourceToken resource token obtained from create payment API
 * @property redirectUri uri that will be invoked once payment authorization is completed
 * @property preferences object containing various preferences that allow to override default SDK
 *                     behaviour in certain aspects.
 */
data class PaymentContext(
    val paymentId: String,
    val resourceToken: String,
    val redirectUri: String,
    val preferences: Preferences? = null
)

/**
 * Preferences class that allows to set preferences and override default SDK behaviour
 * in certain aspects.
 *
 * @property preferredCountryCode (optional) in case there are available payment providers from
 *               multiple countries the SDK will try select most appropriate one automatically.
 *               You may want to override that behaviour.
 *               By setting the preferredCountryCode (ISO 3166-1 alpha-2, example: "GB" or "FR"),
 *               the SDK will try first to select preferred country before falling back to the
 *               auto selection.
 */
data class Preferences(
    val preferredCountryCode: String? = null
) : Parcelable

Option 1: Process a payment with an AndroidX Activity integration

import android.widget.Toast
import com.truelayer.payments.ui.models.PaymentContext
import com.truelayer.payments.ui.screens.coordinator.FlowCoordinatorActivityContract
import com.truelayer.payments.ui.screens.coordinator.FlowCoordinatorResult

// Register for the end result.
val contract = FlowCoordinatorActivityContract()
val flowResult = registerForActivityResult(contract) {
    val text = when (it) {
        is FlowCoordinatorResult.Failure -> {
            "Failure ${it.reason}"
        }
        is FlowCoordinatorResult.Successful -> {
            "Successful ${it.step}"
        }
    }
    // present the final result
    Toast.makeText(this, text, Toast.LENGTH_LONG).show()
}

// Obtain your payment context from your backend
val paymentContext = PaymentContext(
    paymentId =  "your-payment-identifier",
    paymentToken = "payment-resource-token",
    redirectUri = "redirect-uri-that-will-be-invoked-when-coming-back-from-bank"
)

// 🚀 Launch the payment flow.
flowResult.launch(paymentContext)

Option 2: Process a payment with an Android Activity integration

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.widget.Toast
import com.truelayer.payments.core.domain.configuration.Environment
import com.truelayer.payments.ui.TrueLayerUI
import com.truelayer.payments.ui.models.PaymentContext
import com.truelayer.payments.ui.screens.coordinator.FlowCoordinatorActivityContract
import com.truelayer.payments.ui.screens.coordinator.FlowCoordinatorResult

class ActivityIntegration : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Initialise the payments configuration
        TrueLayerUI.init(context = applicationContext) {
            environment = Environment.PRODUCTION
            httpConnection = HttpConnectionConfiguration(
                timeoutMs = 5000,
                httpDebugLoggingLevel = HttpLoggingLevel.None
            )
        }
        
        // Obtain your payment context from your backend
        val paymentContext = PaymentContext(
            paymentId =  "your-payment-identifier",
            paymentToken = "payment-resource-token",
            redirectUri = "redirect-uri-that-will-be-invoked-when-coming-back-from-bank"
        )
        // Create an intent to launch the SDK
        val intent = FlowCoordinatorActivityContract().createIntent(this, paymentContext)
        // Launch the SDK
        startActivityForResult(intent, 0)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        // Act on the SDK result
        val text = when (val result = FlowCoordinatorResult.unwrapResult(data)) {
            is FlowCoordinatorResult.Failure -> "Failure ${result.reason}"
            is FlowCoordinatorResult.Successful -> "Successful ${result.step}"
            null -> "Activity result failed."
        }
        Toast.makeText(this, text, Toast.LENGTH_LONG).show()
    }
}

Option 3: Process a payment with a Jetpack Compose integration

You have to make sure that you have setDecorFitsSystemWindows(window, false) and window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) set for the Activity that will be hosting SDK Compose code. The following example shows how to process a payment with a Jetpack Compose integration:

// place the following code in your `onCreate` method of the activity hosting compose code
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    // The following lines are required for the accompanist-ui-insets
    // to work properly
    WindowCompat.setDecorFitsSystemWindows(window, false)
    @Suppress("DEPRECATION")
    window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)

}

// Your payments custom theme or use the provided defaults as below
val theme = TrueLayerTheme(
    lightPalette = LightColorDefaults,
    darkPalette = DarkColorDefaults,
    typography = TypographyDefaults
)

// Obtain your payment context from your backend
val paymentContext = PaymentContext(
    paymentId =  "your-payment-identifier",
    paymentToken = "payment-resource-token",
    redirectUri = "redirect-uri-that-will-be-invoked-when-coming-back-from-bank"
)

setContent {
    Theme(
        theme = theme
    ) {
        FlowCoordinator(
            paymentContext = paymentContext,
            onSuccess = { successStep ->
                // action on success
            },
            onFailure = { failureReason ->
                // action on failure
            },
        )
    }
}

Customise colours

Currently, colour customisation is only available when integrating via Jetpack Compose. To change colours or typography, you have to provide your own version of LightColorDefaults, DarkColorDefaults, TypographyDefaults. You can use .copy() to override just a single colour. For example:

TrueLayerTheme(
    lightPalette = LightColorDefaults.copy(primary = Color.Red),
    darkPalette = DarkColorDefaults.copy(primary = Color.DarkGray),
    typography = TypographyDefaults
)

To find a full list of colours you can override, you can check out the details of androidx.compose.material.Colors in the Android reference documentation.


Did this page help you?