Open Finance
The React Native SDK wraps the Lean Link SDK in a React component backed by react-native-webview and exposes each method via a ref.
PrerequisitesBefore calling any SDK method you need to have completed the backend setup in the Getting Started section:
- Create your Lean application in the developer dashboard to obtain an
app_token.- Authentication — OAuth flow for minting customer-scoped
access_tokens.- Creating a customer —
POST /customers/v1to obtain acustomer_id.- Sandbox testing — test users and mock bank.
This page covers only the client-side SDK integration.
Installation
# npm
npm install lean-react-native react-native-webview
# yarn
yarn add lean-react-native react-native-webviewOn iOS, install pods:
cd ios && pod installThe latest version is on npm.
Usage
Render the LinkSDK component once in your tree with a ref, then call methods on that ref to launch a flow.
import React, { useRef } from 'react';
import { View, TouchableOpacity, Text } from 'react-native';
import LinkSDK from 'lean-react-native';
export default function App() {
const lean = useRef<any>(null);
return (
<View>
<TouchableOpacity
onPress={() =>
lean.current?.connect({
customer_id: 'CUSTOMER_ID',
permissions: ['identity', 'accounts', 'transactions', 'balance'],
access_token: '<CUSTOMER_SCOPED_JWT>',
})
}
>
<Text>Connect Account</Text>
</TouchableOpacity>
<LinkSDK
ref={lean}
appToken="<YOUR_APP_TOKEN>"
version="latest"
country="ae" // or "sa"
sandbox
callback={(response) => console.log(response)}
/>
</View>
);
}The component renders a full-screen modal when a flow is invoked and dismisses itself when the user closes or completes the flow. The callback prop receives the response — see LinkSDK statuses for status codes.
Available methods
All methods take a config object with snake_case field names (same as the Web SDK).
.connect()
Link a bank account for data access (and optionally payments).
Required: customer_id, permissions.
lean.current.connect({
customer_id: 'CUSTOMER_ID',
permissions: ['identity', 'accounts', 'transactions', 'balance'],
access_token: '<CUSTOMER_SCOPED_JWT>',
// Optional:
bank_identifier: '<BANK_IDENTIFIER>',
account_type: 'PERSONAL',
end_user_id: '<END_USER_ID>',
access_to: '2025-12-31',
access_from: '2025-01-01',
fail_redirect_url: '<FAIL_URL>',
success_redirect_url: '<SUCCESS_URL>',
show_consent_explanation: false,
destination_alias: '<ALIAS>',
destination_avatar: '<URL>',
customer_metadata: '<METADATA>',
payment_destination_id: '<PAYMENT_DESTINATION_ID>',
});.pay()
Initiate a bank-to-bank payment.
Required: exactly one of payment_intent_id or bulk_payment_intent_id.
lean.current.pay({
payment_intent_id: 'PAYMENT_INTENT_ID',
// OR: bulk_payment_intent_id: 'BULK_PAYMENT_INTENT_ID',
access_token: '<CUSTOMER_SCOPED_JWT>',
// Optional:
account_id: '<ACCOUNT_ID>',
bank_identifier: '<BANK_IDENTIFIER>',
end_user_id: '<END_USER_ID>',
fail_redirect_url: 'https://yourapp.com/payment-failure',
success_redirect_url: 'https://yourapp.com/payment-success',
destination_alias: '<ALIAS>',
destination_avatar: '<URL>',
risk_details: { /* fraud signals */ },
});.reconnect()
Restore a broken bank connection.
Required: reconnect_id.
lean.current.reconnect({
reconnect_id: 'RECONNECT_ID',
access_token: '<CUSTOMER_SCOPED_JWT>',
destination_alias: '<ALIAS>',
destination_avatar: '<URL>',
});.updatePaymentSource()
Add a beneficiary to an existing payment source.
Required: customer_id, payment_destination_id, and one of payment_source_id or entity_id.
lean.current.updatePaymentSource({
customer_id: 'CUSTOMER_ID',
payment_destination_id: 'PAYMENT_DESTINATION_ID',
payment_source_id: 'PAYMENT_SOURCE_ID',
// OR: entity_id: 'ENTITY_ID',
access_token: '<CUSTOMER_SCOPED_JWT>',
// Optional:
end_user_id: '<END_USER_ID>',
success_redirect_url: '<SUCCESS_URL>',
fail_redirect_url: '<FAIL_URL>',
destination_alias: '<ALIAS>',
destination_avatar: '<URL>',
});.checkout()
Open Finance guest payment — the customer authenticates at the bank and is redirected back to your success_redirect_url / fail_redirect_url with status query parameters you feed into captureRedirect.
Required: payment_intent_id, success_redirect_url, fail_redirect_url.
lean.current.checkout({
payment_intent_id: 'PAYMENT_INTENT_ID',
success_redirect_url: 'https://yourapp.com/payment-success',
fail_redirect_url: 'https://yourapp.com/payment-failure',
// Optional:
customer_name: 'Jane Doe',
bank_identifier: '<BANK_IDENTIFIER>',
access_token: '<CUSTOMER_SCOPED_JWT>',
risk_details: { /* fraud signals */ },
});.authorizeConsent()
Grant a long-lived Open Finance consent. Redirects to the bank and returns to your success_redirect_url / fail_redirect_url.
Required: customer_id, consent_id, success_redirect_url, fail_redirect_url.
lean.current.authorizeConsent({
customer_id: 'CUSTOMER_ID',
consent_id: 'CONSENT_ID',
success_redirect_url: 'https://yourapp.com/consent-success',
fail_redirect_url: 'https://yourapp.com/consent-failure',
access_token: '<CUSTOMER_SCOPED_JWT>',
// Optional:
destination_alias: '<ALIAS>',
destination_avatar: '<URL>',
risk_details: { /* fraud signals */ },
});.manageConsents()
Show a customer-facing consent management screen.
Required: customer_id.
lean.current.manageConsents({
customer_id: 'CUSTOMER_ID',
access_token: '<CUSTOMER_SCOPED_JWT>',
});.captureRedirect()
Show the outcome screen after an Open Finance redirect. Extract the status query parameters Lean appends to your redirect URL (consent_attempt_id, granular_status_code, status_additional_info) and pass them in.
Required: customer_id.
lean.current.captureRedirect({
customer_id: '<from_query_param>',
access_token: '<customer_scoped_access_token>',
consent_attempt_id: '<from_query_param>',
granular_status_code: '<from_query_param>',
status_additional_info: '<from_query_param>',
});.verifyAddress()
Proof-of-address check.
Required: customer_id, customer_name, permissions (typically ["identity"]).
lean.current.verifyAddress({
customer_id: 'CUSTOMER_ID',
customer_name: 'Jane Doe',
permissions: ['identity'],
access_token: '<CUSTOMER_SCOPED_JWT>',
destination_alias: '<ALIAS>',
destination_avatar: '<URL>',
});Deprecated methods
.createBeneficiary()
Deprecated — useupdatePaymentSourceinstead.
Alias for updatePaymentSource. Accepts the same configuration and behaves identically.
.createPaymentSource()
Deprecated — useconnectwithpermissions: ['payments']instead.
Customisation
Pass customization on any method call, or set defaults via a prop on <LinkSDK>. Full field reference in Customisation.
<LinkSDK
ref={lean}
appToken="<YOUR_APP_TOKEN>"
version="latest"
country="ae"
sandbox
customization={{
theme_color: '#0080ff',
button_text_color: '#ffffff',
button_border_radius: '8',
dialog_mode: 'contained',
}}
/>Language
Pass language: "ar" (or "en") on any method call to override the SDK UI language.
Bank-list and account-selection shortcuts
Pass bank_identifier to skip the bank-selection screen (Lean bank identifier — see Create your own bank list). Pass account_id on pay to skip the payment-source-selection screen.
Troubleshooting
Android WebView crashes
Disable hardware acceleration on the WebView by passing Android-specific props:
<LinkSDK
ref={lean}
appToken="<YOUR_APP_TOKEN>"
sandbox
webViewProps={{
androidHardwareAccelerationDisabled: true,
}}
/>JDK version issues (Android)
Gradle errors about JDK mismatch typically mean your system JDK differs from the one bundled with Android Studio. Point JAVA_HOME at the Android Studio JDK:
- macOS:
export JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home" - Windows:
SET JAVA_HOME="C:\Program Files\Android\Android Studio\jbr"
Related
Updated about 3 hours ago
