Android SDK

In this article, you will learn how to integrate our Android Checkout SDK into your applications.

We have created our Android SDK to make it easy for our merchants to integrate and customize their subscription checkout flows. Our Android SDK supports Android SDK version 21 and above.

Gradle Changes

Add Cashfree maven repository

Add to your module build.gradle file if your gradle version is less than 6.+ or below.

repositories 
{
    maven 
    { 
      url 'https://maven.cashfree.com/release'
    }
}

If you are using Gradle version 7.+ in your project then add the maven repository in your settings.gradle file

dependencyResolutionManagement {
  repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
  repositories {
  ...
    maven 
    { 
      url 'https://maven.cashfree.com/release'
    }
  }
}

add the following lines to the dependencies section of the app build.gradle file

implementation 'com.cashfree.subscription:coresdk:0.0.1'

Initiate Web Checkout flow

To initiate the Web checkout flow in the SDK, follow these steps

  • Create a CFSubscriptionPayment checkout object.
  • Set checkout callback.
  • Do the payment using the subscription checkout object created in Step 1

Create a CFSubscriptionPayment checkout object

val checkoutObject = CFSubscriptionPayment("paymentLink")
CFSubscriptionPayment checkoutObject = new CFSubscriptionPayment(url);

Setup Checkout Callback

The SDK exposes an interface CFCheckoutResponseCallback to receive callbacks from the SDK once the payment flow ends.

This protocol comprises 2 methods:

  1. fun onPaymentVerify(response: CFSubscriptionResponse)
  2. fun onPaymentCancelled(error: CFErrorResponse)

In case of payment success/failure, onPaymentVerify will be triggered.
In case of payment is canceled by the user, onPaymentCancelled will be triggered.

  • Code snippet demonstrating its usage:
private fun addPaymentCallback() {
        CFSubscriptionPaymentService.setCheckoutCallback(object : CFCheckoutResponseCallback {
            override fun onPaymentVerify(response: CFSubscriptionResponse) {
                Log.d(TAG, "Verify-->>$response")
                
            }

            override fun onPaymentCancelled(error: CFErrorResponse) {
                Log.d(TAG, "Cancel-->>$error")
            }
        })
    }
private void addPaymentCallback() {
        CFSubscriptionPaymentService.INSTANCE.setCheckoutCallback(new CFCheckoutResponseCallback() {

            @Override
            public void onPaymentVerify(@NonNull CFSubscriptionResponse cfSubscriptionResponse) {
                Log.d(TAG, "Verify-->>"+ cfSubscriptionResponse);
            }

            @Override
            public void onPaymentCancelled(@NonNull CFErrorResponse cfErrorResponse) {
                Log.d(TAG, "Failure-->>"+ cfErrorResponse);
            }
        });
    }

📘

Callback

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

Do payment

Using the checkout object created in 1st Step, make a call to thedoPayment method. This accepts context and checkout object as params.

CFSubscriptionPaymentService.doPayment(this, CFSubscriptionPayment(url))
CFSubscriptionPaymentService.INSTANCE.doPayment(this, new CFSubscriptionPayment(url));

Sample Code

package com.cashfree.susbcription.sample

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import com.cashfree.subscription.coresdk.channel.CFCheckoutResponseCallback
import com.cashfree.subscription.coresdk.models.CFErrorResponse
import com.cashfree.subscription.coresdk.models.CFSubscriptionPayment
import com.cashfree.subscription.coresdk.models.CFSubscriptionResponse
import com.cashfree.subscription.coresdk.services.CFSubscriptionPaymentService
import com.cashfree.susbcription.sample.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

    private val TAG = "SubscriptionPayment"
    private lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        handlePaymentClick()
        addPaymentCallback()
        binding.tiePaymentUrl.setText("https://cfre.in/gjxrigv")
    }

    private fun handlePaymentClick() {
        binding.btnMakePayment.setOnClickListener {
            val paymentLink = binding.tiePaymentUrl.text.toString()
            if (paymentLink.isEmpty().not()) openWebPaymentFlow(paymentLink)
            else showToast("Payment Link can't be empty")
        }
    }

    private fun openWebPaymentFlow(url: String) {
        CFSubscriptionPaymentService.doPayment(this, CFSubscriptionPayment(url))
    }

    private fun addPaymentCallback() {
        CFSubscriptionPaymentService.setCheckoutCallback(object : CFCheckoutResponseCallback {
            override fun onPaymentVerify(response: CFSubscriptionResponse) {
                Log.d(TAG, "Verify-->>$response")
            }

            override fun onPaymentCancelled(error: CFErrorResponse) {
                Log.d(TAG, "Cancelled-->>$error")
            }
        })
    }


    private fun showToast(message: String) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
    }

}
package com.cashfree.susbcription.sample;

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

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.cashfree.subscription.coresdk.channel.CFCheckoutResponseCallback;
import com.cashfree.subscription.coresdk.models.CFErrorResponse;
import com.cashfree.subscription.coresdk.models.CFSubscriptionPayment;
import com.cashfree.subscription.coresdk.models.CFSubscriptionResponse;
import com.cashfree.subscription.coresdk.services.CFSubscriptionPaymentService;
import com.cashfree.susbcription.sample.databinding.ActivityMainBinding;

public class MainActivityJava extends AppCompatActivity {

    private static final String TAG = "MainActivityJava";
    private ActivityMainBinding binding;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        handlePaymentClick();
        addPaymentCallback();
        binding.tiePaymentUrl.setText("https://cfre.in/gjxrigv");
    }

    private void handlePaymentClick() {
        binding.btnMakePayment.setOnClickListener(v -> {
            String paymentLink = binding.tiePaymentUrl.getText().toString();
            if (!paymentLink.isEmpty()) openWebPaymentFlow(paymentLink);
            else showToast("Payment Link can't be empty");
        });
    }

    private void openWebPaymentFlow(String url) {
        CFSubscriptionPaymentService.INSTANCE.doPayment(this, new CFSubscriptionPayment(url));
    }

    private void addPaymentCallback() {
        CFSubscriptionPaymentService.INSTANCE.setCheckoutCallback(new CFCheckoutResponseCallback() {

            @Override
            public void onPaymentVerify(@NonNull CFSubscriptionResponse cfSubscriptionResponse) {
                Log.d(TAG, "Verify-->>"+ cfSubscriptionResponse);
            }

            @Override
            public void onPaymentCancelled(@NonNull CFErrorResponse cfErrorResponse) {
                Log.d(TAG, "Failure-->>"+ cfErrorResponse);
            }
        });
    }


    private void showToast(String message) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
    }

}

❗️

You must always verify subscription status from your backend

Before starting subscription or showing success, please ensure you call check the Subscription status from your backend.

Advance SDK Configuration

Enable logging to debug issues

If you are facing trouble during payment, you can look at the SDK debug logs to try and identify the issue.
To enable SDK logging add the following to your AndroidManifest file.

 <meta-data
        android:name="subscription_logging_level"
        android:value="3"
        tools:replace="android:value" />

Following are the Logging levels.

  • VERBOSE = 2
  • DEBUG = 3
  • INFO = 4
  • WARN = 5
  • ERROR = 6
  • ASSERT = 7

🚧

Note

Make sure to set the logging level back to value '4' before going live.

You can use our sample Android app project mentioned below as a reference for this SDK integration.

Github Sample


What’s Next