ReactNative - Android
This guide will help you integrate the ReadyRemitSDK into your React Native developed Android projects.
The SDK is compatible with Android versions 9 to 14.
Step 1 - Prepare your project
- Make sure that your app's minimum Android API level is 26 or higher. This can be found in the
build.gradle
file. Depending on your setup this might be defined in thebuild.gradle
file at the Module level or at the Project level.
android {
..
compileSdkVersion 33
defaultConfig {
..
minSdkVersion 26
targetSdkVersion 33
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
composeOptions {
kotlinCompilerExtensionVersion '1.3.2'
}
..
}
- Add classpath dependencies to the
build.gradle
at the Project level
buildscript {
..
ext {
..
kotlinVersion = "1.7.20"
}
dependencies {
..
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
}
}
allprojects {
repositories {
google()
mavenCentral()
jcenter()
maven { url 'https://maven.google.com' }
maven { url "https://jitpack.io" }
}
}
- Add the following
apply
statements to the top of yourbuild.gradle
file at the Module level:
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-parcelize'
Step 2 - Install the ReadyRemit SDK
- Download the
readyremit.aar
from the Releases page on Github - Add the .aar file to the folder your_app_root/app/libs
- Add the path as a dependency to your app's
build.gradle
file a the Module level:
dependencies {
..
// ReadyRemit SDK
implementation files('libs/readyremit.aar')
}
- Add missing third-party dependencies to your app's
build.gradle
file at the Module level:
dependencies {
..
// Core
implementation "androidx.core:core-ktx:1.10.0"
// UI
implementation "androidx.appcompat:appcompat:1.6.1"
implementation "com.google.android.material:material:1.9.0"
// Navigation
implementation "androidx.navigation:navigation-fragment-ktx:2.6.0"
implementation "androidx.navigation:navigation-ui-ktx:2.6.0"
implementation "androidx.navigation:navigation-compose:2.6.0"
// Compose
implementation platform("androidx.compose:compose-bom:2023.06.01")
implementation "androidx.compose.compiler:compiler:1.3.2"
implementation "androidx.compose.runtime:runtime:1.3.2"
implementation "androidx.compose.material:material:1.3.2"
implementation "androidx.compose.ui:ui-tooling"
implementation "androidx.compose.ui:ui-tooling-preview"
implementation "androidx.lifecycle:lifecycle-runtime-compose:2.6.0"
// PDFViewer
implementation 'com.github.DImuthuUpe:AndroidPdfViewer:3.1.0-beta.1'
// Kotlin
implementation platform("org.jetbrains.kotlin:kotlin-bom:1.8.22")
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android"
// OkHttp
implementation "com.squareup.okhttp3:okhttp:4.11.0"
implementation "com.squareup.okhttp3:logging-interceptor:4.11.0"
// Profiler
implementation "com.localebro:okhttpprofiler:1.0.8"
// Retrofit
implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation "com.squareup.retrofit2:converter-gson:2.9.0"
implementation "com.squareup.retrofit2:converter-moshi:2.9.0"
// Moshi
implementation "com.squareup.moshi:moshi:1.14.0"
implementation "com.squareup.moshi:moshi-adapters:1.14.0"
kapt "com.squareup.moshi:moshi-kotlin-codegen:1.14.0"
// Dagger
implementation "com.google.dagger:dagger:2.50"
implementation "com.google.dagger:dagger-android:2.50"
implementation "com.google.dagger:dagger-android-support:2.50"
kapt "com.google.dagger:dagger-compiler:2.50"
kapt "com.google.dagger:dagger-android-processor:2.50"
// Mixpanel
implementation "com.mixpanel.android:mixpanel-android:7.4.1"
// Launch Darkly
implementation "com.launchdarkly:launchdarkly-android-client-sdk:5.0.0"
implementation 'com.github.barteksc:android-pdf-viewer:3.2.0-beta.1'
}
- Set view binding to true in build features to your app's
build.gradle
file at the Module level:
android {
..
buildFeatures {
dataBinding true
viewBinding true
buildConfig true
compose true
}
}
Step 3 - Install required Visa sensory branding libraries
- Download visa-sensory-branding-sdk from Github
- Add the .aar file to the folder your_app_root/app/libs
- Add the path as a dependency to your app's
build.gradle
file a the Module level:
dependencies {
..
implementation files ('libs/visa-sensory-branding-2.0.aar')
}
Step 4 - Create the React Native Bridge and Module
In React Native, a module facilitates communication and interaction between your React Native code and your native modules (Refer to the React Native documentation for more details).
In the root of your Android project in Android Studio, create the following file:
Remember
Remember to replace com.readyremit_demo with your actual package name.
Copy/Paste
The ReadyRemitModule and ReadyRemitPackage code should be added to your project without modification.
package com.readyremit_demo // Put your package name here
import com.brightwell.readyremit.sdk.*
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.brightwell.readyremit.sdk.environment.Environment
import com.facebook.react.bridge.ReadableMap
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter
import com.google.gson.Gson
class ReadyRemitModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
private val REQUEST_CODE = 10
private val READYREMIT_AUTH_TOKEN_REQUESTED = "READYREMIT_AUTH_TOKEN_REQUESTED"
private val READYREMIT_TRANSFER_SUBMITTED = "READYREMIT_TRANSFER_SUBMITTED"
private val READYREMIT_SDK_CLOSE = "SDK_CLOSED"
private val READYREMIT_SDK_LAUNCHED = "SDK_LAUNCHED"
private lateinit var _onAuthCallback: ReadyRemitAuthCallback
private lateinit var _onTransferCallback: ReadyRemitTransferCallback
override fun getName(): String {
return "ReadyRemitModule"
}
@ReactMethod
fun launch(environment: String, language: String = "en", style: ReadableMap? = null) {
ReadyRemit.initialize(
ReadyRemit.Config.Builder(currentActivity!!.application)
.useEnvironment(if(environment == "PRODUCTION") Environment.PRODUCTION else Environment.SANDBOX)
.useAuthProvider { callback -> requestReadyRemitAccessToken(callback) }
.useTransferSubmitProvider { request, callback -> submitReadyRemitTransfer(request, callback) }
.useLanguage(language)
.build()
)
/**
* Initiates the remittance process using ReadyRemit.
*
* @param1 activity - The current activity of the application.
* @param2 requestCode - The request code that will be returned in the `onActivityResult` function this can be a int.
* @param3 theme - The theme to be applied when initiating the SDK, this should be a id (i.e. R.styles.ReadyRemit) or null to use the SDK default one.
* @param4 languageCode - The language code to be used on SDK, in locale format (e.g., "en_US", "es_MX").
*/
ReadyRemit.remitFrom(currentActivity!!, REQUEST_CODE, null, language)
ReadyRemit.setEventListener { event ->
when (event) {
SDKClosed -> {
reactApplicationContext
.getJSModule(RCTDeviceEventEmitter::class.java)
.emit(READYREMIT_SDK_CLOSE, null)
}
SDKLaunched -> {
reactApplicationContext
.getJSModule(RCTDeviceEventEmitter::class.java)
.emit(READYREMIT_SDK_LAUNCHED, null)
}
}
}
}
@ReactMethod
fun setAuthToken(token: String, errorAuthCode: String?) {
if (token != "") {
_onAuthCallback.onAuthSucceeded(ReadyRemitAuth(token, ""))
} else {
_onAuthCallback.onAuthFailed()
}
}
private fun requestReadyRemitAccessToken(callback: ReadyRemitAuthCallback) {
_onAuthCallback = callback
reactApplicationContext
.getJSModule(RCTDeviceEventEmitter::class.java)
.emit(READYREMIT_AUTH_TOKEN_REQUESTED, null)
}
@ReactMethod
fun setTransferId(transferId: String? = "", errorCode: String? = "", errorMessage: String? = "") {
if (transferId != "" && transferId != null) {
_onTransferCallback.onTransferSucceeded(transferId)
} else if (errorCode != null) {
val error = ReadyRemitError(errorCode, errorMessage ?: "", errorMessage ?: "")
_onTransferCallback.onTransferFailed(error)
}
}
private suspend fun submitReadyRemitTransfer(
request: ReadyRemitTransferRequest,
callback: ReadyRemitTransferCallback
) {
_onTransferCallback = callback
var jsonRequest = Gson().toJson(request)
reactApplicationContext
.getJSModule(RCTDeviceEventEmitter::class.java)
.emit(READYREMIT_TRANSFER_SUBMITTED, jsonRequest)
}
}
To add the new module to your native application, you need to create a package with this new module.
Create the following file:
package com.readyremit_demo // Put your package name here
import com.facebook.react.ReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.uimanager.ViewManager
class ReadyRemitPackage : ReactPackage {
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
return listOf(ReadyRemitModule(reactContext))
}
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
return emptyList()
}
}
To have access from your React Native app to your new ReadyRemitModule, you need to add the package in the main application:
@Override
protected List<ReactPackage> getPackages() {
..
packages.add(new ReadyRemitPackage());
}
(Optional) Closing ReadyRemitSDK
If you wish to gracefully close the ReadyRemitSDK at any point in your code, please:
- Add this code to your ReadyRemitModule.kt
@ReactMethod
fun close() {
ReadyRemit.close()
}
- Call this function in your React Native project:
ReadyRemitModule.close();
(Optional) Inactivity Detector
If you prefer to automatically close the ReadyRemitSDK when your users are inactive, you can add the following snippet into your ReadyRemitModule.kt
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.yourcompany.ReadyRemitSDK
class ReadyRemitModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
@ReactMethod
fun launch(environment: String, language: String = "en", style: ReadableMap? = null) {
ReadyRemit.initialize(
ReadyRemit.Config.Builder(currentActivity!!.application)
.useEnvironment(if(environment == "PRODUCTION") Environment.PRODUCTION else Environment.SANDBOX)
.useAuthProvider { callback -> requestReadyRemitAccessToken(callback) }
.useTransferSubmitProvider { request, callback -> submitReadyRemitTransfer(request, callback) }
.useLanguage(language)
.build()
)
// Launch ReadyRemitSDK
ReadyRemit.remitFrom(currentActivity!!, REQUEST_CODE, null, language)
// Set inactivity timeout (e.g., 60 seconds)
ReadyRemit.close(60)
}
}
(Optional) Style the ReadyRemit SDK
- In the root of your Android project create a new "Values Resource File" (ex: theme_readyremit.xml).
- Use the following code as a template and fill in any colors you'd like to override:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.ReadyRemit" parent="Theme.ReadyRemit.Light">
<item name="rrmBackgroundColor">#FEE598</item>
<item name="rrmForegroundColor">#B7D7A9</item>
<item name="rrmButtonTextColor">#D5A6BD</item>
<item name="rrmButtonColor">#9801FF</item>
<item name="rrmDangerColor">#44808E</item>
<item name="rrmDangerLightColor">#6FA8DC</item>
<item name="rrmDividerColor">#660000</item>
<item name="rrmIconColor">#FE0100</item>
<item name="rrmInputLineColor">#008761</item>
<item name="rrmPrimaryColor">#9801FF</item>
<item name="rrmPrimaryLightColor">#9801FF</item>
<item name="rrmSuccessColor">#B55F07</item>
<item name="rrmTextColor">#0100FE</item>
<item name="rrmTextSecondaryColor">#00FEFE</item>
</style>
</resources>
- Navigate to the project's resource folder. The path should be something like: MyProject/app/src/main/res
- Ensure that there is a folder named "values-night". If this folder doesn't exist, create it.
- Inside the "values-night" folder, create an XML file with the exact same name as the original theme used for the light mode.
- Open the project in Android Studio. In the res/values directory, you will find a directory for these themes. There will be one for light mode and one for dark mode (indicated by "night" tag).
- In the dark mode theme file, add the following structure:
Important
• Make sure to set the parent attribute to Theme.ReadyRemit.Dark.
• If you're only using the light mode in your application, you can copy the same colors from the theme used for the light mode. If you're using the dark mode, make the necessary color modifications here.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.ReadyRemit" parent="Theme.ReadyRemit.Dark">
<item name="rrmBackgroundColor">#111111</item>
<item name="rrmForegroundColor">#1F1F1F</item>
<item name="rrmButtonTextColor">#FFFFFF</item>
<item name="rrmButtonColor">#558CF4</item>
<item name="rrmDangerColor">#AA220F</item>
<item name="rrmDangerLightColor">#201311</item>
<item name="rrmDividerColor">#313131</item>
<item name="rrmIconColor">#7E7E7E</item>
<item name="rrmInputLineColor">#505050</item>
<item name="rrmPrimaryColor">#558CF4</item>
<item name="rrmPrimaryLightColor">#83ACF7</item>
<item name="rrmSuccessColor">#008761</item>
<item name="rrmTextColor">#E3E3E3</item>
<item name="rrmTextSecondaryColor">#B0B0B0</item>
<item name="rrmButtonColor">#558CF4</item>
</style>
</resources>
- Update the launch function inside ReadyRemitModule.kt to use the new theme.
ReadyRemit.remitFrom(currentActivity!!, REQUEST_CODE, R.style.ReadyRemit, language)
(For KYC users only) Implement KYC
If you wish to use the ReadyRemitSDK with the KYC feature enabled, you will need to ask your users for Camera permission, to do that, follow this guide
- Enable camera permission into your Manifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.your.package">
..
<uses-feature android:name="android.hardware.camera"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
</manifest>
Updated 5 months ago