iOS SDK

Use our SDK to integrate the Cashfree Payment Gateway directly into your app for iOS versions 10.3 and above. CF SDK has been designed to offload the complexity of handling and integrating payments in your app.

Integration Steps

To integrate Cashfree iOS SDK with your iOS application,

  1. Initiate payment - Invoke a payment API from the Cashfree SDK with the token generated when the customer initiates payment for an order from your application. Cashfree SDK displays appropriate screens to the customer for the payment.

  2. Receive and handle response - Cashfree SDK returns the payment result for the order which should be handled in your application.

  3. Verify response - We recommend you to verify the payment response using webhooks and by checking the signature value returned in the payment response.

Step 1: Create Account and Get API Keys

  1. Go to Cashfree website and create an account. Click here for detailed steps on how to create and activate your account.

  2. Log in to your Merchant Dashboard using the same credentials.

  3. Click Payment Gateway section View Dashboard click Credentials. For security purposes, you need to enter your password for verification.

  4. Copy the app ID and the secret key. These values are required to create the order token from your server. Order tokens are used to authenticate the API calls made from Cashfree iOS SDK.

Step 2: Integrate SDK

Below are the latest iOS SDK download links:

ENABLE_BITCODE should be set to YES

Xcode Version

Swift Version

Supported Architectures

Framework Download Link

10.3

4.2

arm, armv7, arm64

Download Phone SDK

10.3

4.2

x86_64, i386

Download Simulator SDK

11.+

5+

All

Download Phone SDK

Set up your Project

Add Cashfree SDK

  1. Drag and drop the contents of zip file onto your Xcode project navigator. Select the checkbox for Copy items if needed. Click Finish.

  2. Then click the + button on Embedded Binaries under the General tab of your ios app project file.

  3. Select CFSDK.xcframework.

  4. Click Finish.

Click here for more information.

Step 3: Generate Token (From Backend)

The cftoken is used to authenticate the payment requests made from SDK. It has to be generated for every payment attempt made for an order. Pass this token to the SDK while initiating the payment for that order. For generating a cftoken you need to use our token generation API.

Request Description to Generate Token

Production: set the URL to https://api.cashfree.com/api/v2/cftoken/order

Testing: set the URL to https://test.cashfree.com/api/v2/cftoken/order

You need to send orderId, orderCurrency and orderAmount as a JSON object to the API endpoint and in response you will receive a token. Please see the description of the request below.

Token Request Description:

curl -XPOST -H 'Content-Type: application/json'
-H 'x-client-id: '
-H 'x-client-secret: '
-d '{
"orderId": "",
"orderAmount":,
"orderCurrency": "INR"
}' 'https://test.cashfree.com/api/v2/cftoken/order'

Token Request Example: Replace YOUR_APP_ID and YOUR_SECRET_KEY with actual values.

curl -XPOST -H 'Content-Type: application/json' -H 'x-client-id: 2754xxxxxxxxxxf5272' -H 'x-client-secret: 2279ccxxxxxxxxxxxxx409517' -d '{
"orderId": "Order0001",
"orderAmount":1,
"orderCurrency":"INR"
}' 'https://test.cashfree.com/api/v2/cftoken/order'

Token Response Example:

{
"status": "OK",
"message": "Token generated",
"cftoken": "v79JCXXXXXXXXXXXXN1EjOiAHelJCLiXXXXXXXXXXXZiclRmcvJye.K3NKICVS5DcEzXm2VQUO_ZagtWMIKKXzYOqPZ4x0r2P_N3-PRu2mowm-8UXoyqAgsG"
}

The “cftoken” attribute is the token that needs to be used to secure your request.

This API should be called from your server (backend) only, and never from your iOS application as it uses the secretKey.

Step 4: Initiate Payment

After generating the order token, the payment gets initiated when the payment APIs are called (doWebCheckoutPayment, doUPIPayment, doGPayPayment, doAmazonPayment).

For payment, your application passes the order info and the cftoken to the SDK. The relevant payment screen is displayed to the customer where they enter the required information and make the payment. After the payment is complete the customers are redirected to the iOS application and response is received in the ResultDelegate implementation.

The order details passed during the token generation and the payment initiation should match. Else, you will get an `Invalid order details` error.

Wrong appId and token will result in `Unable to authenticate merchant` error. The token generated for payment is valid for 5 minutes within which the payment has to be initiated. Else, you will get an `Invalid token` error.

Step 5: Receive and Handle Response

Once the payment is done, you will get a response in ResultDelegate implementation.

extension ViewController: ResultDelegate {
func onPaymentCompletion(msg: String) {
print("Result Delegate : onPaymentCompletion")
print(msg)
// Handle the result here
}
}

