Android
How to integrate
Lean's Link Android SDK is a Kotlin library, distributed as a AAR/JAR and distributed via Jitpack.
To get started update your project level build.gradle to include jitpack:
repositories {
maven { url 'https://jitpack.io'}
}Next, add this dependency code to your module's build.gradle file:
dependencies {
implementation "me.leantech:link-sdk-android:X.X.X"Demo app
In order to test out Lean's android Link SDK, please refer to this guide.
Usage
Create a new lean instance with the .Builder() method and pass your app token and list of permissions that you want your user to grant.
These two parameters are necessary and Lean will not be initialised without these.
showLogs() is used to show some basic logs such as which step the user reached etc.
val lean = Lean.Builder()
.setAppToken("YOUR_APP_TOKEN")
.setVersion("latest")
.setCountry("ae")
.setLanguage("en")
.setSandboxMode()
.showLogs()
.build()Listener
Each call to lean's method requires passing a Lean.Listener object which notifies you when the SDK flow completes, is cancelled, or encounters an error.
lean.connect(
activity = this,
customerId = "CUSTOMER_ID",
// ... other parameters
leanListener = object : Lean.Listener {
override fun onResponse(response: Lean.Response) {
when (response.status) {
"SUCCESS" -> {
// User successfully completed the flow
}
"CANCELLED" -> {
// User cancelled the flow
}
"ERROR" -> {
// An error occurred - check response.message and response.secondaryStatus
}
}
}
}
)The onResponse() method is called when the SDK flow completes. The response object contains information about the outcome, including the status, exit point, and any error details. See the Callback functions section for details on the response structure.
NoteThe old
LeanListenerinterface withonSuccess()andonFailure()methods has been deprecated. Please useLean.ListenerwithonResponse()instead.
Available Methods
.connect()
The connect method is used to connect a customer to both the Payments and Data API. You can use this method to generate a Payment Source and an Entity with a single customer login.
lean.connect(
activity = this,
customerId = "CUSTOMER_ID",
bankIdentifier = null,
paymentDestinationId = "PAYMENT_DESTINATION_ID", //if not sent, the default destination ID (your CMA account) will be used
permissions = arrayListOf(
Lean.UserPermissions.IDENTITY,
Lean.UserPermissions.ACCOUNTS,
Lean.UserPermissions.TRANSACTIONS,
Lean.UserPermissions.BALANCE,
Lean.UserPermissions.PAYMENTS
),
customization = null,
accessTo = null,
accessFrom = null,
failRedirectUrl = null,
successRedirectUrl = null,
accountType = null,
endUserId = null,
accessToken = null,
showConsentExplanation = null,
destinationAlias = null,
destinationAvatar = null,
customerMetadata = null,
leanListener = object : Lean.Listener {
override fun onResponse(response: Lean.Response) {
// Handle response
}
}
).reconnect()
The reconnect method is used to re-authenticate a customer account with the Data API.
lean.reconnect(
activity = this,
reconnectId = "RECONNECT_ID",
customization = null,
accessToken = null,
destinationAlias = null,
destinationAvatar = null,
leanListener = object : Lean.Listener {
override fun onResponse(response: Lean.Response) {
// Handle response
}
}
).createBeneficiary()
The createBeneficiary method is used to authorize an additional payment destination for an existing payment source in the Payments API.
NOTE: We have renamed the updatePaymentSource() method on the Link SDK. It will now be called createBeneficiary(). The updatePaymentSource() method is now deprecated. Please use the new method as detailed below.
lean.createBeneficiary(
activity = this,
customerId = "CUSTOMER_ID",
paymentSourceId = "PAYMENT_SOURCE_ID", //or entityId if the customer was already connected for Data permissions without the payments permission
paymentDestinationId = "PAYMENT_DESTINATION_ID",
customization = null,
failRedirectUrl = null,
successRedirectUrl = null,
accessToken = null,
entityId = null,
destinationAlias = null,
destinationAvatar = null,
leanListener = object : Lean.Listener {
override fun onResponse(response: Lean.Response) {
// Handle response
}
}
)
Connecting data customers with paymentsIf your customer already connected their account for Data permissions (accounts, transactions, identity or balances) but was missing the "payments" permission, you can pass the "entityId" instead of the "paymentSourceId" and the payments permission will be added to the connected account accordingly
.pay()
The pay method is used to make a bank to bank transfer from your customer's account to your account in the Payments API.
lean.pay(
activity = this,
paymentIntentId = "PAYMENT_INTENT_ID",
bulkPaymentIntentId = null,
accountId = null,
bankIdentifier = null,
showBalances = false,
customization = null,
failRedirectUrl = "https://yourapp.com/payment-failure", // Required for OpenFinance payments
successRedirectUrl = "https://yourapp.com/payment-success", // Required for OpenFinance payments
endUserId = null,
accessToken = null,
destinationAlias = null,
destinationAvatar = null,
riskDetails = null,
leanListener = object : Lean.Listener {
override fun onResponse(response: Lean.Response) {
// Handle response
}
}
)The showBalances parameter is optional and allows you to show/hide the balances of bank accounts when an end user is going through the payment authorization flow. It's RECOMMENDED to always "HIDE" the balances.
For Open Finance clients, the successRedirectUrl and failRedirectUrl parameters are MANDATORY when calling the pay method. These URLs are used to redirect your customer back to your application once the payment is completed on the bank side.
.checkout()
The checkout method purpose build for Open Finance payments, it allows you initiate a guest payment flow without requiring a customer account.
lean.checkout(
activity = this,
paymentIntentId = "PAYMENT_INTENT_ID",
customerName = null,
bankIdentifier = null,
accessToken = null,
successRedirectUrl = "https://yourapp.com/payment-success",
failRedirectUrl = "https://yourapp.com/payment-failure",
customization = null,
riskDetails = null,
leanListener = object : Lean.Listener {
override fun onResponse(response: Lean.Response) {
// Handle response
}
}
).authorizeConsent()
The authorizeConsent method is used to authorize an Account on File consent.
lean.authorizeConsent(
activity = this,
customerId = "CUSTOMER_ID",
consentId = "CONSENT_ID",
failRedirectUrl = "https://yourapp.com/payment-failure",
successRedirectUrl = "https://yourapp.com/payment-success",
customization = null,
accessToken = null,
destinationAlias = null,
destinationAvatar = null,
riskDetails = null,
leanListener = object : Lean.Listener {
override fun onResponse(response: Lean.Response) {
// Handle response
}
}
).manageConsents()
The manageConsents method is used to show an interface where customers can view all data and payment long-lived consent and also manage them.
lean.manageConsents(
activity = this,
customerId = "CUSTOMER_ID",
accessToken = null,
customization = null,
leanListener = object : Lean.Listener {
override fun onResponse(response: Lean.Response) {
// Handle response
}
}
).captureRedirect()
After Open Finance method like pay, checkout and authorizeConsent when bank flow is completed, Lean redirects the customer back to your configured URL (successRedirectUrl or failRedirectUrl), appending a set of query parameters that describe the outcome of the Consent attempt. These parameters include identifiers that your application can use to verify and persist the result.
To display the final result screen to the customer, you should call the captureRedirect() function from the LinkSDK and pass parameters from redirect.
lean.captureRedirect(
activity = this,
customerId = "<from_query_param>",
accessToken = "<customer_scoped_access_token>",
consentAttemptId = "<from_query_param>",
granularStatusCode = "<from_query_param>",
statusAdditionalInfo = "<from_query_param>",
customization = null,
leanListener = object : Lean.Listener {
override fun onResponse(response: Lean.Response) {
// Handle response
}
}
)Callback functions
The Android SDK uses a Listener interface which allows you to receive events on SDK close, completion or error.
Response
The responseObject returned to your callback function is in the following format:
{
"status": "SUCCESS",
"message": "User successfully connected their account",
"last_api_response": "SUCCESS",
"exit_point": "SUCCESS",
"secondary_status": "SUCCESS",
"bank": {
"bank_identifier": "LEANMB1",
"is_supported": true
}
}status enum
The end status of the LinkSDK at close.
| Status | Reason |
|---|---|
SUCCESS | The initiated flow was completed successfully |
CANCELLED | The initiated flow was cancelled by the user |
ERROR | The SDK or user experienced an error - the details for the error are available in the message and secondary_status. |
message string
Further details on the end state. May be null.
last_api_response string
Details on the last response status from the Lean API. May be null.
exit_point enum
The last screen displayed before the user exited the SDK.
| value | screen |
|---|---|
INITIAL | The first screen displayed to users |
RECONNECT_INITIAL | The first screen displayed to users when using .reconnect() |
BANK_SELECTION | The bank list screen |
OPEN_BANKING | Open banking redirect initiation |
CONSENT | The permissions screen |
CREDENTIALS | The login detail entry screen |
CREDENTIALS_UPDATE | The re-entry form for login details when credentials are outdated |
MFA | The OTP entry screen |
OPEN_BANKING_ENABLE_PAYMENTS | Open banking redirect initiation for payments |
PAYMENT_SOURCES | The screen that lists all a user's payment sources prior to payment initiation |
UPDATE_PAYMENT_SOURCE | The update payment source consent screen |
PAYMENT_DETAILS | The payment initiation screen |
SECURITY_QUESTION | The security question answer form |
MFA_INSTRUCTIONS | The instructions for entering an OTP |
UNSUPPORTED_BANK_REQUEST | The unsupported bank list screen |
SUCCESS | The success screen |
FAIL | The failure screen |
secondary_status enum
Further details on failures e.g. INVALID_CREDENTIALS. May be null.
bank object
Details on the bank selected by the user.
bank.bank_identifier
| The Lean identifier for the bank. |
bank.is_supported
| Whether the bank is supported by Lean or not (is false when a user selects a bank through the 'My bank is not listed' button) |
Unsupported banks
Your users can indicate that their bank is not supported. When this happens, the callback from the LinkSDK will contain a false flag in the bank object.
{
"status": "CANCELLED",
"message": "User cancelled the operation",
"exit_point": "UNSUPPORTED_BANK_REQUEST_SUCCESS",
"last_api_response": "CANCELLED",
"secondary_status": "CANCELLED",
"bank": {
"bank_identifier": "AHB_UAE",
"is_supported": false
}
}Skip Bank List
In some use cases you may want to provide your own UI for the bank selection screen in the LinkSDK. This can be achieved by passing in a bank_identifier during the .connect() flow.
You can get a list of available bank_identifiers for your application by making a call to the /banks/ endpoint.
Call:
curl -X GET 'https://api.leantech.me/banks/v1/' \
--header 'lean-app-token: 2c9a80897169b1dd01716a0339e30003'Response:
[
{
"id": 13,
"identifier": "FAB_UAE",
"name": "First Abu Dhabi Bank",
"main_color": "#ffffff",
"background_color": "#00458A",
"theme": "light",
"country_code": "UAE",
"active": true,
"traits": [
"user-input-on-login",
"auth-credentials"
],
"supported_account_types": [
"CREDIT",
"SAVINGS",
"CURRENT"
]
},
{
"id": 12,
"identifier": "LEANMB1",
"name": "Lean Mock Bank",
"main_color": "#FDB813",
"background_color": "#06357A",
"theme": "light",
"country_code": "UAE",
"active": true,
"traits": [
"auth-credentials"
],
"supported_account_types": [
"CREDIT",
"SAVINGS",
"CURRENT"
]
}You can then use the bank identifier directly with the LinkSDK to skip the bank selection screen:
lean.connect(
Activity, customer_id, bankIdentifer, paymentDestinationId, userPermissionsArray, customization, new Lean.LeanListener() {
@Override
public void onSuccess() {
Log.d("LEAN_SDK", "SUCCESS");
}
@Override
public void onFailure(@NotNull Lean.StepCompleted lastStep) {
Log.e("LEAN_SDK", "FAILED -> " + lastStep.toString());
}
});Skip Payment Source selection
In Some use cases, you may want to render your own list of Payment Sources - or have business logic around which payment source can be used to make a specific payment. In these cases, you can pass the accounts[n].id parameter from a Customer's Payment Source into the LinkSDK to skip the selection screen within the SDK.
How to get Payment Sources for a Customer
lean.pay(
Activity, payment_intent_id, showBalances, account_id, customization, new Lean.LeanListener() {
//if you add the account ID the payment source will be skipped
@Override
public void onSuccess() {
Log.d("LEAN_SDK", "SUCCESS");
}
@Override
public void onFailure(@NotNull Lean.StepCompleted lastStep) {
Log.e("LEAN_SDK", "FAILED -> " + lastStep.toString());
}
});Changing the SDK language
Link SDK is available in English and Arabic, fully supported with a right-to-left UI, including text alignment, icons and images. If no language is provided the default is English. The language parameter is provided to the Lean.Builder()
val lean = Lean.Builder()
.setLanguage("ar")
...Language option
language enum
en | English |
ar | Arabic |
Customizing Link SDK
We are progressively releasing customization capabilities to the Link SDK to match its UI with your application branding style. This allows customers to programmatically theme the Link SDK directly from any of the methods.
For more detailed documentation on how best to use the customization feature see our guides.
Presentation options
dialog_mode string
Presents the Link SDK with or without a containing modal.
"contained" for modal (default), or "uncontained" for no modal.
button_border_radius string
Change the shape of the main button on each step. See guidance for examples.
A unitless number as a String. Options:
| Value | Style |
|---|---|
"4" | default |
"8" | Border radius of 8px |
"0" | Rectangle button |
"pill" | Always pill shaped, whatever the button height |
Color options
theme_color string
Buttons background color, active input borders, and loading spinners.
button_text_color string
Elements inside any primary button such as the text, icons and the loading spinner. It is useful to boost readability of the button color.
link_color string
CTAs and helpers.
overlay_color string
Overlay containing the Link SDK dialog box.
The following color formats are supported:
| Example | Format |
|---|---|
"#000000" | Hex |
"#000" | Shorthand hex |
"#000000FF" | Hex with alpha |
"rgb(0, 0, 0)" | Comma separated RGB |
"rgba(0, 0, 0, 0.5)" | Comma separated RGB with Alpha |
"black" | Color name |
Example
val linkCustomization = Lean.Customization().apply {
themeColor = "#0080ff"
buttonTextColor = "#ffffff"
linkColor = "#0080ff"
overlayColor = "rgba(0, 0, 0, 0.8)"
buttonBorderRadius = "8"
dialogMode = "uncontained"
}
lean.connect(
activity = this,
customerId = "CUSTOMER_ID",
bankIdentifier = null,
paymentDestinationId = "PAYMENT_DESTINATION_ID",
permissions = arrayListOf(
Lean.UserPermissions.IDENTITY,
Lean.UserPermissions.ACCOUNTS,
Lean.UserPermissions.TRANSACTIONS,
Lean.UserPermissions.BALANCE,
Lean.UserPermissions.PAYMENTS
),
customization = linkCustomization,
accessTo = null,
accessFrom = null,
failRedirectUrl = null,
successRedirectUrl = null,
accountType = null,
endUserId = null,
accessToken = null,
showConsentExplanation = null,
destinationAlias = null,
destinationAvatar = null,
customerMetadata = null,
leanListener = object : Lean.Listener {
override fun onResponse(response: Lean.Response) {
// Handle response
}
}
)Updated 26 days ago
