Integrate Turbo UPI UI

Steps to integrate Razorpay Turbo UPI with your app.


Use Razorpay Turbo UPI to make UPI payments faster. Follow these steps to integrate with the Razorpay Turbo UPI UI SDK.

What's New

Users can now link their credit cards alongside bank accounts during onboarding. Merchants can seamlessly retrieve both credit and bank accounts for transactions, thereby simplifying payments, expanding options, and ensuring security.

Watch Out!

Charges will be levied for payments made using CC on UPI. Contact the

for further information.

Prerequisites

  1. Contact our

    to get your mobile number, app and GitHub account whitelisted to get access to the https://github.com/upi-turbo/android-turbo-sample-app - sample app repository. In this repository, you will find the AAR files (libraries for Turbo) and the sample app source code to help you do the entire integration. The AARs on the main branch are for the UAT environment, and the ones on the prod branch are for the production environment.
    These are the important files in the sample app repo:

    • app/src/turboUI: Sample app code for UI SDK
    • app/libs: All libraries (Bank, SecureComponent and Turbo) common for headless and UI SDK
    • app/uiLibrary: Library for UI SDK.
    • app/build.gradle: All transitive dependencies needed to integrate Turbo SDK.
  2. Integrate with the

    .

  3. Import the following frameworks:

    • Razorpay Turbo Wrapper Plugin SDK (maven)
    • Razorpay Turbo Core SDK
    • Razorpay SecureComponent SDK
    • Bank SDK
  4. Add the following lines to your Android project's gradle.properties file:

    • android.enableJetifier=true
    • android.useAndroidX=true

Watch Out!

  • minSDKversion for using Turbo UPI is currently 19 and cannot be over written.
  • Use the rzp_test_0wFRWIZnH65uny API key id for testing on the UAT environment and the for prod testing.
  • As a compliance requirement, you need to get approval from Google for READ_SMS permission. Refer for more details.
  • If you choose for the With UI approach, please note that specific functions of headless SDK will not be available. Ensure you select the method that suits your integration requirements.

