Skip to main content

Documentation Index

Fetch the complete documentation index at: https://www.cashfree.com/docs/llms.txt

Use this file to discover all available pages before exploring further.

The Cashfree Subscription Element SDK lets you build a fully custom subscription payment experience within your Android application. Unlike the hosted checkout, you collect payment details directly in your own UI and pass them to the SDK, giving you complete control over the look and feel of your payment flow. The SDK supports three payment methods for subscriptions: card, UPI Intent, and eNach (net banking).

Prerequisites

Complete the following tasks before you start the integration: The integration consists of three steps:

Step 1

Create a subscription

Step 2

Open the payment page

Step 3

Confirm the payment
The step-by-step guide for each step of the integration process is as follows:

Step 1: Create a subscription Server-side

Create a subscription from your backend server before you process any payment. This API requires your secret key, so don’t call it directly from your mobile application.
Create subscriptions through your server as this API requires your secret key. Don’t call it directly from your mobile application.
After the subscription is created, your backend receives a subscription_id and a subscription_session_id. Pass both values to your Android client to proceed with the payment.
The following example shows how to create a subscription using the Create Subscription API:
curl --request POST \
  --url https://sandbox.cashfree.com/pg/subscriptions \
  --header 'Content-Type: application/json' \
  --header 'x-api-version: 2025-01-01' \
  --header 'x-client-id: <your-client-id>' \
  --header 'x-client-secret: <your-client-secret>' \
  --data '{
    "subscription_id": "Demo_Subscription",
    "customer_details": {
      "customer_name": "john",
      "customer_email": "john@dummy.com",
      "customer_phone": "9908730221",
      "customer_bank_account_number": "59108290701802",
      "customer_bank_ifsc": "HDFC0002614",
      "customer_bank_code": "HDFC",
      "customer_bank_account_type": "SAVINGS"
    },
    "plan_details": {
      "plan_name": "plan12345",
      "plan_type": "PERIODIC",
      "plan_amount": 10,
      "plan_max_amount": 100,
      "plan_max_cycles": 100,
      "plan_intervals": 2,
      "plan_currency": "INR",
      "plan_interval_type": "WEEK",
      "plan_note": "Bi-weekly INR 10 plan"
    },
    "authorization_details": {
      "authorization_amount": 100,
      "authorization_amount_refund": true,
      "payment_methods": [
        "enach",
        "upi",
        "card"
      ]
    },
    "subscription_meta": {
      "return_url": "https://example.com/subscription/return",
      "notification_channel": [
        "EMAIL",
        "SMS"
      ],
      "session_id_expiry": "2025-06-01T23:00:08+05:30"
    },
    "subscription_expiry_time": "2100-01-01T23:00:08+05:30",
    "subscription_first_charge_time": "2025-06-01T23:00:08+05:30",
    "subscription_tags": {
      "psp_note": "Monthly subscription payment"
    }
  }'
A successful response returns the subscription_id and subscription_session_id. Use these values to build the CFSubscriptionSession object in Step 2. The API returns the following response on success:
{
  "subscription_id": "Demo_Subscription",
  "subscription_session_id": "subs_token_tc9JCN4MzUIJ",
  "subscription_status": "INITIALIZED",
  "cf_subscription_id": "4"
}
For the full list of request parameters and response fields, see the Create Subscription API.

Step 2: Open the payment page Client-side

After you create the subscription, open the payment page so the customer can provide payment details.

1. Set up the SDK

The Cashfree Android SDK is available on Maven Central. The latest version is 2.4.0. The SDK requires Android API level 19 or higher. Add the following dependency to your app-level build.gradle file:
implementation 'com.cashfree.pg:api:2.4.0'

2. Select a payment method

The Subscription Element SDK supports the following payment methods:
In this flow, the customer enters their card details directly in your application UI. The SDK securely processes the card payment and initiates the subscription mandate.

3. Complete the payment

To complete the payment, follow these steps:
  1. Create a CFSubscriptionSession object.
  2. Create the payment object for the selected payment method.
  3. Set up the subscription callback.
  4. Initiate the payment using doSubscriptionPayment().

Create a session

The CFSubscriptionSession object holds the session context for the payment. It accepts the subscription_session_id and subscription_id obtained from Step 1, and the Cashfree environment (.SANDBOX or .PRODUCTION). Set Environment to .SANDBOX for testing or .PRODUCTION for live payments. Create the session object in the following example:
CFSubscriptionSession.Environment cfEnvironment = CFSubscriptionSession.Environment.SANDBOX; // or .PRODUCTION

