3.2 Initiate Payment - Element Checkout flow

Cashfree payment gateway's iOS SDK (supports iOS 11 and above) provides a way for users who want to implement the payment screen as per their requirement and then use our SDK to process the payment.

Customer selects the payment mode and enters payment details inside the merchant's application. These details are then passed on to the our iOS SDK for processing.

1198

Element Checkout flow

📘

Here you can find the sample application demonstrating the usage of this SDK

Initiate the payment by following these steps

  1. Create a CFSession object.
  2. Create a payment mode object (CFCard, CFWallet, CFUPI, etc.) for the selected payment mode and setup the callbacks.
  3. Create the payment object (CFCardPayment, CFWalletPayment, etc.) for the selected payment mode.
  4. Set payment callback.
  5. Initiate the payment using the payment object created from [step 3]

Create a session

📘

We have released our latest version 2022-09-01 to make our integration more secure for merchants and customers to use. In the this latest version, we have revamped the integration method for using our Drop and Element SDK.

Previous Implementation of creating session with "order_token" (setOrderToken) is deprecated and is replaced by "payment_session_id" (setPaymentSessionId).

As discussed above, the payment_session_id contains all the order details and is used to authenticate the payment. The SDK exposes a class CFSession which has member variables for a payment session. One of them sets the payment_session_id value.

Cashfree provides the following two environments for our merchants

  1. Sandbox environment for developers to test the payment flow and responses
  2. Production environment for live transactions.

The values for environment field can be either .SANDBOX or .PRODUCTION.

Code Snippet

do {
     let cfSession = try CFSession.CFSessionBuilder()
                .setEnvironment(.SANDBOX)
                .setPaymentSessionId("payment_session_id")
                .setOrderId("order_Id")
                .build()
   } catch let e {
     let error = e as! CashfreeError
     print(error.localizedDescription)
   }

Create a payment mode object and setup the callbacks

Our iOS SDK provides multiple modes to make payment. You can choose any mode depending on the requirement and invoke that payment mode from the SDK.

The following payment modes are supported by the iOS SDK:-

  1. Card
  2. Netbanking
  3. UPI Collect
  4. UPI Intent
  5. Wallet
  6. EMI
  7. Paylater

Create a Card Object

  • A card object has to be created by sending all the required details i.e., Card Holder Name, Card Number, Card CVV and more
  • The SDK exposes a class CFCard that collects these details.
  • The below code snippet creates an object of CFCard
do {
        let card = try CFCard.CFCardBuilder()
            .setCardNumber("1234123412341234")// Valid card number
            .setCardHolderName("Suhas")
            .setCardExpiryYear("25") // in YY format
            .setCardExpiryMonth("12")// in MM format
            .setCVV("123")
            .build()

    } catch let e {
        let error = e as! CashfreeError
        print(error.localizedDescription)
    }

Create a Netbanking Object

  • A Netbanking object has to be created by sending all the required details i.e., Bank Code
  • The SDK exposes a class CFNetbanking that collects these details.
  • The below code snippet creates an object of CFNetbanking
do {
  let netbanking = try CFNetbanking.CFNetbankingBuilder()
 	 	.setBankCode(3003)
  	.build()
} catch let e {
  	let error = e as! CashfreeError
  	print(error.localizedDescription)
}

📘

Visit to get a list of all the bank codes.

Create a Wallet Object

  • A Wallet object has to be created by sending all the required details i.e., provider name, phone number
  • The SDK exposes a class CFWallet that collects these details.
do {
            let wallet = try CFWallet.CFWalletBuilder()
                .setProvider("phonepe")
                .setPhone("99999999")
                .build()
        } catch let e {
            let error = e as! CashfreeError
            print(error.localizedDescription)
       }

Note: Below is the list of all values for all the wallet providers supported by Cashfree:-

  1. phonepe
  2. paytm
  3. amazon
  4. airtel
  5. freecharge
  6. mobikwik
  7. jio
  8. ola

Create a UPI Object

  • A UPI object has to be created by sending all the required details i.e., channel and UPI ID
  • The SDK exposes a class CFUPI that collects these details.
  • Cashfree provides 2 modes of payment with UPI. One being the collect flow and the other being the intent flow.
  • In the collect flow, the user has to enter his/her UPI ID and a request will be sent to that UPI ID to complete the payment.
  • In the intent flow, the user has to be presented with a list of all installed UPI applications present in the phone. Clicking on one of them, the user will be redirected to the application to complete the payment
  • Depending on the requirement, you can choose to use any.