Follow these steps:

  1. You need to link the customer's UPI account with your app. Use the code samples given below to fetch the UPI account.

    • If your customer has already linked the UPI account, use the following code to fetch it. If there are no linked UPI accounts, an empty list is returned.
    razorpay.upiTurbo?.getLinkedUpiAccounts("<customerMobile>", 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)
    }
    })
  2. If the customer has not linked any UPI account, there are two methods to link UPI accounts:

    • Link one UPI account at a time:
      Use the following code to link the newly created UPI account with your app. This function can be called from anywhere in the application, providing multiple entry points for customers to link their UPI account with your app.

      razorpay.upiTurbo?.linkNewUpiAccountWithUI("<customerMobile>",object:
      UpiTurboLinkAccountResultListener{
      override fun onSuccess(upiAccount: List< UpiAccount>){
      }
      override fun onError(error: Error){
      }
      }, "<color>")
    • Prefetch and Link multiple accounts together:
      Use the following code to prefetch and link multiple UPI accounts from popular banks. This function is versatile and can be called from anywhere in the application, offering customers multiple entry points to link their UPI accounts with your app.

      razorpay.upiTurbo?.setCustomerMobile("<customerMobile>")
      .setColor("<color>")
      .prefetchAndLinkUpiAccountsWithUI(
      object: UpiTurboPrefetchLinkAccountsResultListener {
      override fun onResponse(accounts: AllAccounts) {
      var accountsWithPinSet = accounts.accountsWithPinSet
      var accountsWithPinNotSet = accounts.accountsWithPinNotSet
      if (accountsWithPinSet[0] is BankAccount) {
      when (accountsWithPinSet[0].state) {
      LINKING_IN_PROGRESS -> {
      // Show account is linking
      }
      LINKING_FAILED -> {
      // Show account linking failed
      }
      else -> {
      // Not possible in prefetch flow
      }
      }
      } else if (accountsWithPinSet[0] is UpiAccount) {
      // Continue payment
      }
      // Display accountsWithPinNotSet in expandable section - with Set Pin button
      }
      }
      )
  3. To accept payments, call Custom Checkout’s submit method with the following payload:

    val payload = JSONObject("""
    {
    "currency":"INR",
    "amount":"700",
    "email":"gaurav.kumar@example.com",
    "contact":"9999999999",
    "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())
  4. Pass the upiAccount and payload objects as shown in the code below:

    HashMap<String, Object> turboPayload = new HashMap<>();
    turboPayload.put("upiAccount", upiAccount);
    turboPayload.put("payload", payload);
    razorpay.submit(turboPayload, object : PaymentResultListener {
    override fun onPaymentSuccess(razorpay_payment_id: String?, data: PaymentData?) {
    // show appropriate status of the payment to user.
    }
    override fun onPaymentError(code: Int, message: String?, data: PaymentData?) {
    // show appropriate status of the payment to user.
    }
    })

You can directly interact with the exposed methods of the Turbo Framework to perform the non-transactional flows listed below.

Manage UPI Accounts

Let Razorpay SDK manage the linked UpiAccounts on the applications by triggering manageUpiAccounts().

razorpay.upiTurbo?.manageUpiAccounts("9999999999",
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*/}
})

Set UPI PIN with UI

Allow Razorpay SDK to handle linked UPI accounts within your application by triggering setUpiPinWithUI().

razorpay.upiTurbo?.setUpiPinWithUI(accountsWithPinNotSet[0],
object: UpiTurboSetPinResultListener {
override fun onSuccess(upiAccount: UpiAccount) {
// Continue payment
}
override fun onError(error: Error) {
// Show error
}
}
)

  1. The below function is triggered internally after integrating with the Razorpay Android Custom SDK.

    import com.razorpay.Razorpay
    Razorpay razorpay = new Razorpay(activity);
  2. The .onBackPressed() is triggered when a customer tries to exit the app or return to the previous page. The razorpay.upiTurbo.destroy() function clears that particular session. Therefore, when the customer returns, the payment process starts from the beginning.

    override fun onBackPressed() {
    razorpay.onBackPressed()
    razorpay.upiTurbo.destroy()
    super.onBackPressed()
    }

The SDKs given below provide access to exposed models for seamless integration.

UpiAccount

MethodReturn TypeDescription
accountNumberStringReturns masked bank account number.
getAccountTypeStringThe account type. Possible values are savings and current .
ifscStringReturns IFSC for Bank.
bankNameStringReturns name of bank.
bankLogoUrlStringReturns URL to the logo of the PNG image.
bankPlaceholderUrlStringImage URL for bank logo placeholder.
pinLengthIntegerLength on UPI PIN.

Error

ErrorDescription
errorCodeTypes of error codes
  • BAD_REQUEST_ERROR: Failure from the client's end (SDK).
  • GATEWAY_ERROR: Failure either from the Secure Component or the Bank.
  • SERVER_ERROR: Failure at PSP.
errorDescriptionBrief description of the error.
errorReasonSpecifies the specific reason for the error.
errorSourceIndicates the origin of the error.
errorStepHighlights the stage where the error occurred.

[This is the latest version of the list and was last updated on February 27th, 2024]

BankAccount

MethodReturn TypeDescription
accountNumberStringMasked account number.
typeStringThe account type. Possible values are savings and current .
ifscStringReturns IFSC for Bank.
stateBankAccountStateThe current state of account.

BankAccountState

Enum InstancesDescription
UPI_PIN_NOT_SETThis is the state of the bank account when the UPI pin is not set.
UPI_PIN_SETThis is the state of the bank account when the UPI pin is set.
LINKING_IN_PROGRESSThis is the state of the bank account when account linking is in progress.
LINKING_SUCCESSThis is the state of the bank account when the account is linked successfully.
LINKING_FAILEDThis is the state of the bank account when the account linking is failed.

Bank

MethodReturn TypeDescription
ifscStringIFSC of bank.
nameStringName of bank.
getImageURL()StringImage URL of bank logo.
bankPlaceholderUrlStringImage URL for bank logo placeholder.

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 whitelisted by Razorpay to test on prod.

    Handy Tips

    Contact our

    to get your mobile number and app whitelisted.

  • Import the prod library from the Github repository → https://github.com/upi-turbo/android-turbo-sample-app/tree/prod/app/libs prod branch.

  • 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?