API Reference
Log In

iOS SDK Custom UI

Instamojo SDK Custom UI Documentation

Table of Contents

Using Custom Created UI

This document assumes that you have finished the basic SDK integration in your application. If you haven't done it yet, please refer to this Documention
####Note: Please contact a qualified security assessor to determine your PCI-DSS incidence and liability if you’re implementing a custom interface that collects cardholder information.

If you choose to create your own UI to collect Payment information, SDK has necessary APIs to achieve this.
Use PaymentOptions, which uses SDK APIs to collect Payment Information, to extend and modify as per your needs.
You can change the name of the controller and the Storyboard ID to anything you like.

Changing the Caller method

Replace Instamojo.invokePaymentOptionsView(order : order) method with the following one.

let paymentOptions = self.storyboard?.instantiateViewController(withIdentifier: "paymentOptions") as! PaymentOptions
paymentOptions.order = order
self.navigationController?.pushViewController(paymentOptions, animated: true)

Collecting Card Details

Validating Card Option

Always validate whether the current order has card payment enabled.

if order.cardOptions == nil {
   //seems like card payment is not enabled. Make the necessary UI Changes.
} else{
   // Card payment is enabled.
}

Creating and validating Card deatils

Once the user has typed in all the card details and ready to proceed, you can create the Card object.

let card = Card.init(cardHolderName: self.cardHolderNameTextField.text!, cardNumber: self.cardNumberTextField.text!, date: self.expiryDateTextField.text!, cvv: self.cvvTextField.text!, savedCard: false)

//Validate the card now
if !card.isValidCard() {
      if !card.isValidCardHolderName() {
          //Invalid Card Holder Name
      }     
      if !card.isValidCardNumber() {
          //Invalid Card Number
      }   
      if !card.isValidDate() {
          //Invalid Card Expiry Date
       }     
       if !card.isValidCVV() {
            //Invalid Card CVV
       }
 }else{
       // Valid Card 
  }
}

Generating Juspay Browser Params using Card

Once the card details are validated, You need to generate JusPay BrowserParams with the card details given. Add JuspayRequestCallBack protocol to your view controller

//Good time to show progress dialog while the browser params is generated
let request = Request(order: self.order, card: card, jusPayRequestCallBack: self)
request.execute()

//Call back recieved from juspay request to instamojo
func onFinish(params: BrowserParams, error: String ) {
    if error.isEmpty {
        DispatchQueue.main.async {
            //Hide spinner
            Instamojo.makePayment(params: params)
        }
    }else{
       DispatchQueue.main.async {
           // Hide Spinner
           //There seems to be some problem. Please choose a different payment options
       }
   }
}

Collecting Netbanking Details

Validating Netbanking Option

Similar to Card Options, Netbanking options might be disabled. Check Netbanking Options for nil

if order.netBankingOptions == nil {
   //seems like the Netbanking option is not enabled. Make the necessary UI Changes.
} else{
   // Netbanking is enabled.
}

Displaying available Banks

The Bank and its code set can be fetched from order itself.

order.netBankingOption.banks

The above code snippet will return a [NetBankingBanks]
Use an list view to display the available banks and collect the bank code of the bank user selects.

Generating Juspay Browser Params using bank code

Once the bank code is collected, You can generate the Juspay Browser Params using the following snippet.

//User selected a Bank. Hence proceed to Juspay
let bank = netBanks[indexPath.row] as NetBankingBanks
let submissionURL = order.netBankingOptions.url
let postData = order.netBankingOptions.getPostData(accessToken: order.authToken!, bankCode: bank.bankCode)
let browserParams = BrowserParams()
browserParams.url = submissionURL
browserParams.postData = postData
browserParams.clientId = order.clientID
browserParams.endUrlRegexes = Urls.getEndUrlRegex()

//Pass the Browser Params to start payment view controller
Instamojo.makePayment(params: browserParams)

Collecting EMI Details

Validating EMI Options

Similar to Card Options, EMI options might be disabled. Check EMI Options for nil.

if order.emiOptions == nil {
   //seems like EMI option is not enabled. Make the necessary UI Changes.
} else{
   // EMI is enabled.
}

Displaying available EMI Options

For EMI, the user should be given an option to choose his/her Credit Card Bank.
The list of Banks enabled for EMI can be fetched as [EMIBank] using the following code snippet.

let banks = order.emiOptions.emiBanks as [EMIBank]

Each EMIBank has following fields

  1. Bank Name
  2. Bank Code
  3. List of rate and tenure

We recommend using a ListView to show the List of EMIBanks available.

Once the user chooses a Bank from the list, you would need to present the user with available tenure options and the interest rate for each tenure.

To fetch the tenure and tenure's interest rate, please use the following code snippet.

let rates = selectedBank.rate

The result will fetch you [(key: Int, value: Int)] with key = tenure and value = interest rate.
The map is sorted in ascending order wrt key ie.. tenure.
We recommend you to use a ListView to show the tenure and its interest rate to the user.

Updating Order and Collecting Card Details

Once the user choose a tenure, please set the selected bankCode and tenure in order.