The code snippet for CFUPICollect object.

do {
            let cfUPI = try CFUPI.CFUPIBuilder()
                .setChannel(.COLLECT)
                .setUPIID("test@gocashfree")
                .build()
        } catch let e {
            let error = e as! CashfreeError
            print(error.localizedDescription)
       }

Pre-requisite for UPI Intent

  • The SDK exposes a util class CFUPIUtils which consists of a method getInstalledUPIApplications() that returns a list of all the installed UPI applications in the user's phone.
  • Add the following permission to info.plist
<key>LSApplicationCategoryType</key>
<string></string>
<key>LSApplicationQueriesSchemes</key>
<array>
  <string>bhim</string>
  <string>paytm</string>
  <string>phonepe</string>
  <string>tez</string>
</array>
let upiApplications = CFUPIUtils().getInstalledUPIApplications() // Returns an array ([[String: String]])

The below code snippet creates an object of CFUPI intent

do {
            let cfUPI = try CFUPI.CFUPIBuilder()
                .setChannel(.INTENT)
                .setUPIID("id") // Here you have to send the "id" of the app that was clicked from the list that you received earlier
                .build()
        } catch let e {
            let error = e as! CashfreeError
            print(error.localizedDescription)
       }

Create a EMICard Object

  • An EMI card object has to be created by sending all the required details i.e., Card Holder Name, Card Number, Card CVV, EMI tenure and more
  • The SDK exposes a class CFEMICard that collects these details.
  • The below code snippet creates an object of CFEMICard
do {
        let card = try CFEMICard.CFEMICardBuilder()
            .setCardNumber("1234123412341234")
            .setCardHolderName("Suhas")
            .setCardExpiryYear("25")
            .setCardExpiryMonth("12")
            .setCVV("123")
            .setEMITenure(3)
            .setBankName("ICICI")
            .build()
    } catch let e {
        let error = e as! CashfreeError
        print(error.localizedDescription)
    }
AttributeSupported values
BankNameHolds Bank Name for the corresponding card. Values can be HDFC ICICI Kotak RBL BOB Standard Chartered
EMITenureHolds Tenure for the EMI payment.
Values are:
HDFC: 3 6 9 12
ICICI: 3 6 9 12
Kotak: 3 6 9 12 18 20 24 30 36
RBL: 3 6 9 12 18 24
BOB: 3 6 9 12 18 24 36
Standard Chartered: 3 6 9 12

Create a Paylater Object

  • A Paylater object has to be created by sending all the required details i.e., provider name, phone number
  • The SDK exposes a class CFPaylater that collects these details.
  • The below code snippet creates an object of CFPaylater
do {
            let payLater = try CFPaylater.CFPaylaterBuilder()
                .setProvider("lazypay")
                .setPhone("99999999")
                .build()
        } catch let e {
            let error = e as! CashfreeError
            print(error.localizedDescription)
       }

Create the payment object

1. CFCardPayment

  • Code Snippet to create a payment object for card
do {
        let cardPaymentObject = try CFCardPayment.CFCardPaymentBuilder()
                .setSession(cfSession)
                .setCard(card)
                .build()
    } catch let e {
      let error = e as! CashfreeError
      print(error.localizedDescription)
    }

2. CFNetbankingPayment

  • Code Snippet to create a payment object for netbanking
do {
        let netbankingPaymentObject = try CFNetbankingPayment.CFNetbankingPaymentBuilder()
                .setSession(cfSession)
                .setNetbanking(netbanking)
                .build()
    } catch let e {
      let error = e as! CashfreeError
      print(error.localizedDescription)
    }

3. CFWalletPayment

  • Code Snippet to create a payment object for wallet
do {
        let cfWalletPaymentObject = try CFWalletPayment.CFWalletPaymentBuilder()
                .setSession(cfSession)
                .setWallet(wallet)
                .build()
    } catch let e {
      let error = e as! CashfreeError
      print(error.localizedDescription)
    }

4. CFUPIPayment

  • Code Snippet to create a payment object for UPI
do {
        let cfUPIPaymentObject = try CFUPIPayment.CFUPIPaymentBuilder()
                .setSession(cfSession)
                .setUPI(cfUPI)
                .build()
    } catch let e {
      let error = e as! CashfreeError
      print(error.localizedDescription)
    }

5. CFEMICardPayment

  • Code Snippet to create a payment object for EMI