Step 6: Verify Response

We recommend you to verify the payment response using webhooks. You can also verify the response by checking the signature in the payment response.

Checkout

Checkout is the standard flow for Cashfree iOS SDK. In this flow, SDK loads a webview which renders the Cashfree's payment page. Customers can fill in details here and complete payment.

There are two types of Web Checkout methods. You can select the required method based on your business need.

  • Normal - Customer selects the payment mode and enters the payment details within the Cashfree's web payment page to complete the payment

  • Seamless - Customer selects the payment mode and enters payment details in your application. These details are then passed on to the Cashfree SDK. Webview is launched only for the two-factor authentication.

When integrating our iOS SDK, the invoking UIViewController should have been embedded inside a UINavigationController. If your UIViewController is inside a UITabBarController you should embed the UIViewController inside a UINavigationController

Step 1: Import the SDK

import CFSDK

Step 2: Input Params Dictionary

Once you generate the token from server, create the input params dictionary with the following values.

The order details sent from the server should match the values sent from the app to SDK otherwise you'll see this error "Invalid order data".

func getPaymentParams() -> Dictionary<String, Any> {
return [
"appId": "<<YOUR_APP_ID>>",
"orderId": "Order100003",
"tokenData" : "<<GENERATED_TOKEN>>",
"orderAmount": "1",
"customerName": "Customer name",
"orderNote": "Order Note",
"orderCurrency": "INR",
"customerPhone": "9012341234",
"customerEmail": "sample@gmail.com",
"notifyUrl": "https://test.gocashfree.com/notify"
]
}

Step 3: Call Payment Function

Create an object of CFPaymentService from the SDK and call the doWebCheckoutPaymentfunction with the env and ResultDelegatecallback. env can be either be TEST or PROD.Click here to know how to get the App ID and Secret Key.

CFPaymentService().doWebCheckoutPayment(
params: params,
env: Constants.environment,
callback: self)

Step 4: Result Delegate

Once the payment is done, you will get a response in your ResultDelegate implementation.

extension ViewController: ResultDelegate {
func onPaymentCompletion(msg: String) {
print("Result Delegate : onPaymentCompletion")
print(msg)
// Handle the result here
}
}

Seamless

In a Seamless payment flow, the customer enters all details on merchant app checkout view itself. Once the customer has entered all details related to the payment mode, the request opens in a webview showing the service provider (Example, OTP page in case of card payment).

The integration steps for seamless mode is almost the same as the checkout flow except the input params passed will have extra parameters according to the payment mode selected.

Pass the params in the below snippet in addition to the other input params specified here.

Card Payment

Add the following parameters to the params map before invoking doWebCheckoutPayment() method to initiate a seamless card transaction.

let cardParams = [
"paymentOption": "card",
"card_number": "4434260000000008", //Replace Card number
"card_holder": "John Doe", // Card Holder name
"card_expiryMonth": "05", // Card Expiry Month in MM
"card_expiryYear": "2021", // Card Expiry Year in YYYY
"card_cvv": "123" // Card CVV
]

UPI Payment

Add the following parameters to the params map before invoking doWebCheckoutPayment() method to initiate a seamless UPI transaction.

let upiParams = [
"paymentOption": "upi",
"upi_vpa": "testsuccess@gocash"
]

Wallet Payment

Add the following parameters to the params map before invoking doWebCheckoutPayment() method to initiate a seamless wallet transaction. All valid wallet codes are available here.

let walletParams = [
"paymentOption": "wallet",
"paymentCode": "4001" // Wallet code https://docs.cashfree.com/docs/resources/#wallet
]

Netbanking Payment

Add the following parameters to the params map before invoking doWebCheckoutPayment() method to initiate a seamless net banking transaction. All valid bank codes are available here.

let netBankingParams = [
"paymentOption": "nb",
"paymentCode": "3333" // Bank code https://docs.cashfree.com/docs/resources/#net-banking
]

Paypal Payment

Add the following parameters to the params map before invoking doWebCheckoutPayment() method to initiate a seamless Paypal transaction.

let paypalParams = [
"paymentOption": "paypal"
]

UPI Intent

UPI Intent for iOS supports Gpay and PhonePe currently.

Steps to integrate,

Update info.plist file

Add the following code to info.plist file

<key>LSApplicationCategoryType</key>
<string></string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>phonepe</string>
<string>tez</string>
</array>

Compose order details and pass to Cashfree PG SDK

Using the last 2 API responses compose dictionary<String, Any>.

