Integrate Turbo UPI Headless

Steps to integrate the Razorpay Turbo UPI Headless SDK with your app.


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

Prerequisites

  1. Contact our

    to get your mobile number, app, and GitHub account whitelisted to get access to the https://github.com/upi-turbo/ios-sample-app - sample app repository. In this repository, you will find the framework files (libraries for Turbo) and the sample app source code to help you with the integration. Use branch custom_ui/turbo to access the sample app and frameworks for Turbo UPI. The sample app workspace is divided into Prod and UAT environment targets with separate pod dependencies.

  2. Integrate with

    .

  3. Add the below line of code to your Podfile to install Turbo pods:

    pod 'razorpay-customui-pod'
    pod 'razorpay-turbo-pod'
  4. Import the Turbo plugin as given below:

    import Razorpay
    import TurboUpiPlugin

Watch Out!

  • The minimum supported iOS version for using Turbo UPI is currently 11.0.
  • Use the rzp_test_0wFRWIZnH65uny API key id for testing on the UAT environment and the for prod testing.

Follow these steps:

  1. Initialise the SDK and set up the Checkout instance (Razorpay) to handle payment outcomes like success and errors by listening to delegate methods.

    var razorpay = RazorpayCheckout.initWithKey("rzp_test_0wFRWIZnH65uny",
    andDelegate: self,
    withPaymentWebView: wkWebView,
    plugin: RazorpayTurboUPI.pluginInstance())
  2. You need to link the customer’s UPI account with your app. Use the code samples given below to fetch the UPI account.

    Watch Out!

    If the device binding is not completed and getLinkedUpiAccounts is triggered, it will return an OnError with a DEVICE_BINDING_INCOMPLETE error message.

    • Get the customer's linked UpiAccount list using the below code. 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?.getLinkedUpiAccounts("<mobile_num>", resultDelegate: self)

      Request Parameters

      mobile_num

      string The customer's mobile number.

      Delegate

      object The Delegate to be sent is of type UpiTurboResultDelegate.

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

      extension ViewController: UPITurboResultDelegate {
      func onSuccessFetchingLinkedAcc(_ accList: [UpiAccount]) {
      if accList.count > 0 {
      print("Success Fetching Accounts")
      } else {
      // call linkNewUpiAccount()
      }
      }
      func onErrorFetchingLinkedAcc(_ error: TurboUpiPlugin.TurboError?) {
      print("Error: \(error?.errorDescription)")
      print("Error code: \(error?.errorCode)")
      }
      }

    Response Parameters

    onSuccess

    This function is triggered if the list is fetched successfully. accList can be empty to indicate that no accounts have been linked yet.

    onError

    This function is triggered in case an error is thrown during the retrieval process, either by the Razorpay SDK or the Bank SDK.

  3. If the customer has not linked any UPI account, 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.

    self.razorpay?.upiTurbo?.linkNewUpiAccount("<mobile_num>", linkActionDelegate: self)

    Request Parameters

    mobileNumber

    mandatory

    string Customer's mobile number needed to initialise the SDKs.

    linkActionDelegate

    UpiTurboLinkAccountDelegate Used as a callback to send a response or failure to you. Given below are the functions:

    • action.code: This function denotes that the user registration is incomplete and additional action is required.
    • action.data: This function denotes that the user has registered UpiAccounts on the device. It returns a list of UpiAccount objects, which can then be used to show the details on UI.
    • action.error: Returns an error object with a description and message relating to a failure in either one of the registration steps or in retrieving the UpiAccount list.

    • Link the customer's new UPI account using the below code:

      extension ViewController: UpiTurboLinkAccountDelegate {
      func onResponse(_ action: LinkUpiAction) {
      switch action.code {
      case .sendSms:
      guard action.error == nil else {
      return
      }
      action.registerDevice()
      case .selectBank:
      guard action.error == nil else {
      return
      }
      if let banks = action.data as? [UpiBank] {
      let selectedBank = banks[0]
      action.selectedBank(selectedBank)
      }
      case .selectBankAccount:
      guard action.error == nil else {
      return
      }
      if let bankAccounts = action.data as? [UpiBankAccount] {
      let bankAccount = bankAccounts[0]
      action.selectedBankAccount(bankAccount)
      }
      case .setUpiPin:
      let card = UpiCard("last6Digits", "expiry", "cvv")
      action.setUpiPin(bankAccount, card)
      case .linkAccountResponse:
      guard action.error == nil else {
      return
      }
      if let banks = action.data as? [UpiAccount] {
      //save the upi account response
      }
      default: break
      }
      }
      }

      action

      The current state of customer registration with which you can call further functions. All values for this variable are exposed as an enum for ease of integration. Know more about the

      .

  4. To accept payments, call Custom Checkout’s authorize method with the following payload:

    let payload: [String: AnyHashable] = [
    "currency": "INR",
    "amount": "700",
    "email": "gaurav.kumar@example.com",
    "contact": "9999999999",
    "method": "upi",
    "upi": [
    "flow": "in_app"
    ],
    "order_id": "order_L2MUBUOeFItcpU", //optional
    ]
    var turboPayload: [String: Any] = [:]
    turboPayload["upiAccount"] = upiAccount
    turboPayload["payload"] = payload
    razorpay?.authorize(turboPayload)