CFSubscriptionSession cfSession = new CFSubscriptionSession.CFSubscriptionSessionBuilder()
        .setEnvironment(cfEnvironment)
        .setSubscriptionSessionID(subscription_session_id)
        .setSubscriptionId(subscription_id)
        .build();

Create a payment object

The SDK provides a dedicated payment builder for each supported payment method. Build only the object that corresponds to the payment method your customer has selected.
Use the following builders to create a card payment object:
CFSubsCard cfCard = new CFSubsCard.CFSubsCardBuilder()
        .setCardHolderName("Kishan")
        .setCardNumber("4011381307299555")
        .setCardExpiryMonth("08")
        .setCardExpiryYear("29")
        .setCVV("950")
        .build();

CFSubsCardPayment cfCardPayment = new CFSubsCardPayment.CFSubsCardPaymentBuilder()
        .setSubscriptionSession(cfSession)
        .setSubsCard(cfCard)
        .build();

Set up the subscription callback

The SDK exposes the CFSubscriptionResponseCallback interface to receive callbacks when the subscription payment journey ends. This interface consists of two methods:
public void onSubscriptionVerify(CFSubscriptionResponse response)
public void onSubscriptionFailure(CFErrorResponse cfErrorResponse)
Register the callback in your activity’s onCreate method. This configuration also handles activity restarts correctly.
Implement the callback in your activity in the following example:
public class YourActivity extends AppCompatActivity implements CFSubscriptionResponseCallback {

    @Override
    public void onSubscriptionVerify(CFSubscriptionResponse response) {
        // Verify subscription status from your backend before proceeding.
    }

    @Override
    public void onSubscriptionFailure(CFErrorResponse cfErrorResponse) {
        // Handle payment failure. Inspect cfErrorResponse for details.
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_subscription_checkout);
        try {
            // If you are using a fragment, add this line inside onCreate() of your Fragment.
            CFPaymentGatewayService.getInstance().setSubscriptionCheckoutCallback(this);
        } catch (CFException e) {
            e.printStackTrace();
        }
    }
}

Initiate the payment

Call doSubscriptionPayment() to open the payment screen when the customer taps the pay button. The example below uses cfSubsNetBankingPayment. Replace it with cfCardPayment or cfSubsUpiPayment for your selected payment method.
// Replace YourActivity with your activity class name.
CFPaymentGatewayService.getInstance().doSubscriptionPayment(YourActivity.this, cfSubsNetBankingPayment);

Sample code

The following example shows a complete card payment flow, including session creation, payment object setup, optional theme customisation, and payment initiation.
The following method demonstrates a complete card payment integration:
private void openCardElementFlow() {
    try {
        CFSubscriptionSession cfSession = new CFSubscriptionSession.CFSubscriptionSessionBuilder()
                .setEnvironment(cfEnvironment)
                .setSubscriptionSessionID(subsSessionID)
                .setSubscriptionId(subsID)
                .build();

        CFSubsCard cfCard = new CFSubsCard.CFSubsCardBuilder()
                .setCardHolderName("Kishan")
                .setCardNumber("4011381307299555")
                .setCardExpiryMonth("08")
                .setCardExpiryYear("29")
                .setCVV("950")
                .build();

        CFSubsCardPayment cfCardPayment = new CFSubsCardPayment.CFSubsCardPaymentBuilder()
                .setSubscriptionSession(cfSession)
                .setSubsCard(cfCard)
                .build();

        // Optional: apply a custom theme.
        CFTheme theme = new CFTheme.CFThemeBuilder()
                .setNavigationBarBackgroundColor("#6A2222")
                .setNavigationBarTextColor("#FFFFFF")
                .build();
        cfCardPayment.setTheme(theme);

        CFPaymentGatewayService.getInstance().setSubscriptionCheckoutCallback(this);
        CFCorePaymentGatewayService.getInstance().doSubscriptionPayment(this, cfCardPayment);
    } catch (CFException exception) {
        exception.printStackTrace();
    }
}
Refer to the sample integration on GitHub for a working end-to-end implementation.

Step 3: Confirm the payment Server-side

After the SDK delivers a callback via onSubscriptionVerify, confirm the payment status from your backend before taking any action. The SDK callback only signals that the payment flow has ended; it does not guarantee a successful payment. Use the Fetch Details of All Payments of a Subscription API to retrieve the current payment status.
The following request fetches all payments for a subscription:
curl --request GET \
  --url https://api.cashfree.com/pg/subscriptions/{subscription_id}/payments \
  --header 'x-api-version: 2025-01-01' \
  --header 'x-client-id: <your-client-id>' \
  --header 'x-client-secret: <your-client-secret>'
