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

# Android Integration

> Integrate the Cashfree Subscription Android SDK to create subscriptions, capture mandate authorisations, and process recurring payments in Android apps.

### Setting up mobile SDK <Badge color="orange">Client-side</Badge>

```
implementation 'com.cashfree.pg:api:2.4.0'
```

### Step 1: Creating a subscription <Badge color="green">Server-side</Badge>

The first step in the Subscription Checkout integration is to create a subscription. You need to do this before any payment can be processed. You can add an endpoint to your server which creates this subscription and is used for communication with your frontend.

<Tip>Subscription creation must happen from your backend (as this API uses your secret key). Please do not call this directly from your mobile application. You can use below-mentioned backend SDKs</Tip>

<AccordionGroup>
  <Accordion title="Node">
    [Creating Subscription from Node SDK](https://github.com/cashfree/cashfree-pg-sdk-nodejs/blob/main/api.ts#L31393)
  </Accordion>

  <Accordion title="Java">
    [Creating Subscription from Java SDK](https://github.com/cashfree/cashfree-pg-sdk-java/blob/main/src/main/java/com/cashfree/pg/Cashfree.java)
  </Accordion>

  <Accordion title="Golang">
    [Creating Subscription from Golang SDK](https://github.com/cashfree/cashfree-pg/blob/main/api_subscription.go#L1288)
  </Accordion>

  <Accordion title="Dotnet">
    [Creating Subscription from Dotnet SDK](https://github.com/cashfree/cashfree-pg-sdk-dotnet/blob/master/src/cashfree_pg/Client/ApiClient.cs#L9375)
  </Accordion>

  <Accordion title="Python">
    [Creating Subscription from Python SDK](https://github.com/cashfree/cashfree-pg-sdk-python/blob/master/cashfree_pg/api_client.py#L8502)
  </Accordion>

  <Accordion title="PHP">
    [Creating Subscription from PHP SDK](https://github.com/cashfree/cashfree-pg-sdk-php)
  </Accordion>
</AccordionGroup>

Once you create subscription, you will get the `subscription_id` and `subscription_session_id`

### Step 2: Opening the subscription checkout payment page <Badge color="orange">Client-side</Badge>

Once the subscription is created, the next step is to open the payment page so the customer can make the payment. Cashfree Android SDK offer below payment flow.

To complete the payment, we can follow the following steps:

1. Enable Subscription flow flag in Android Manifest
2. Create a `CFSubscriptionSession` object.
3. Create a `CFWebCheckoutTheme` object (Optional).
4. Create a `CFSubscriptionPayment` object.
5. Set payment callback.
6. Initiate the payment using the payment object created from \[step 3]

We go through these step by step below.

#### Enable subscription flow flag

Add the Below entry to your Android manifest file. If you don't enable `cashfree_subscription_flow_enable` flag, SDK won't provide a payment callback.
<Note>It should be added inside application tag, not inside activity tag.</Note>

<CodeGroup>
  ```java java theme={"dark"}
    <application
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name">

        <meta-data
            android:name="cashfree_subscription_flow_enable"
            android:value="true"
            tools:replace="android:value"/>
    </application>
  ```
</CodeGroup>

#### Create a subscription session

This object contains essential information about the subscription, including the subscription session ID (`subscription_session_id`) and subscription ID (`subscription_id`) obtained from creation step. It also specifies the environment (sandbox or production).

<CodeGroup>
  ```java java theme={"dark"}
  CFSubscriptionSession cfSubsSession = new CFSubscriptionSession.CFSubscriptionSessionBuilder()
                      .setEnvironment(CFSubscriptionSession.Environment.SANDBOX)
                      .setSubscriptionSessionID(subscription_session_id)
                      .setSubscriptionId(subscription_id)
                      .build();
  ```

  ```kotlin kotlin theme={"dark"}
  val cfSubsSession = CFSubscriptionSessionBuilder()
      .setEnvironment(CFSubscriptionSession.Environment.SANDBOX)
      .setSubscriptionSessionID(subscription_session_id)
      .setSubscriptionId(subscription_id)
      .build()
  ```
</CodeGroup>

#### Customise theme (optional)

You can customise the appearance of the checkout screen using `CFWebCheckoutTheme`. This step is optional but can help maintain consistency with your app's design.
You can set the `NavigationBarBackgroundColor` which will set the colour for status bar and cashfree loader

<CodeGroup>
  ```java java theme={"dark"}
  CFWebCheckoutTheme cfTheme = new CFWebCheckoutTheme.CFWebCheckoutThemeBuilder()
      .setNavigationBarBackgroundColor("#6A3FD3")
      .build();
  ```

  ```kotlin kotlin theme={"dark"}
  val cfTheme = CFWebCheckoutThemeBuilder()
      .setNavigationBarBackgroundColor("#6A3FD3")
      .build()
  ```
</CodeGroup>

#### Create subscription payment object

<CodeGroup>
  ```java java theme={"dark"}
  CFSubscriptionPayment cfSubscriptionPayment = new CFSubscriptionPayment.CFSubscriptionCheckoutBuilder()
      .setSubscriptionSession(cfSubsSession)
      .setSubscriptionUITheme(cfTheme)
      .build();
  ```

  ```kotlin kotlin theme={"dark"}
  val cfSubscriptionPayment = CFSubscriptionCheckoutBuilder()
    .setSubscriptionSession(cfSubsSession)
    .setSubscriptionUITheme(cfTheme)
    .build()
  ```
</CodeGroup>

#### Setup payment callback

The SDK exposes an interface `CFSubscriptionResponseCallback` to receive callbacks from the SDK once the payment journey ends.

This interface consists of 2 methods:

<CodeGroup>
  ```java java theme={"dark"}
  void onSubscriptionVerify(CFSubscriptionResponse cfSubscriptionResponse);
  void onSubscriptionFailure(CFErrorResponse cfErrorResponse);
  ```

  ```kotlin kotlin theme={"dark"}
  fun onSubscriptionVerify(cfSubscriptionResponse: CFSubscriptionResponse)
  fun onSubscriptionFailure(cfErrorResponse: CFErrorResponse) 
  ```
</CodeGroup>

<Tip>Make sure to set the callback at activity's onCreate as this also handles the activity restart cases.</Tip>

<CodeGroup>
  ```java java theme={"dark"}
  public class YourActivity extends AppCompatActivity implements CFSubscriptionResponseCallback {
      ...
      @Override
      public void onSubscriptionVerify(CFSubscriptionResponse cfSubscriptionResponse) {
      }

      @Override
      public void onSubscriptionFailure(CFErrorResponse cfErrorResponse) {
      }

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

  }

  ```

  ```kotlin kotlin theme={"dark"}
  class YourActivity : AppCompatActivity(), CFSubscriptionResponseCallback {

      override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          setContentView(R.layout.activity_drop_checkout)
          try {
              CFPaymentGatewayService.getInstance().setSubscriptionCheckoutCallback(this)
          } catch (e: CFException) {
              e.printStackTrace()
          }
      }

      override fun onSubscriptionVerify(cfSubscriptionResponse: CFSubscriptionResponse) {
          Log.d("onSubscriptionVerify", "verifyPayment triggered")
      }

      override fun onSubscriptionFailure(cfErrorResponse: CFErrorResponse) {
          Log.e("onSubscriptionFailure", cfErrorResponse.message)
      }
  ...
  }
  ```
</CodeGroup>

#### Open checkout screen

Finally, call `doSubscriptionPayment()` to open the Cashfree Subscription checkout screen. This will present the user with the payment options and handle the payment process.

<CodeGroup>
  ```java java theme={"dark"}
  // replace the SubscriptionCheckoutActivity class with your class name
  CFPaymentGatewayService.getInstance().doSubscriptionPayment(SubscriptionCheckoutActivity.this, cfSubscriptionPayment);
  ```

  ```kotlin kotlin theme={"dark"}
  // replace the SubscriptionCheckoutActivity class with your class name
  CFPaymentGatewayService.getInstance().doSubscriptionPayment(this@SubscriptionCheckoutActivity, cfSubscriptionPayment)
  ```
</CodeGroup>

#### Sample code

<CodeGroup>
  ```java java theme={"dark"}
  package com.cashfree.sdk_sample.java;

  import android.os.Bundle;
  import android.text.TextUtils;
  import android.util.Log;
  import android.widget.Toast;

  import androidx.appcompat.app.AppCompatActivity;

  import com.cashfree.pg.api.CFPaymentGatewayService;
  import com.cashfree.pg.core.api.CFSubscriptionSession;
  import com.cashfree.pg.core.api.callback.CFSubscriptionResponseCallback;
  import com.cashfree.pg.core.api.exception.CFException;
  import com.cashfree.pg.core.api.subscription.CFSubscriptionPayment;
  import com.cashfree.pg.core.api.utils.CFErrorResponse;
  import com.cashfree.pg.core.api.utils.CFSubscriptionResponse;
  import com.cashfree.pg.core.api.webcheckout.CFWebCheckoutTheme;
  import com.cashfree.sdk_sample.R;

  public class SubscriptionCheckoutActivity extends AppCompatActivity implements CFSubscriptionResponseCallback {
      String subsID = "sub_1936672690";
      String subsSessionID = "sub_session_Axr2QtKpKwh4_dQypuNwtkpy0uZ8wWbwejEv7gYqrsej2jfXDpQPfDfJr999H-ay9ipYx4-2ZIV6MXX-d7vodyuEHVpDDH43yavnmPiK9kTtNosm";
      CFSubscriptionSession.Environment cfEnvironment = CFSubscriptionSession.Environment.SANDBOX;

      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_drop_checkout);
          try {
              CFPaymentGatewayService.getInstance().setSubscriptionCheckoutCallback(this);
              doSubscriptionCheckoutPayment();
          } catch (CFException e) {
              e.printStackTrace();
          }
      }

      @Override
      public void onSubscriptionVerify(CFSubscriptionResponse cfSubscriptionResponse) {
          Log.d("onSubscriptionVerify", "verifyPayment triggered");
          finish();
      }

      @Override
      public void onSubscriptionFailure(CFErrorResponse cfErrorResponse) {
          Log.d("onPaymentFailure " + subsID, cfErrorResponse.getMessage());
          finish();
      }

      public void doSubscriptionCheckoutPayment() {
          if (subsID.equals("ORDER_ID") || TextUtils.isEmpty(subsID)) {
              Toast.makeText(this, "Please set the subsId", Toast.LENGTH_SHORT).show();
              finish();
              return;
          }
          if (subsSessionID.equals("SUBS_SESSION_ID") || TextUtils.isEmpty(subsSessionID)) {
              Toast.makeText(this, "Please set the subs_session_id", Toast.LENGTH_SHORT).show();
              finish();
              return;
          }
          try {
              CFSubscriptionSession cfSession = new CFSubscriptionSession.CFSubscriptionSessionBuilder()
                      .setEnvironment(cfEnvironment)
                      .setSubscriptionSessionID(subsSessionID)
                      .setSubscriptionId(subsID)
                      .build();

              CFSubscriptionPayment cfSubscriptionPayment = new CFSubscriptionPayment.CFSubscriptionCheckoutBuilder()
                      .setSubscriptionSession(cfSession)
                      .setSubscriptionUITheme(new CFWebCheckoutTheme.CFWebCheckoutThemeBuilder()
                              .setNavigationBarBackgroundColor("#d11b1b")
                              .build())
                      .build();
              CFPaymentGatewayService gatewayService = CFPaymentGatewayService.getInstance();
              gatewayService.doSubscriptionPayment(SubscriptionCheckoutActivity.this, cfSubscriptionPayment);
          } catch (CFException exception) {
              exception.printStackTrace();
          }
      }
  }
  ```
</CodeGroup>

[Github Sample](https://github.com/cashfree/nextgen-android/blob/master/app/src/main/java/com/cashfree/sdk_sample/java/SubscriptionCheckoutActivity.java)

### Step 3: Confirming the payment <Badge color="green">Server-side</Badge>

After the payment is completed, you need to confirm whether the payment was successful by checking the subscription status. Once the payment finishes, the user will be redirected back to your activity to your implementation of the `CFSubscriptionResponseCallback` interface.

<Note>You must always verify payment status from your backend. Before delivering the goods or services, please ensure you check the subscription status from your backend. Ensure you check the subscription status from your server endpoint.</Note>

### Testing

You should now have a working checkout button that redirects your customer to Cashfree Subscription Checkout. If your integration isn’t working:

1. Open the Network tab in your browser’s developer tools.
2. Click the button and check the console logs.
3. Use console.log(session) inside your button click listener to confirm the correct error returned.

### Other options

<AccordionGroup>
  <Accordion title="(Optional) Enable logging to debugging issues">
    To enable SDK logging add the following to your `values.xml` file.

    `<integer name="cashfree_pg_logging_level">3</integer>`

    Following are the Logging levels.

    * VERBOSE = 2
    * DEBUG = 3
    * INFO = 4
    * WARN = 5
    * ERROR = 6
    * ASSERT = 7
  </Accordion>
</AccordionGroup>