Request Parameters

amount

mandatory

integer The transaction amount expressed in the currency subunit. For example, for an actual amount of ₹299.35, the value of this field should be 29935.

currency

mandatory

string The currency in which the transaction should be made.

email

mandatory

string Email address of the customer.

contact

mandatory

string Customer's phone number.

order_id

optional

string Order id generated via the

.

method

mandatory

string The payment method used by the customer on Checkout. In this case, it is upi (default).

upi

mandatory

array Details of the UPI payment.

flow

string Type of the UPI method. In this case, it is in_app.

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

Fetch Balance

Fetch the customer's account balance. Call getBalance() on the bank account object received from upiAccount.

razorpay?.upiTurbo?.fetchAccountBalance(upiAccount: upiAccount) { (accountBalance, error) in
if error == nil {
//error
} else if let accountBalance = accountBalance {
//success
print(accountBalance.balance)
}
}

Change UPI PIN

Provide the customer the ability to change their UPI PIN. Call changeUpiPin() on the bank account object received from upiAccount.

razorpay?.upiTurbo?.changeUpiPin(upiAccount: upiAccount) { (bankAccount, error) in
if error == nil {
//error
} else if let account = bankAccount {
//success
print(UPI Pin Updated)
}
}

Reset UPI PIN

Let your customers reset their UPI PIN. Call resetUpiPin() on the bank account object received from getLinkedUpiAccounts().

razorpay?.upiTurbo?.resetUpiPin(upiAccount: upiAccount, card: cardObj) { (bankAcount, error) in
if error == nil {
//error
} else if let account = bankAccount {
//success
}
}

Let your customers delink their UpiAccounts.

To get the device binding status, please use the variable razorpay.upiTurbo.deviceBindingDone of type boolean. It indicates whether the device binding, which is a prerequisite for adding UPI accounts, is done with the user's mobile number.

if self.razorpay?.upiTurbo?.deviceBindingDone {
// Device Binded
} else {
// Call Link New Account for Device Binding
}

Action Parameter Values

Following are the constants that are passed in action.code parameter in onResponse.

NameDescriptionNext function
sendSmsSIM details are fetched from the device to show to the user to begin the registration process.action.fetchAllBanks
selectBankObject AllBanks returned by SDK for user selection with
  • popularBanks
  • allBanks
action.selectedBank(bank)
selectBankAccountList of accounts related to the user in selected bank.action.selectedBankAccount(bankAccount)
setUpiPinTriggered in the event UPI Pin is not set for a selected bank account.action.setUpiPin(Card)
linkAccountResponseTriggered if any errors occurred during the onboarding flow or on Onboard completion with UPI Accounts.NA

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

UpiBankAccount

MethodReturn TypeDescription
accountNumberStringMasked bank account number.
beneficiaryNameStringName of account holder.
bankStringThe bank code.

UpiAccountBalance

MethodReturn TypeDescription
balanceIntegerBalance amount in paise.
outstandingIntegerOutstanding balance for Credit accounts in paise.
currencyStringCurrency Type INR.
idStringBank Account id.

UpiAccount

MethodReturn TypeDescription
accountNumberStringReturns masked bank account number.
typeStringThe account type. Possible values are bank_account or credit_card .
ifscStringReturns IFSC for Bank.
bankNameStringReturns the name of the bank.
bankLogoUrlStringReturns the URL to the logo of the PNG image.
bankPlaceholderUrlStringImage URL for bank logo placeholder.

UpiCard

MethodReturn TypeDescription
expiryMonthStringExpiry month of the card.
expiryYearStringExpiry year of the card. The format is YY .
lastSixDigitsStringLast six digits of the card.

UpiBank

MethodReturn TypeDescription
ifscStringIFSC of the bank.
logoStringBank logo URL.
nameStringName of the bank.
bankPlaceholderUrlStringImage URL for bank logo placeholder.

AllBanks

MethodReturn TypeDescription
popularBanksArray<UpiBank>Returns the list of the top 8 banks.
banksArray<UpiBank>Returns a list of all banks.

TurboError

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. Possible values:
  • gateway
  • issuer_bank
  • beneficiary_bank
  • customer_psp
  • customer
  • internal
errorStepHighlights the stage where the error occurred.

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

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/ios-sample-app custom_ui/turbo branch.

  • Switch to Prod environment and podfile.

  • Replace the UAT credential with the

    for prod testing.


Is this integration guide useful?