A successful response returns an array of payment objects. Check the payment_status field to determine the outcome. The API returns the following response on success:
[
  {
    "cf_payment_id": "123456",
    "cf_subscription_id": "7891011",
    "payment_id": "your-payment-id",
    "payment_amount": 1,
    "payment_status": "SUCCESS",
    "payment_type": "AUTH",
    "payment_initiated_date": "2025-06-01T22:14:58+0530",
    "subscription_id": "your-subscription-id",
    "retry_attempts": 0,
    "failure_details": {
      "failure_reason": ""
    }
  }
]
Always verify the subscription status from your backend before delivering goods or services to the customer. Proceed only when payment_status is SUCCESS.

Error codes

If a required field or object is missing when you initiate payment, the SDK returns a CFException. The following table lists SDK-level validation errors and when they occur.
The SDK validation errors are grouped by category as follows:

Session errors

These errors occur when the CFSubscriptionSession object or its required fields are not provided.
Error codeMessageDescription
SUBSCRIPTION_SESSION_OBJECT_MISSINGThe “CFSubscriptionSession” is missing in the request.The CFSubscriptionSession object was not passed to the payment builder.
SUBSCRIPTION_SESSION_ID_MISSINGThe “subscription_session_id” is missing in the request.The subscription_session_id was not set on the CFSubscriptionSession builder.
SUBSCRIPTION_ID_MISSINGThe “subscription_id” is missing in the request.The subscription_id was not set on the CFSubscriptionSession builder.
ENVIRONMENT_MISSINGThe “environment” is missing in the request.The Cashfree environment (.SANDBOX or .PRODUCTION) was not set on the CFSubscriptionSession builder.

Payment method object errors

These errors occur when a payment method object is absent or one of its required fields is not set.
Error codeMessageDescription
SUBSCRIPTION_CARD_OBJECT_MISSINGThe “CFSubsCard” object is missing in the request.The CFSubsCard object was not passed to the CFSubsCardPayment builder.
SUBSCRIPTION_NB_OBJECT_MISSINGThe “CFSubsNetBanking” object is missing in the request.The CFSubsNetBanking object was not passed to the CFSubsNetBankingPayment builder.
SUBSCRIPTION_UPI_OBJECT_MISSINGThe “CFSubsUpi” object is missing in the request.The CFSubsUpi object was not passed to the CFSubsUpiPayment builder.
SUBSCRIPTION_NB_ACCOUNT_HOLDER_NAME_MISSINGThe “account holder name” is missing in the request.The setAccountHolderName field was not set on the CFSubsNetBanking builder.
SUBSCRIPTION_NB_ACCOUNT_NUMBER_MISSINGThe “account number” is missing in the request.The setAccountNumber field was not set on the CFSubsNetBanking builder.
SUBSCRIPTION_NB_BANK_CODE_MISSINGThe “bank code” is missing in the request.The setAccountBankCode field was not set on the CFSubsNetBanking builder.
SUBSCRIPTION_NB_ACCOUNT_TYPE_MISSINGThe “account type” is missing in the request.The setAccountType field was not set on the CFSubsNetBanking builder.
SUBSCRIPTION_NB_AUTH_MODE_MISSINGThe “auth mode” is missing in the request.The setAuthMode field was not set on the CFSubsNetBanking builder.

Callback errors

These errors occur when the payment callback is not registered before initiating payment.
Error codeMessageDescription
CALLBACK_MISSINGThe “callback” cannot be null.setSubscriptionCheckoutCallback was not called before doSubscriptionPayment(). Register the callback in your activity’s onCreate method before you initiate payment.

Other options

The following optional configurations help you customise the payment screen appearance and enable SDK logging for troubleshooting.
Apply a custom theme to the payment screen to match your application’s visual design. Use the CFTheme builder to set the navigation bar background colour and text colour. Apply the theme to your payment object before you call doSubscriptionPayment().The following example sets the navigation bar colours:
CFTheme theme = new CFTheme.CFThemeBuilder()
        .setNavigationBarBackgroundColor("#6A2222") // sets the status bar and toolbar colour
        .setNavigationBarTextColor("#FFFFFF")        // sets the toolbar text colour
        .build();

cfSubsNetBankingPayment.setTheme(theme);
// or: cfCardPayment.setTheme(theme);
To enable SDK logging, add the following entry to your values.xml file:<integer name="cashfree_pg_logging_level">3</integer>The following logging levels are available:
  • VERBOSE = 2
  • DEBUG = 3
  • INFO = 4
  • WARN = 5
  • ERROR = 6
  • ASSERT = 7