Integrate Turbo UPI (with UI) on Android App
Steps to integrate Razorpay Turbo UPI with UI on your Android app.
Use Razorpay Turbo UPI to make UPI payments faster. Follow these steps to integrate with the Razorpay Turbo UPI UI SDK.
-
Integrate with the
. -
Contact our
and provide the following details to get allowlisted:- Mobile numbers of your internal users.
- App id of your debug, staging and production apps.
-
Contact our
to get the access to the Sample App Repositoryhttps://github.com/upi-turbo/android-turbo-sample-app
. Once you have access, please read the readme section of the repository to learn how to locate the library files and integrate them into your project. -
Add the following lines to your Android project's
gradle.properties
file:android.enableJetifier=true
android.useAndroidX=true
-
The
minSDKversion
for using Turbo UPI is currently 23 and cannot be over written.
Add the following dependencies:
- In the root settings.gradle file, use:
dependencyResolutionManagement {repositories {// ... other repositories ...maven {url = uri("https://maven.pkg.github.com/upi-turbo/android-turbo-sample-app")credentials {username = "upi-turbo"password = "<Get the password from Razorpay team>"}}}}
- In the library module's build.gradle, use:
dependencies {// UATimplementation "com.razorpay:customui-uat:$CUSTOMUI_VERSION"implementation "com.razorpay:razorpay-turbo-uat:$TURBO_VERSION"implementation "com.razorpay:turbo-ui-uat:$TURBO_VERSION"// ProductionreleaseImplementation "com.razorpay:customui:$CUSTOMUI_VERSION"releaseImplementation "com.razorpay:razorpay-turbo:$TURBO_VERSION"releaseImplementation "com.razorpay:turbo-ui:$TURBO_VERSION"}
Watch Out!
- Use the
rzp_test_0wFRWIZnH65uny
API key id for testing on the UAT environment and the on the prod testing. - Replace the placeholders ($CUSTOMUI_VERSION, $TURBO_VERSION and $CHECKOUT_VERSION) with the latest versions provided by Razorpay's team or similar to
app/build.gradle
file in the Sample app.
To enhance security, you must create a session token via a server-to-server (S2S) call between your backend and Razorpay's backend. This session token ensures secure communication between the Turbo SDK and Razorpay's systems.
-
Trigger the S2S API from your Backend. Use the following API to generate a session token:
Environment based URLs:
-
UAT:
https://api-web-turbo-upi.ext.dev.razorpay.in
-
Production:
https://api.razorpay.com
Authorization Header Creation:
Base64.encode(${public_key}:${secret})
customer_reference
mandatory
string
A unique identifier for the customer provided by the business. The recommended value is mobile number. For example,9000090000
.token
string
A session token to be used in subsequent session-protected APIs.expire_at
long
Expiry time (in seconds) for the session token, used to optimise session handling and reduce unnecessary reinitialisations.error
object
The request failure due to business or technical failure. -
-
Pass the Generated Token to Turbo SDK. Use the session token in the
, ensuring that it is refreshed upon expiry.
Initialise the TurboSessionDelegate
object anonymously and pass it through the initialize method. The SDK will call fetchToken
whenever required and use the provided callback to handle the new/updated token.
In the fetchToken function, retrieve a new token from your server (see
) and once available, pass it to the completion object. This mechanism allows you to seamlessly refresh the session by retrieving a new token via a server-to-server (S2S) call whenever the SDK requests it.val turboSessionDelegate: TurboSessionDelegate = object : TurboSessionDelegate {override fun fetchToken(completion: (Session) -> Unit) {// fetch token here and once fetched,// it can be passed back to Turbo SDK using completion lambda callbackcompletion(Session(token: <new-token>))}}// pass the above created turboSessionDelegate object through initialize methodrazorpay.upiTurbo.initialize(turboSessionDelegate)
After initialising the Turbo SDK, proceed to securely link UPI accounts and complete the payment flow.
-
Get already linked accounts.
If your customer has already linked accounts, use the following code to fetch them. If there are no linked UPI accounts, an empty list is returned.
Handy Tips
- When the user arrives at your checkout screen, use the
getLinkedUpiAccounts
function to fetch the updated list of UPI accounts. - A mobile number is required in the
linkNewUpiAccount
function for an enhanced user experience. Otherwise, feel free to use either your mobile number or customer id.
razorpay.upiTurbo?.getLinkedUpiAccounts(<10 digit mobile number>, <unique customer id>, object : UpiTurboResultListener {override fun onSuccess(accList: List<UpiAccount>) {if (accList.isNotEmpty()) {Log.d("UpiTurbo", "UpiAccount list")} else {// call linkNewAccount()}}override fun onError(error: Error) {Log.d("UpiTurbo", error.message)}})Watch Out!
If the device binding is not completed and the
getLinkedUpiAccounts
is triggered, it will return anOnError
with a DEVICE_BINDING_INCOMPLETE error code.customerMobile
mandatory
string
The customer's mobile number.listener
object
The listener to be sent should be of typeUpiTurboResultListener
. - When the user arrives at your checkout screen, use the
Invoke the below function for these use cases:
-
To initiate new onboarding, in case you get a DEVICE_BINDING_INCOMPLETE error in the above section,
-
To link additional bank accounts for already onboarded users.
Handy Tips
A mobile number is required in the
linkNewUpiAccount
function for an enhanced user experience. Otherwise, feel free to use either your mobile number or customer id.razorpay.upiTurbo?.linkNewUpiAccountWithUI(<10 digit mobile number>, <unique customer id>, object: UpiTurboLinkAccountResultListener {override fun onSuccess(upiAccounts: List<UpiAccount>) {//Display onboarded UpiAccounts.}override fun onFailure(error: com.razorpay.upi.Error) {//Display error message to user.}}, {color-hex for button's theme})
-
To process the payments, call the
submit method
of custom checkout with the provided payload.val payload = JSONObject("""{"currency":"INR","amount":"700","email":"gaurav.kumar@example.com","contact":"9000090000","method":"upi",// the below upi block is specific for Turbo UPI Payment"upi":{"flow":"in_app"},"order_id":"order_L2MUBUOeFItcpU",//optional"customer_id":"cust_KQlMczYKcDIqmB"//optional}""".trimIndent()) -
Pass the
vpa
andpayload
objects as shown in the code below.val turboPayload = HashMap<String, Any> ().apply {put("upiAccount", upiAccount)put("payload", payload)}razorpay.submit(turboPayload, object: PaymentResultWithDataListener {override fun onPaymentSuccess(razorpayPaymentID: String, paymentData: PaymentData) {}override fun onPaymentFailure(code: Int, response: String, paymentData: PaymentData) {//Show error message}})
You can directly interact with the exposed methods of the Turbo Framework to perform the non-transactional flows listed below.
Let Razorpay SDK manage the linked UpiAccount
on the applications by triggering manageUpiAccounts()
.
Handy Tips
A mobile number is required in the linkNewUpiAccount
function for an enhanced user experience. Otherwise, feel free to use either your mobile number or customer id.
razorpay.upiTurbo?.manageUpiAccounts(<10 digit mobile number>, <unique customer id>,object : UpiTurboManageAccountListener {override fun onError(error: JSONObject) {/*Throws error if UPI Turbo cannot be initialized or throws error*/}override fun onSuccess(data: Any) {/*Can be safely ignored*/}})
Watch Out!
The same combination of mobile number and customer id must be consistently passed across all sessions when calling linkNewUpiAccountWithUI
, getLinkedUpiAccounts
and manageUpiAccounts
for a given user.
-
To get the device binding status, please use the method
isDeviceOnboarded()
which returns a boolean. It indicates whether the device binding, which is a prerequisite for adding UPI accounts, is done with the user's mobile number.if (Razorpay.UpiTurbo.isDeviceOnboarded(activity: Activity)) {// User Device Binded} else {// Call Link New Account for Device Binding} -
Users can now link their credit cards alongside bank accounts during onboarding. You can seamlessly retrieve both credit and bank accounts for transactions, thereby simplifying payments, expanding options, and ensuring security.
-
Charges will be levied for payments made using CC on UPI. Contact the
for further information.
The SDKs given below provide access to exposed models for seamless integration.
We recommend the following:
- Complete the integration on UAT before using the prod builds.
- Perform the UAT using the Razorpay-provided API keys.
Complete these steps to take your integration live:
-
You should get your app id allowlisted by Razorpay to test on prod.
-
As a compliance requirement, you need to get approval from Google for READ_SMS permission. Refer
for more details. -
Add Proguard rules:
keepclassmembers,allowobfuscation class * { @com.google.gson.annotations.SerializedName <fields>; }
keepclassmembers enum * { *; }
keepclassmembers class * { @android.webkit.JavascriptInterface <methods>; }
dontwarn com.razorpay.**
keep class com.razorpay.** {*;}
keep class com.olivelib.** {*;}
keep class com.olive.** {*;}
keep class org.apache.xml.security.** {*;}
keep interface org.apache.xml.security.** {*;}
keep class org.npci.** {*;}
keep interface org.npci.** {*;}
keep class retrofit2.** { *; }
keep class okhttp3.** { *; }
-
Replace the UAT credential with the
for prod testing.
Is this integration guide useful?