Android SDK

The Cashfree Android SDK allows you to integrate Cashfree Payment Gateway into your application and start collecting payments from your customers.

The Cashfree SDK has been designed to minimise the complexity of handling and integrating payments in your application. The Cashfree Android SDK is available at the Github repo as a .aar file.

Integration Steps

To integrate Cashfree Android SDK with your Android 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 Android SDK.

Step 2: Integrate SDK

The Cashfree SDK is bundled as an AAR file according to the latest Android standards. We support integration from API level 16. Ensure that the minSdkVersion in the build.gradle of your app is equal to or greater than that.

To integrate the SDK, follow the steps below:

Step 2.1: Download Library

The Cashfree SDK is bundled as an AAR file according to the latest Android standards. Download and include this library as a dependency in your app.

Version

Download Link

1.2

​Support Library Version​

1.2

​AndroidX Version​

Step 2.2: Gradle Changes

Step 2.2.1 Add library dependency to your Android project

  1. Create a libs folder inside your module. For example, app/libs is the location for the app module.

  2. Copy your .aar file to this libs folder.

  3. Open the `build.gradle` file of your module and add the following code in the dependency section.

dependencies {
implementation files(β€˜libs/cashfreesdk-1.4.9.5-release.aarβ€˜)
}

If you have to use this library in multiple modules use the method mentioned here.​

Step 2.2.2 Add other dependencies

You need to add a few additional dependencies to the build.gradle file depending on the payment type.

Click the links below to know more about what dependencies need to be added:

  • Web Checkout

  • Google Pay

  • Amazon Pay

  • PhonePe

  • UPI Intent

Step 2.3: Android Manifest Changes

  • The Cashfree SDK requires you to add the permissions shown below in your Android Manifest file.

<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application ...>
  • Set the tools:node attribute to "merge" in the definition of your application element in the Android Manifest file.

  • If the OTP auto-read-submit feature is enabled for your account add the Google Play services version meta-data.

<application
...
tools:node="merge">
<!--Only add it if you need Auto OTP reading feature is enabled-->
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
</application>

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 tohttps://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.

curl -XPOST -H 'Content-Type: application/json'
-H 'x-client-id: <YOUR_APP_ID>'
-H 'x-client-secret: <YOUR_SECRET_KEY>'
-d '{
"orderId": "<ORDER_ID>",
"orderAmount":<ORDER_AMOUNT>,
"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: YOUR_APP_ID' -H 'x-client-secret: YOUR_SECRET_KEY' -d '{
"orderId": "Order0001",
"orderAmount":1,
"orderCurrency":"INR"
}' 'https://test.cashfree.com/api/v2/cftoken/order'

Response Example

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

This API should be called from your server (backend) only, and never from your Android 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 (doPayment, 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 Android application and response is received on onActivityResult()

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

After the payment is complete you will receive the response on the onActivityResult() function of the invoking activity. In the intent extras, you will receive a set of response parameters which is used to determine if the transaction was successful or not. Request code will always be equal to CFPaymentService.REQ_CODE

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//Same request code for all payment APIs.
Log.d(TAG, "ReqCode : " + CFPaymentService.REQ_CODE);
Log.d(TAG, "API Response : ");
//Prints all extras. Replace with app logic.
if (data != null) {
Bundle bundle = data.getExtras();
if (bundle != null)
for (String key : bundle.keySet()) {
if (bundle.getString(key) != null) {
Log.d(TAG, key + " : " + bundle.getString(key));
}
}
}
}

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 Android 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.

Add Dependencies

dependencies {
...
//Dependencies used by all payment functions
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.android.volley:volley:1.1.1'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
​
//doPayment - If OTP Auto read enabled (default)
implementation 'com.google.android.material:material:1.1.0'
implementation 'com.google.android.gms:play-services-auth:17.0.0'
implementation 'com.google.android.gms:play-services-auth-api-phone:17.3.0'
...
}
  • Web checkout includes the Google pay, Amazon pay, PhonePe and UPI payment modes.

  • The difference between web checkout and the other payment APIs (doGPayPayment() etc) is that the web checkout initiates a collect request instead of opening the applications directly for payment.

  • In a collect request, after the payment for an order is initialised, a notification is received in that respective application and the user proceeds with the payment.

doPayment

The doPayment method initiates the payment inside a webview. The customer will be taken to the payment page where they can pay through any of the payment methods that is activated for their account. Once the payment is complete the webview will close and the response will be delivered through onActivityResult().

public void doPayment(Context context, Map<String, String> params, String token, String stage)

Parameters:

  • context: Context of the calling activity.

  • params: A map of all the relevant parameters described here​

  • token: The token generated here​

  • stage: Value should be either "TEST" for testing server, or "PROD" for production server respectively.

public void doPayment(Context context, Map<String, String> params, String token, String stage, String color1, String color2)

Additional Parameters:

  1. color1: Toolbar background color.

  2. color2: Toolbar text and back arrow color.

If you want to hide the order ID, add another parameter hideOrderID as shown below:

public void doPayment(Context context, Map<String, String> params,
String token, String stage, boolean hideOrderId)

If you want to customise the toolbar colour and also hide the order ID in the toolbar, add the parameters as shown below:

public void doPayment(Context context, Map<String, String> params,
String token, String stage, String color1, String color2,
boolean hideOrderId)

Seamless Integration

When you have a requirement for a customised payment flow, you can use the seamless integration. You can implement the payment page as per your requirement and then use our SDK to authorise the payment. Once the payment details are collected the OTP or the two-factor authentication page will open in a webview. After the payment is confirmed the webview closes and you will receive a response.

We recommend that you use Checkout integration method unless you are certain that you require a customised payment flow.

The following sections describe the additional parameters for each of the payment methods:

Credit/Debit Card

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

params.put(PARAM_PAYMENT_OPTION, "card");
params.put(PARAM_CARD_NUMBER, "4434260000000008");//Replace Card number
params.put(PARAM_CARD_MM, "05"); // Card Expiry Month in MM
params.put(PARAM_CARD_YYYY, "2021"); // Card Expiry Year in YYYY
params.put(PARAM_CARD_HOLDER, "John Doe"); // Card Holder name
params.put(PARAM_CARD_CVV, "123"); // Card CVV

Net Banking

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

params.put(PARAM_PAYMENT_OPTION, "nb");
params.put(PARAM_BANK_CODE, "3333");// Put correct bank code here

Wallet

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

params.put(PARAM_PAYMENT_OPTION, "wallet");
params.put(PARAM_BANK_CODE, "4001");// Put correct wallet code here

UPI

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

params.put(PARAM_PAYMENT_OPTION, "upi");
params.put(PARAM_UPI_VPA, "testsuccess@gocash");// Put correct upi vpa here

Paypal

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

params.put(PARAM_PAYMENT_OPTION, "paypal");

UPI Intent

When the doUPIPayment method is invoked the customer is shown a list of all the installed UPI applications on their phone. After the customer selects their preferred application, the payment confirmation page will open in the application. After payment completion, the response is delivered through onActivityResult().

You also have the option to display the UPI applications in your user interface and send the response to Cashfree to launch the application selected by the customer.

Add Dependencies

dependencies {
...
//Dependencies used by all payment functions
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.android.volley:volley:1.1.1'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
​
//doUPIPayment - Only if you are using the default UI from the SDK instead of showing your own UI and calling setUpiClient()
implementation 'androidx.recyclerview:recyclerview:1.1.0'
}

Initiate Payment

public void upiPayment(Context context, Map<String, String> params, String token, String stage)

Parameters:

  • context: Context object of the calling activity is required for this method. In most of the cases this will mean sending the instance of the calling activity (this).

  • params: A map of all the relevant parameters described here​

  • token: The token generated here​

  • stage: Value should be either "TEST" or "PROD" for testing server or production server respectively.

Select Upi Client

When initiating the UPI intent the customer is shown a list of all the UPI client applications (BHIM, GPay, PhonePe etc.) on their phone. This allows the customer to select any UPI application they want to pay with. If you want the customer to pay with a particular app you can use the parameter upiClientPackage. After calling this method whenever upiPayment is called the customer will not see the application selection screen, instead will be redirected to the application whose package is provided in the parameters.

public void selectUpiClient(String upiClientPackage)

Parameters:

  • upiClientPackage: The string describing the java package of the upi client that is to be selected.

Get UPI Clients

Get the packages of all the UPI Clients installed on the device as a string array. These packages can then be passed to selectUpiClient() method to initiate the payment.

public String[] getUpiClients(Context context)

Get the packages of all the UPI Clients installed on the device as a string array. These packages can then be passed to selectUpiClient() method to initiate payment.

Parameters

  • context: Context object of the calling activity is required for this method.

Direct App Integration

Google Pay

The doGPayPayment API opens the Google Pay application directly for the customer to make the payment. On payment completion, the SDK verifies the payment and the response is delivered through onActivityResult().

Add Dependencies

Add the google maven repository to your project in the top level build.gradle. Add the following google maven repository to your project at the top level (project) build.gradle only if you are using doGPayPayment() function.

allprojects{
repositories {
google()
...
}
}

Add the following dependencies to your module.

dependencies {
...
//Dependencies used by all payment functions
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.android.volley:volley:1.1.1'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
​
//doGPayPayment - Also add the google maven repository as shown in the consecutive step
implementation files ("libs/google-pay-client-api-1.0.0.aar")
implementation 'com.google.android.gms:play-services-tasks:15.0.1'
​
}

Check if Google Pay is Ready

You need to first check if the Google Pay app is available for payments.

Call the function isGPayReadyForPayment before showing the GPay payment option to the user. It checks if the GPay app is installed in the device and if it is ready for making payments.

public void isGPayReadyForPayment(Context context,
final GooglePayStatusListener listener)

Parameters

context: Context of the calling activity. listener: GooglePayStatusListener to receive the result.