var orderParms = [
"orderId": "<YOUR_ORDER_ID>",
"tokenData" : "<cfToken>",
"orderAmount": "<ORDER_AMOUNT>",
"orderCurrency":"<ORDER_AMOUNT_CURRENCY>",
"customerName": "Example",
"orderNote": "First Order",
"customerPhone": "1111111111",
"appId": "<YOUR_APP_ID>",
"customerEmail": "example@gmail.com",
"notifyUrl": "https://test.gocashfree.com/notify", //optional
"appName" : CFUPIApp.GPAY
]

Pass this object to Cashfree SDK with appName and environment.

CFPaymentService().doUPIPayment(params : orderParams, env: "TEST", callback: self)

Params

Possible Values

UpiApp

UpiApp.GPAY

UpiApp.PHONEPE

UPIApp.PAYTM

env

"TEST" or "PROD"

Get result from Cashfree PG SDK

Cashfree SDK will launch either PhonePe or Google Pay based on the option selected by the user. Once the payment is completed in the 3rd party UPI payment app and the user switches back to the app, the SDK will verify the payment and return the result through the ResultDelegate.

extension ViewController: ResultDelegate
{
func onPaymentCompletion(msg: String)
{
print("Result Delegate : onPaymentCompletion \(msg)")
// Handle the result here
}
}

The response will be a stringified JSON syntax

{"txStatus": "PENDING", "message": null}

You can verify the payment after successfully completing the above steps.

Direct App Integration

AmazonPay

Steps to integrate,

Compose order details and pass to Cashfree PG SDK

Using the last 2 API responses compose dictionary<String, Any>.

var orderParms = [
"orderId": <YOUR_ORDER_ID>,
"tokenData" : <cfToken>,
"orderAmount": <ORDER_AMOUNT>,
"orderCurrency":<ORDER_AMOUNT_CURRENCY>,
"customerName": "Example",
"orderNote": "First Order",
"customerPhone": "1111111111",
"appId": <YOUR_APP_ID>,
"customerEmail": "example@gmail.com",
"notifyUrl": "https://test.gocashfree.com/notify"
]

Now pass this object to Cashfree SDK with appName and environment.

CFPaymentService().doAmazonPayPayment(params : orderParams, env: "TEST", callback: self)

Params

Possible values

env

TEST or PROD

Get result from Cashfree PG SDK

Cashfree SDK will launch either PhonePe or Google Pay based on the option selected by the user. Once the payment is completed in the SFSafariViewController and the user clicks on done, the SDK will verify the payment and pass the result through the ResultDelegate.

extension ViewController: ResultDelegate {
func onPaymentCompletion(msg: String) {
print("Result Delegate : onPaymentCompletion \(msg)")
// Handle the result here
}
}

The response will be a stringified JSON of syntax {"txStatus": "PENDING", "message": null}

Request Parameters

These are the parameters that are available to you when you are making a request for payment on Cashfree iOS SDK.

Parameter

Required

Description

appId

Yes

Your app id

orderId

Yes

Order/Invoice Id

orderAmount

Yes

Bill amount of the order

orderCurrency

No

Currency for the order. INR if left empty. See the Currency Codes below for a list of available currencies. Contact care@gocashfree.com to enable new currencies.

orderNote

No

A help text to make customers know more about the order

customerName

Yes

Name of the customer

customerPhone

Yes

Phone number of customer

customerEmail

Yes

Email id of the customer

notifyUrl

No

Notification URL for server-server communication. Useful when the user’s connection drops while.

paymentModes

No

Allowed payment modes for this order. Available values: cc, dc, nb, paypal, wallet. Leave it blank if you want to display all modes

appName

Yes

CFUPIApp value. (Only for UPI Intent payment mode)

Response Parameters

These parameters are returned to the functions you implement using paymentVC.getResult(). transactionResult contains the details of the transaction. Always verify the signature in the response as described in the response verification section.

Parameter

Description

orderId

Order id for which transaction has been processed. Ex: GZ-212

orderAmount

Amount of the order. Ex: 256.00

referenceId

Cashfree generated unique transaction Id. Ex: 140388038803

txStatus

Payment status for that order. Values can be: SUCCESS, FLAGGED, PENDING, FAILED, CANCELLED.

For UPI Intent the status can be: PENDING, INCOMPLETE, FAILED, FLAGGED, USER_DROPPED, SUCCESS, CANCELLED, VOID

paymentMode

Payment mode used by customer to make the payment. Ex: DEBIT_CARD, MobiKwik, etc

txMsg

Message related to the transaction. Will have the reason if payment failed

txTime

Time of the transaction

signature

signature generated to verify the authenticity of the transaction as explained here.

Webhook Notification

Do not go live without integrating webhook notification.

