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.
-
Contact our
to get your mobile number, app, and GitHub account whitelisted to get access to thehttps://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 branchcustom_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. -
Integrate with
. -
Add the below line of code to your
Podfile
to install Turbo pods:pod 'razorpay-customui-pod'pod 'razorpay-turbo-pod' -
Import the Turbo plugin as given below:
import Razorpayimport 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:
-
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()) -
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 anOnError
with aDEVICE_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("9000090000", resultDelegate: self) -
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)")}}
onSuccess
string
This function is triggered if the list is fetched successfully.accList
can be empty to indicate that no accounts have been linked yet.onError
string
This function is triggered in case an error is thrown during the retrieval process, either by the Razorpay SDK or the Bank SDK. -
-
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.
self.razorpay?.upiTurbo?.linkNewUpiAccount("9000090000", linkActionDelegate: self)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
.- Prefetch and Link multiple accounts together
Use the following code to prefetch and link multiple UPI accounts from popular banks. If you want to use your own prefetch banks, you can create a prefetch banks array and send it through thebanks
key of consent. 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?.setCustomerMobile(mobile: "<mobile_num>").prefetchAndLinkUpiAccounts(linkActionDelegate: self)extension CheckoutVC: UpiTurboLinkAccountDelegate {func onResponse(_ action: LinkUpiAction) {switch action.code {case .consent:guard action.error == nil else { return }if let prefetchBanks = action.data as? [UpiPrefetchBank] {let consent = Consent(acknowledge: true,consentMessage: "We will automatically fetch and link all your accounts with these top banks",timeStamp: String(Int(Date().timeIntervalSince1970)),type: .prefetchAndLink,data: ["banks": prefetchBanks])action.consents(consent: [consent])}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], !banks.isEmpty {let selectedBank = banks[0]action.selectedBank(selectedBank)}case .selectBankAccount:guard action.error == nil else { return }if let bankAccounts = action.data as? [UpiBankAccount], !bankAccounts.isEmpty {let bankAccount = bankAccounts[0]action.selectedBankAccount(bankAccount)}case .setUpiPin:let card = UpiCard(expMonth: "last6Digits", expYear: "expiry", lastSixDigits: "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} else if let allAccounts = action.data as? UpiAllAccounts {// Save the UPIAllAccounts responseif let account = allAccounts.accountsWithPinSet?.first as? UpiBankAccount {switch account.state {case .linkingInProgress:// Show account is linkingbreakcase .linkingFailed:// Show account linking failedbreakdefault:// Not possible in prefetch flowbreak}} else if let upiAccount = allAccounts.accountsWithPinSet?.first as? UpiAccount {// Continue payment}if let bankAccount = allAccounts.accountsWithPinNotSet?.first as? UpiBankAccount {// Display accountsWithPinNotSet in expandable section - with Set Pin buttonlet card = UpiCard(expMonth: "last6Digits", expYear: "expiry", lastSixDigits: "cvv")action.setUpiPin(bankAccount, card)}}default:break}}}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.
Watch Out!
If the merchant wants to use the prefetch feature, they need to specifically include a case for prefetch in their code's switch statement. If they do not need prefetching, they can just use a default case in the switch statement to handle all other situations.
- Link one UPI account at a time
-
The Reward feature allows you to allocate rewards to users without specific criteria. To avail rewards, you need to configure them from the dashboard. You can seamlessly integrate this function into your application, providing multiple entry points for users to check their rewards eligibility before completing a payment.
razorpay.upiTurbo?.getRewardForCustomer(mobileNumber: "9000090000",action: RewardAction.payment,amount: "10000"?,rewardsDelegate: self)extension ViewController: UpiTurboCustomerRewardsDelegate {func onSuccess(_ reward: CustomerReward) {}func onFailure(_ error: TurboError?) {}}mobileNumber
mandatory
string
The customer's mobile number.action
mandatory
RewardAction
This parameter specifies the action to check reward eligibility. Possible values:onboarding
: To check reward eligibility for Onboarding.payment
: To check reward eligibility for Payment.
amount
optional
string
The transaction amount expressed in the currency subunits.rewardsDelegate
mandatory
delegate
This parameter allows you to receive callbacks regarding reward eligibility. -
To process the payments, call the
authorize
method of custom checkout with the provided payload. Upon receiving thePaymentData
response, you will also receiverewardStatus
along with the payment response. Please note that therewardStatus
key will be present in the response only if your eligible for a reward.let turboPayload: [AnyHashable: Any] = ["currency": "INR","amount": "700","email": "gaurav.kumar@example.com","contact": "9000090000","method": "upi","upi": ["flow": "in_app"],"order_id": "order_L2MUBUOeFItcpU", //optional]turboPayload["upiAccount"] = upiAccountrazorpay?.authorize(turboPayload)extension ViewController: RazorpayPaymentCompletionProtocol {func onPaymentSuccess(_ payment_id: String, andData response: [AnyHashable: Any]) {let rewardStatus = response["rewardStatus"]// show payment success screen with reward if rewarded}func onPaymentError(_ code: Int32, description str: String, andData response: [AnyHashable: Any]){}}
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.
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 the customer's account balance. Call getBalance()
on the bank account object received from upiAccount.
razorpay?.upiTurbo?.fetchAccountBalance(upiAccount: upiAccount) { (accountBalance, error) inif error == nil {//error} else if let accountBalance = accountBalance {//successprint(accountBalance.balance)}}
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) inif error == nil {//error} else if let account = bankAccount {//successprint(“UPI Pin Updated”)}}
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) inif error == nil {//error} else if let account = bankAccount {//success}}
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}
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 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?