public interface GooglePayStatusListener {
void isReady();
void isNotReady();
}

Initiate Payment

public void gPayPayment(Context context, Map<String, String> params, String token, String stage)

Parameters

  • context: Context of the calling activity.

  • params: A map of all the relevant parameters described here​

  • token: The token generated here​

  • stage: The value should be "TEST" for testing server, or "PROD" for production server respectively.

Amazon Pay

The doAmazonPayment API initiates the payment inside chrome custom tab (or default browser if it is not available) where the customer is shown the amazon pay payment page. After the payment is complete and the customer closes the chrome tab, the SDK verifies the payment. After the payment is verified, the user is redirected to the application. The response is delivered through onActivityResult().

Add Dependencies

dependencies {
...
//Dependencies used by all payment functions
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.android.volley:volley:1.1.1'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
​
//doAmazonPayment
implementation 'androidx.browser:browser:1.0.0'
}

Initiate Payment

public void doAmazonPayment(Context context, Map<String, String>
params, String token, String stage)

Parameters

  • context: Context of the calling activity.

  • params: A map of all the relevant parameters described here​

  • token: The token generated here​

  • stage: The value should be "TEST" for testing server, or "PROD" for production server respectively.

PhonePe

After the payment is initiated the PhonePe app is opened directly for payment. After the payment is complete, the SDK verifies the payment. The response is delivered through onActivityResult().

Add Dependencies

dependencies {
...
//Dependencies used by all payment functions
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.android.volley:volley:1.1.1'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
}

Check if PhonePe is Ready

You need to first check if PhonePe App is available for payment.

Call the function doesPhonePeExist before showing PhonePe as a payment option to the user. It checks if the device has a valid version of PhonePe app installed. If it is available then it checks if the app is set up to make payments.

public boolean doesPhonePeExist(Context context, String stage)

Parameters

  • context: Context of the calling activity.

  • stage: The value should be "TEST" for testing server, or "PROD" for production server respectively.

Initiate Payment

public void phonePePayment(Context context, Map<String, String> params,
String token, String stage)

Parameters

  • context: Context of the calling activity.

  • params: A map of all the relevant parameters described here​

  • token: The token generated here​

  • stage: The value should be "TEST" for testing server, or "PROD" for production server respectively.

Other Common SDK Functions

SetOrientation

Choose the orientation (portrait or landscape) of the payment page. By default the payment page is shown in portrait orientation.

public void setOrientation(Context context, int val)

Parameters

  • val: If the integer value is zero the orientation will be in portrait mode. Else, it will be landscape mode.

  • context: Context of the calling activity.

SetConfirmOnExit

By default, a confirmation dialog is displayed when the users press back in the payment screen. You have the option to disable the confirmation dialog.

public void setConfirmOnExit(Context context, boolean confirmOnExit)

Parameters

  • context: Context of the calling activity.

  • confirmOnExit: Value should be true if you want to show a confirmation popup on pressing back in the payment screen.

Verify Response

It is recommended to verify the payment response from the SDK using one of the following methods.

Webhook Notifications

We send a notification from Cashfree backend to your backend whenever a payment is successful for an order. This is useful for users in cases when the internet connection is not stable after payment. This will allow you to reconcile all the successful orders at your end. The notification will be sent to notifyUrl which is specified during order creation. The parameters sent in notification are described here.

To specify notifyUrl, add it with other parameters (orderId, orderAmount etc.) as shown below: params.put(PARAM_NOTIFY_URL, "https://example.com/path/to/notify/url/")

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.

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 this received signature at your end. This will verify if the response has tampered. This verification has to be done on your server as it will involve secretKey which should not be exposed on the client side.

PHP
PYTHON
JAVA
CSHARP
PHP
<?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
iimport 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())
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);
}
}
}

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.

Response Parameters

These parameters are sent as extras to the onActivityResult(). They contain the details of the transaction.

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.

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.

type

Fixed value : CashFreeResponse. To identify the response is from cashfree SDK.

signature

Response signature, more here.

Checklist

Checklist to Go Live

  • Ensure you are triggering https://api.cashfree.com/api/v2/cftoken/order endpoint for generating the token.

  • Pass the production appId/secretKey in the x-client-id and x-client-secret of the token request API. Follow the steps available here to get the app ID and secret key.

  • When calling doPayment() or upiPayment() ensure that the stage parameter is "PROD".

  • When calling doPayment() or upiPayment() the params map is sent to your appId. Please ensure it is the correct production appId.

Checklist to Revert to Test

  • Ensure you are triggering https://test.cashfree.com/api/v2/cftoken/order endpoint for generating the token.

  • Pass the Test app ID and secret key in the x-client-id and x-client-secret of the token request API. Follow the steps available here to get the app ID and secret key from

    the "Sandbox" section.

  • When calling doPayment() or upiPayment() ensure that the stage parameter is "TEST".

  • When calling doPayment() or upiPayment() the params map is sent to your appId. Please ensure it is the correct test appId.