We send a notification from our backend to your backend whenever an order payment is processed successfully to your notifyUrl. This is useful in cases such as when the user internet connection breaks after payment. This will allow you to reconcile all the successful orders on your end. The notification will be sent to notifyUrl which is specified at order creation. The parameters sent in the notification are described here.

To specify notifyUrl just add it alongside other parameters (orderId, orderAmount etc.).

Notifications are usually instant but rarely can take a minute to hit your server. Make sure that your url supports https. Notifications are sent only in the case of successful payments. Sometimes you may receive the same notification two or more times. It is recommended to ensure that your implementation of the webhook is idempotent. Ensure that you verify the signature in the webhook response.

Response Verification

Verify the response signature to check the authenticity of the transaction response. Do not go live without verifying the signature.

In every response, we add a digital signature to establish the authenticity of the message. We require you to verify this received signature at your end. This will verify if the response has not been tampered with.

This verification has to be done on your backend server as it will involve secretKey which should never be exposed on the clientside. Please use the appropriate code example from below depending on your backend language.

CURL
PYTHON
JAVA
CSHARP
CURL
<?php
$orderId = $_POST["orderId"];
$orderAmount = $_POST["orderAmount"];
$referenceId = $_POST["referenceId"];
$txStatus = $_POST["txStatus"];
$paymentMode = $_POST["paymentMode"];
$txMsg = $_POST["txMsg"];
$txTime = $_POST["txTime"];
$signature = $_POST["signature"];
$data = $orderId.$orderAmount.$referenceId.$txStatus.$paymentMode.$txMsg.$txTime;
$hash_hmac = hash_hmac('sha256', $data, $secretkey, true) ;
$computedSignature = base64_encode($hash_hmac);
if ($signature == $computedSignature) {
// Proceed
} else {
// Reject this call
}
?>
PYTHON
import hashlib
import hmac
import base64
@app.route('/notify_url/', methods=["POST"])
def notify_url_process():
postData = {
"orderId" : request.form['orderId'],
"orderAmount" : request.form['orderAmount'],
"referenceId" : request.form['referenceId'],
"txStatus" : request.form['txStatus'],
"paymentMode" : request.form['paymentMode'],
"txMsg" : request.form['txMsg'],
"txTime" : request.form['txTime'],
}
signatureData = postData["orderId"] + postData["orderAmount"] + postData["referenceId"] + postData["txStatus"] + postData["paymentMode"] + postData["txMsg"] + postData["txTime"]
message = bytes(signatureData).encode('utf-8')
#get secret key from your config
secret = bytes(secretKey).encode('utf-8')
signature = base64.b64encode(hmac.new(secret,
message,digestmod=hashlib.sha256).digest())
PHP
JAVA
LinkedHashMap<String, String> postData = new LinkedHashMap<String, String>();
postData.put("orderId", ORDERID);
postData.put("orderAmount", ORDERAMOUNT);
postData.put("referenceId", REFERENCE_ID);
postData.put("txStatus", TXN_STATUS);
postData.put("paymentMode", PAYMENT_MODE);
postData.put("txMsg", TX_MSG);
postData.put("txTime", TX_TIME);
String data = "";
Set<String> keys = postData.keySet();
for (String key : keys) {
data = data + postData.get(key);
}
String secretKey = "" // Get secret key from config;
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key_spec = new
SecretKeySpec(secretKey.getBytes(),"HmacSHA256");
sha256_HMAC.init(secret_key_spec);
String signature = Base64.getEncoder().encodeToString(sha256_HMAC.doFinal(data.getBytes()));
CSHARP
using System;
using System.Security.Cryptography;
using System.Collections.Generic;
namespace Rextester {
public class Program {
private string CreateToken(string message, string secret){
secret = secret ?? "";
var encoding = new System.Text.ASCIIEncoding();
byte[] keyByte = encoding.GetBytes(secret);
byte[] messageBytes = encoding.GetBytes(message);
using (var hmacsha256 = new HMACSHA256(keyByte))
{
byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
return Convert.ToBase64String(hashmessage);
}
}
public static void Main(string[] args) {
string secret = "<your_secret_key>";
string data = "";
data = data + "FEX101";
data = data + "10.00";
data = data + "19992";
data = data + "SUCCESS";
data = data + "pg";
data = data + "payment done";
data = data + "2018-02-02 17:29:12";
Program n = new Program();
string signature = n.CreateToken(data, secret);
Console.WriteLine(signature);
}
}
}

Running your App

The CFSDK Dynamic Framework works on iOS 10 and above.

Click here to know how to view or generate the API keys for Production and Test Environment.

Test Credentials

Parameter

Required

Description

Card Number

Yes

4111111111111111

Card Holder

Yes

Test

Expiry Month

Yes

10

Expiry Year

Yes

22

CVV/CVC

Yes

123