self.order.emiOptions.selectedTenure = tenure
self.order.emiOptions.selectedBankCode = selectedBank.bankCode

From this point, the further steps will be same as normal Card payment.
SDK will take the EMI details from the order while generating Browser Params for Juspay.

Collecting Wallet details

Validating Wallet Options

Similar to Card Options, Wallet options might be disabled. Check Wallet Options for nil.

if order.walletOptions == nil {
   //seems like Wallet option is not enabled. Make the necessary UI Changes.
} else{
   // Wallet is enabled.
}

Displaying available Wallets

Enabled Wallets can be fetched from the order as a [Wallet].

let wallets = order.walletOptions.wallets as [Wallet]

Each Wallet object has three fields namely

  1. Wallet Name
  2. Wallet ID
  3. Wallet Image URL

We recommend using a ListView to show the list of Wallets.

Generating Juspay Browser Params using Wallet ID

Once the user chooses a Wallet to proceed, Browser params should be generated with the selected Wallet ID.
Generate the browser params using the follwing code snippet

let wallet = wallets[indexPath.row] as Wallet
let walletID = wallet.walletID
let submissionURL = order.walletOptions.url
let postData = order.walletOptions.getPostData(accessToken: order.authToken!, walletID: walletID)
let browserParams = BrowserParams()
browserParams.url = submissionURL
browserParams.clientId = order.clientID
browserParams.postData = postData
browserParams.endUrlRegexes = Urls.getEndUrlRegex()

//Pass the Browser Params to start payment view controller
Instamojo.makePayment(params: browserParams)

Passing the result back to main view controller

Add the following code snippet in root view controller.

override func viewDidLoad() {
     addNotificationToRecievePaymentCompletion()
}

func addNotificationToRecievePaymentCompletion(){
     NotificationCenter.default.addObserver(self, selector: #selector(self.paymentCompletionCallBack), name: NSNotification.Name("INSTAMOJO"), object: nil)
}
    
func paymentCompletionCallBack() {
     if UserDefaults.standard.value(forKey: "USER-CANCELLED") != nil {
         //Transaction cancelled by user, back button was pressed
     }
     if UserDefaults.standard.value(forKey: "ON-REDIRECT-URL") != nil {
          // Check the payment status with the transaction_id
     }
     if UserDefaults.standard.value(forKey: "USER-CANCELLED-ON-VERIFY") != nil {
          //Transaction cancelled by user when trying to verify UPI payment
     }
}

Collecting UPI details

Validating UPI options

Similar to Card Options, UPI options might be disabled. Check UPI Options for nil.

if order.upiOptions == nil {
   //seems like UPI option is not enabled. Make the necessary UI Changes.
} else{
   // UPI is enabled.
}

Initiating collect request to user's VPA

Using an UITextField, collect the VPA of the user. The collect request will be sent to this VPA.
Once collected, use the below code snippet to initiate the collect request. Extend UPICallBack protocol to your view controller.

let request = Request.init(order: self.order, virtualPaymentAddress: virturalPaymentAddress!, upiCallBack: self)
request.execute()

func onSubmission(upiSubmissionResponse: UPISubmissionResponse, exception: String) {
DispatchQueue.main.async {
       // Hide Spinner
       if !exception.isEmpty && upiSubmissionResponse.statusCode != Constants.PendingPayment {
                self.showAlert(title: "Payment Response", errorMessage: exception)
        } else {
                self.checkForStatusTransaction()
        }
    }
}

func checkForStatusTransaction() {
     // Show Spinner
     let request = Request.init(order: self.order, upiSubmissionResponse: self.upiSubmissionResponse, upiCallback: self)
     request.execute()
}

func onStatusCheckComplete(paymentComplete: Bool, status: Int) {
      DispatchQueue.main.async {
           //Hide Spinner
            if status == Constants.FailedPayment {
                 //Payment Cancelled//
            } else if status == Constants.PendingPayment {
                DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
                    if self.continueCheck {
                        // check transaction status 2 seconds later
                        self.checkForStatusTransaction()
                    }
                }
            } else if status == Constants.PaymentError {
                //Error while making UPI Status Check request
            } else {
              // Payment Completed
            }
        }
}

Using Custom Spinner

A spinner that includes text and activity Indictor is bundled with Instamojo which can be used if required.

Initialise

let spinner = Spinner(text : "Please Wait..")
spinner.hide()
self.view.addSubview(spinner)

Show

spinner.show()

Hide

spinner.hide()

Using Custom Expiry Date Picker

A custom date picker with month and year is bundled with Instamojo which can be used if required.

Setup

Step 1 : Add a Picker View to your view controller in Storyboard
Step 2 : Change the class of Picker View to MonthYearPickerView in the Identity Inspector
Step 3 : Reference outlet the MonthYearPickerView to your view controller
Step 4 : To the UITextField you want to extend the MonthYearPickerView add the following snippet

expiryDateTextField.inputView = expiryPickerView
expiryPickerView.removeFromSuperview()
expiryPickerView.onDateSelected = { (month: Int, year: Int) in
   let date = String(format: Constants.DateFormat, month, year)
   self.expiryDateTextField.text = date
}