iOS SDK (Deprecated)
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.
The Cashfree iOS SDK Integration sample is available at the Github repo.
Watch the video to know how to integrate Cashfree iOS SDK with your iOS application:
Integration Steps
To integrate Cashfree iOS SDK with your iOS application,
- Create an account with Cashfree and get the API keys
- Integrate the Cashfree SDK into your application
- Generate Token - From Backend
- 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.
- Receive and handle response - Cashfree SDK returns the payment result for the order which should be handled in your application.
- Verify response - It is mandatory to verify the payment response by checking the signature value returned in the payment response. It is also highly recommended to implement webhook notifications to receive a notification from the Cashfree backend to your backend whenever a payment is successful for an order.
Step 1: Create Account and Get API Keys
- Go to Cashfree website and create an account. Click here for detailed steps on how to create and activate your account.
- Log in to your Merchant Dashboard using the same credentials.
- Click Payment Gateway section View Dashboard click Credentials. For security purposes, you need to enter your password for verification.
- 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 Link |
11.+ | 5+ | All | Download SDK |
12.+ | 5+ | All | Download SDK |
Set up your Project
Add Cashfree SDK:
- Drag and drop the contents of zip file onto your Xcode project navigator. Select the checkbox for Copy items if needed. Click Finish.
- Then click the + button on Embedded Binaries in the General tab of your iOS app project file.
- Select CFSDK.xcframework.
- 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 action 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'
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'
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 a 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 anInvalid 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
Once the SDK returns a response to the application, it is mandatory to verify the payment response by verifying the signature value returned in the payment response. It is also highly recommended to implement webhook notification to receive a notification from Cashfree backend to your backend whenever a payment is successful for an order.
Click here to know about the implementation details.
Sample Application
Click here to view the sample application.
Checkout
Checkout is the standard flow for Cashfree iOS SDK. In this flow, SDK loads a webview which renders Cashfree's payment page. Customers can fill in the details here and complete the 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 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 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: Permissions
Open the iOS application using XCode or any text editor and add the following into its info.plist file.
<key>LSApplicationCategoryType</key>
<string></string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>bhim</string>
<string>paytm</string>
<string>phonepe</string>
<string>tez</string>
</array>
Step 3: Input Params Dictionary
Once you generate the token from the 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": "[email protected]",
"notifyUrl": "https://test.gocashfree.com/notify"
]
}
Step 4: 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.
CFPaymentService().doWebCheckoutPayment(
params: params,
env: Constants.environment,
callback: self)
Step 5: 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 Checkout
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.
The following sections describe the additional parameters for each of the payment methods:
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
]
Net Banking
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
]
Wallet
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
]
UPI
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"
]
Paypal
Add the following parameters to params map before invoking doWebCheckoutPayment() method to initiate a seamless Paypal transaction.
let paypalParams = [
"paymentOption": "paypal"
]
Third-Party Validation
The iOS SDK also supports Third Party Validation through Seamless Web Checkout.
There is no change in the integration method, the only exception is that you have to send us the pre-registered account number and IFSC code for each of your customers as part of the request parameter.
For TEST credentials and more information, visit here
UPI Intent
With UPI intent you can provide customers with a smoother payment experience through UPI without them having to switch between multiple applications to complete the payment. UPI Intent for iOS supports Gpay, PhonePe, Paytm, and BHIM currently. Click here to know more about UPI intent flow.
Watch the video on how to integrate UPI intent flow with your iOS application.
Steps to integrate,
- Update Info.plist file in your project
- Compose the order details and pass it to Cashfree PG SDK
- Get result from SDK in result delegate
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>
<string>paytm</string>
<string>bhim</string>
</array>
Compose order details and pass to Cashfree PG SDK
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": "[email protected]",
"notifyUrl": "https://test.gocashfree.com/notify", //optional
]
Pass this object to Cashfree SDK with appName and environment. Once the function is called, Cashfree iOS SDK will show the list of supported apps. Once the user selects the app, they will be redirected to the selected app to make the payment. After completing the payment your customers must navigate back to your application.
CFPaymentService().doUPIPayment(params : orderParams, env: "TEST", callback: self)
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}
Seamless UPI Intent
If you do not want to show Cashfree's app listing screen you must pass the app name params as part of the request parameters.
Params | Possible Values |
---|---|
UpiApp | UpiApp.GPAY UpiApp.PHONEPE UPIApp.PAYTM UPIApp.BHIM |
env | "TEST" or "PROD" |
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": "[email protected]",
"notifyUrl": "https://test.gocashfree.com/notify", //optional
"appName" : CFUPIApp.GPAY //extra line for seamless UPI intent
]
Create a new order ID every time you invoke the UPI payment flow since UPI intent flow can be initiated once per order ID.
Customise Navigation Bar
If you want to customise the navigation bar color and text color, use the following parameters:
-
color1: Navigation bar background color.
-
color2: Navigation bar text and back arrow color.
orderParms[ "color1"] = “00FFFF”; // Use hexadecimal values for background color orderParms[ "color2"] = “00FFFF”; // Use hexadecimal values for text color
Direct App Integration
Amazon Pay
Steps to integrate,
- Create token using order token API
- Compose the order details and pass it to Cashfree PG SDK
- Get result from Cashfree SDK in result delegate
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": "[email protected]",
"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)
Parameters:
- env - Possibel values are 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}
Verify Response
Once the SDK returns a response to the application, it is mandatory to verify the payment response by verifying the signature value returned in the payment response and it also highly recommended to implement webhook notification.
Webhook Notifications
Webhooks are events that notify you about the payment. We send a notification from Cashfree backend to your backend whenever a payment is successful for an order. The notification will be sent to notifyUrl which is specified during order creation.
To specify notifyUrl, add it with other parameters (orderId, orderAmount etc.) as shown below:
params["notifyUrl"] = "https://example.com/path/to/notify/url/"
- Notifications are usually instant but in some rare cases it can take up to 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.
- This also handles scenarios for users in cases like the internet connection lost after payment, or user closing the application after payments, etc. It helps to reconcile all the successful orders at your end.
The parameters sent in notification are described here.
Verify Signature
Verify the signature value in the payment response to check the authenticity of the transaction response. In every response, we add a digital signature to establish the authenticity of the message. We require you to verify the signature received at your end to ensure that the response has not been tampered. This verification has to be done on your server as involves secretKey which should not be exposed on the client side.
<?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
}
?>
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
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()));
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);
}
}
}
Request and Response Parameters
Request Parameters
Parameter | Required | Description |
---|---|---|
appId | Yes | Your app ID |
orderId | Yes | Order or Invoice ID |
orderCurrency | Yes | Currency code for the order. |
orderAmount | Yes | Bill amount of the order |
orderNote | No | Help text to provide customers with more information about the order. |
customerName | No | Name of the customer |
customerPhone | Yes | Phone number of the customer |
customerEmail | Yes | Email ID of the customer |
notifyUrl | No | Notification URL for server-server communication. Useful when a user's connection drops after completing the payment. |
paymentModes | No | Allowed payment modes for this order. Available values: cc, dc, nb, paypal, upi, 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. Example, GZ-212. |
orderAmount | Order amount. Example, 256.00 |
paymentMode | Payment mode of the transaction. |
referenceId | Cashfree generated unique transaction ID. Example, 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 customers to make the payment. Example, DEBIT_CARD, MobiKwik. |
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, more here. |
- There can be scenarios where the SDK is not able to verify the payment within a short period of time. The status of such orders will be PENDING.
- If the Webview closes immediately after it is opened then it could be because of some issues with the input that is passed to the SDK. Check the inputs passed and if you still need further help reach out to us at [email protected].
- If you are getting INCOMPLETE as the transaction status please reach out to your account manager or [email protected]. To know more about the transaction statuses, click here.
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 |
Updated about 1 year ago