do {
        let cardPaymentObject = try CFEMICardPayment.CFEMICardPaymentBuilder()
                .setSession(cfSession)
                .setCard(emiCard)
                .build()
    } catch let e {
      let error = e as! CashfreeError
      print(error.localizedDescription)
    }

6. CFPaylaterPayment

  • Code Snippet to create a payment object for card
do {
        let payLaterPaymentObject = try CFPaylaterPayment.CFPaylaterPaymentBuilder()
                .setSession(cfSession)
                .setPaylater(payLaterPaymentObject)
                .build()
    } catch let e {
      let error = e as! CashfreeError
      print(error.localizedDescription)
    }

Setup payment callback

The SDK exposes a protocol CFResponseDelegate which the class has to conform to. It comes with 2 functions; one of them informs the user to verify the payment and the other informs the user that there was an error while trying to make payment.

  1. @objc func onError(_ error: CFErrorResponse, order_id: String)
  2. @objc func verifyPayment(order_id: String)
  • Code snippet demonstrating it's usage:
// MARK: - CALLBACK
class YourViewController: CFResponseDelegate {
    
    func onError(_ error: CFErrorResponse, order_id: String) {
        print(error.message)
    }
    
    func verifyPayment(order_id: String) {
        print(order_id)
    }
    
}

Initiate payment

  • Finally to initiate the payment, the above created Payment Object has to be sent to the SDK.
  • The SDK exposes a class CFPaymentGatewayService, which can be used to set the Payment Object and initiate the payment.
  • The below code snippet is an example demonstrating it's usage:
let gatewayService = CFPaymentGatewayService.getInstance()

override func viewDidLoad() {
  // We recommend that the callback be set separately in the viewDidLoad as well
  gatewayService.setCallback(self) // Callback -> CFResponseDelegate
}



do {
   gatewayService.setCallback(self)
   try gatewayService.doPayment(payment: cardPaymentObject)
} catch let e {
  let error = e as! CashfreeError
  print(error.localizedDescription)
}

Note: In the doPayment(), you can send the payment object of any of the above created payment mode (CFCardPayment, CFNetbankingPayment, CFWalletPayment, CFUPIPayment, CFEMIPayment, CFPaylaterPayment)

Sample Code

import Foundation
import UIKit
import CashfreePGCoreSDK
import CashfreePG

class YourViewController: UIViewController {
    
    private let cfPaymentGatewayService = CFPaymentGatewayService.getInstance()
    
    override func viewDidLoad() {
        self.cfPaymentGatewayService.setCallback(self)
    }
    
    
    private func getSession() -> CFSession? {
        do {
            let session = try CFSession.CFSessionBuilder()
                .setEnvironment(.SANDBOX)
                .setOrderID("order_id")
                .setOrderToken("orderToken")
                .build()
            return session
        } catch let e {
            let error = e as! CashfreeError
            print(error.localizedDescription)
            // Handle errors here
        }
        return nil
    }
    
    @IBAction func cardPayTapped(_ sender: Any) {
        // Get Session
        if let session = self.getSession() {
            do {
                
                // CFCard
                let card = try CFCard.CFCardBuilder()
                    .setCVV("123")
                    .setCardNumber("4111111111111111")
                    .setCardExpiryYear("22") // in YY format
                    .setCardExpiryMonth("12")
                    .setCardHolderName("Cashfree")
                    .build()
                
                // CFCardPayment
                let cardPayment = try CFCardPayment.CFCardPaymentBuilder()
                    .setCard(card)
                    .setSession(session)
                    .build()
                
                // Initiate SDK Payment
                try self.cfPaymentGatewayService.doPayment(cardPayment, viewController: self)
            } catch let e {
                let error = e as! CashfreeError
                print(error.localizedDescription)
                // Handle errors here
            }
        }
    }
    
    @IBAction func emiCardPayTapped(_ sender: Any) {
        // Get Session
        if let session = self.getSession() {
            do {
                
                // CFEMICard
                let card = try CFEMICard.CFEMICardBuilder()
                    .setCVV("123")
                    .setCardNumber("4111111111111111")
                    .setCardExpiryYear("22") // in YY format
                    .setCardExpiryMonth("12")
                    .setCardHolderName("Cashfree")
                    .setEMITenure(3)
                    .setBankName("icici")
                    .build()
                
                // CFEMICardPayment
                let emiCardPayment = try CFEMICardPayment.CFEMICardPaymentBuilder()
                    .setCard(card)
                    .setSession(session)
                    .build()
                
                // Initiate SDK Payment
                try self.cfPaymentGatewayService.doPayment(emiCardPayment, viewController: self)
            } catch let e {
                let error = e as! CashfreeError
                print(error.localizedDescription)
                // Handle errors here
            }
        }
    }
    
    @IBAction func upiCollectPayTapped(_ sender: Any) {
        // Get Session
        if let session = self.getSession() {
            do {
                
                // CFUPI
                let upiCollect = try CFUPI.CFUPIBuilder()
                    .setChannel(.COLLECT)
                    .setUPIID("testsuccess@gocash")
                    .build()
                
                // CFUPIPayment
                let upiPayment = try CFUPIPayment.CFUPIPaymentBuilder()
                    .setUPI(upiCollect)
                    .setSession(session)
                    .build()
                
                // Initiate SDK Payment
                try self.cfPaymentGatewayService.doPayment(upiPayment, viewController: self)
            } catch let e {
                let error = e as! CashfreeError
                print(error.localizedDescription)
                // Handle errors here
            }
        }
    }
    
    @IBAction func upiIntentPayTapped(_ sender: Any) {
        let installedApps = CFUPIUtils().getInstalledUPIApplications()
        // Get Session
        if let session = self.getSession() {
            do {
                
                // CFUPI
                let upiIntent = try CFUPI.CFUPIBuilder()
                    .setChannel(.INTENT)
                    .setUPIID(installedApps[0]["id"] ?? "") // Using first index. (App should be shown to user based on the list and clicked app's "id" has to be sent here
                    .build()
                
                // CFUPIPayment
                let upiPayment = try CFUPIPayment.CFUPIPaymentBuilder()
                    .setUPI(upiIntent)
                    .setSession(session)
                    .build()
                
                // Initiate SDK Payment
                try self.cfPaymentGatewayService.doPayment(upiPayment, viewController: self)
            } catch let e {
                let error = e as! CashfreeError
                print(error.localizedDescription)
                // Handle errors here
            }
        }
    }
    
    @IBAction func walletPayTapped(_ sender: Any) {
        // Get Session
        if let session = self.getSession() {
            do {
                
                // CFWallet
                let wallet = try CFWallet.CFWalletBuilder()
                    .setProvider("phonepe")
                    .setPhone("9999999999")
                    .build()
                
                // CFWalletPayment
                let walletPayment = try CFWalletPayment.CFWalletPaymentBuilder()
                    .setWallet(wallet)
                    .setSession(session)
                    .build()
                
                // Initiate SDK Payment
                try self.cfPaymentGatewayService.doPayment(walletPayment, viewController: self)
            } catch let e {
                let error = e as! CashfreeError
                print(error.localizedDescription)
                // Handle errors here
            }
        }
    }
    
    @IBAction func netBankingPayTapped(_ sender: Any) {
        // Get Session
        if let session = self.getSession() {
            do {
                
                // CFNetbanking
                let nb = try CFNetbanking.CFNetbankingBuilder()
                    .setBankCode(3003)
                    .build()
                
                // CFNetbankingPayment
                let nbPayment = try CFNetbankingPayment.CFNetbankingPaymentBuilder()
                    .setNetbanking(nb)
                    .setSession(session)
                    .build()
                
                // Initiate SDK Payment
                try self.cfPaymentGatewayService.doPayment(nbPayment, viewController: self)
            } catch let e {
                let error = e as! CashfreeError
                print(error.localizedDescription)
                // Handle errors here
            }
        }
    }
    
    @IBAction func paylaterPayTapped(_ sender: Any) {
        // Get Session
        if let session = self.getSession() {
            do {
                
                // CFPayLater
                let payLater = try CFPaylater.CFPaylaterBuilder()
                    .setPhone("9999999999")
                    .setProvider("lazypay")
                    .build()
                
                // CFPaylaterPayment
                let payLaterPayment = try CFPaylaterPayment.CFPaylaterPaymentBuilder()
                    .setPaylater(payLater)
                    .setSession(session)
                    .build()
                
                // Initiate SDK Payment
                try self.cfPaymentGatewayService.doPayment(payLaterPayment, viewController: self)
            } catch let e {
                let error = e as! CashfreeError
                print(error.localizedDescription)
                // Handle errors here
            }
        }
    }
    
}

// MARK: - CALLBACK
extension YourViewController: CFResponseDelegate {
    
    func onError(_ error: CFErrorResponse, order_id: String) {
        print(error.message)
    }
    
    func verifyPayment(order_id: String) {
        print(order_id)
    }
    
}

What’s Next