3.2 Initiate payment - UPI Intent Flow

UPI Intent Checkout flow

This flow is for merchants who wants to quickly provide UPI Intent functionality using cashfree's mobile SDK. In this flow, SDK provides a pre-built native Android screen to facilitate a quick integration with our payment gateway. Your customers will see a list of UPI apps installed in their phone which they can select to initiate payment.

This mode handles all the business logic and UI Components to make the payment smooth and easy to use. The SDK allows the merchant to customize the UI in terms of color coding, fonts and payment modes shown.

Initiating the payment

To initiate the UPI intent checkout payment in the SDK, follow these steps

  • Create a CFSession object.
  • Create a CFPaymentComponents object.
  • Create a CFTheme object.
  • Create a UPI Intent Checkout Payment object.
  • Set payment callback.
  • Initiate the payment using the payment object created from [step 4]

Create a session

The payment_session_id created from Step2 is used to authenticate the payment. The SDK exposes a class CFSession class which accepts the payment_session_id, Environment and order ID values.

Cashfree provides two environments, one being the sandbox environment for developers to test the payment flow and responses and the other being production environment which gets shipped to production. This environment can be set in this session object.

The values for environment can be either .SANDBOX or .PRODUCTION.

CFSession cfSession = new CFSession.CFSessionBuilder()
        .setEnvironment(CFSession.Environment.SANDBOX)
        .setPaymentSessionID("payment_session_id")
        .setOrderId("orderID")
        .build();
val cfSession = CFSessionBuilder()
  .setEnvironment(CFSession.Environment.SANDBOX)
  .setPaymentSessionID("payment_session_id")
  .setOrderId("orderID")
  .build()

Set a Theme

CFIntentTheme cfTheme = new new CFIntentTheme.CFIntentThemeBuilder()
        .setButtonBackgroundColor("#6A3FD3")
        .setButtonTextColor("#FFFFFF")
        .setPrimaryTextColor("#000000")
        .setSecondaryTextColor("#000000")
        .build();
val cfTheme = CFIntentThemeBuilder()
  .setPrimaryTextColor("#000000")
  .setBackgroundColor("#FFFFFF")
  .build()

The CFIntentThemeBuilder class used to create CFIntentTheme used to set the theming for UPI checkout screen.

Create a UPI Intent Checkout object

  • Code Snippet to create a CFUPIIntentCheckout object (pre-built UPI Intent UI SDK)
CFUPIIntentCheckout cfupiIntentCheckout = new CFUPIIntentCheckout.CFUPIIntentBuilder()
                                        // Use either the enum or the application package names to order the UPI apps as per your needed
                                        // Remove both if you want to use the default order which cashfree provides based on the popularity
                                        // NOTE - only one is needed setOrder or setOrderUsingPackageName
                                        .setOrder(Arrays.asList(CFUPIIntentCheckout.CFUPIApps.BHIM, CFUPIIntentCheckout.CFUPIApps.PHONEPE))
                                        .setOrderUsingPackageName(Arrays.asList("com.dreamplug.androidapp", "in.org.npci.upiapp"))
                                        .build();
val cfupiIntentCheckout =
                CFUPIIntentBuilder() // Use either the enum or the application package names to order the UPI apps as per your needed
                    // Remove both if you want to use the default order which cashfree provides based on the popularity
                    // NOTE - only one is needed setOrder or setOrderUsingPackageName
                    .setOrderUsingPackageName(Arrays.asList("com.dreamplug.androidapp", "in.org.npci.upiapp"))
                    .setOrder(Arrays.asList(CFUPIIntentCheckout.CFUPIApps.BHIM, CFUPIIntentCheckout.CFUPIApps.PHONEPE))
                    .build()

Create a UPI Intent Checkout Payment object

  • Code Snippet to create a payment object for UPI Intent Checkout (pre-built UI SDK)
CFUPIIntentCheckoutPayment cfupiIntentCheckoutPayment = new CFUPIIntentCheckoutPayment.CFUPIIntentPaymentBuilder()
                                .setSession(cfSession)
                                .setCfUPIIntentCheckout(cfupiIntentCheckout)
                                .setCfIntentTheme(cfTheme)
                                .build();
val cfupiIntentCheckoutPayment = CFUPIIntentPaymentBuilder()
  .setSession(cfSession)
  .setCfUPIIntentCheckout(cfupiIntentCheckout)
  .setCfIntentTheme(cfTheme)
  .build()

Setup Payment Callback

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

This protocol comprises of 2 methods:

  1. public void onPaymentVerify(String orderID)
  2. public void onPaymentFailure(CFErrorResponse cfErrorResponse, String orderID)
  • Code snippet demonstrating it's usage:
public class YourActivity extends AppCompatActivity implements CFCheckoutResponseCallback {
    ...
    @Override
    public void onPaymentVerify(String orderID) {

    }

    @Override
    public void onPaymentFailure(CFErrorResponse cfErrorResponse, String orderID) {

    }
  
    @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().setCheckoutCallback(this);
        } catch (CFException e) {
            e.printStackTrace();
        }
    }
    ...
}
class UPIIntentActivity : AppCompatActivity(), CFCheckoutResponseCallback {
  
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_drop_checkout)
        try {
            CFPaymentGatewayService.getInstance().setCheckoutCallback(this)
        } catch (e: CFException) {
            e.printStackTrace()
        }
    }

    override fun onPaymentVerify(orderID: String) {
        Log.d("onPaymentVerify", "verifyPayment triggered")
    }

    override fun onPaymentFailure(cfErrorResponse: CFErrorResponse, orderID: String) {
        Log.e("onPaymentFailure $orderID", cfErrorResponse.message)
    }
...
}

🚧

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


Sample Code

package com.cashfree.sdk_sample;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;

import com.cashfree.pg.api.CFPaymentGatewayService;
import com.cashfree.pg.core.api.CFSession;
import com.cashfree.pg.core.api.CFTheme;
import com.cashfree.pg.core.api.callback.CFCheckoutResponseCallback;
import com.cashfree.pg.core.api.exception.CFException;
import com.cashfree.pg.core.api.utils.CFErrorResponse;
import com.cashfree.pg.ui.api.upi.intent.CFIntentTheme;
import com.cashfree.pg.ui.api.upi.intent.CFUPIIntentCheckout;
import com.cashfree.pg.ui.api.upi.intent.CFUPIIntentCheckoutPayment;

public class UPIIntentCheckoutActivity extends AppCompatActivity  implements CFCheckoutResponseCallback {

    String orderID = "ORDER_ID";
    String paymentSessionID = "PAYMENT_SESSION_ID";
    CFSession.Environment cfEnvironment = CFSession.Environment.SANDBOX;

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

    @Override
    public void onPaymentVerify(String orderID) {
        Log.e("onPaymentVerify", "verifyPayment triggered");
      // Start verifying your payment 
    }

    @Override
    public void onPaymentFailure(CFErrorResponse cfErrorResponse, String orderID) {
        Log.e("onPaymentFailure " + orderID, cfErrorResponse.getMessage());
    }

    public void doUPIIntentCheckoutPayment() {
        try {
            CFSession cfSession = new CFSession.CFSessionBuilder()
                    .setEnvironment(cfEnvironment)
                    .setOrderToken(token)
                    .setOrderId(orderID)
                    .build();
            // Replace with your application's theme colors
            CFIntentTheme cfTheme = new new CFIntentTheme.CFIntentThemeBuilder()
                        .setButtonBackgroundColor("#6A3FD3")
                        .setButtonTextColor("#FFFFFF")
                        .setPrimaryTextColor("#000000")
                        .setSecondaryTextColor("#000000")
                        .build();

            CFUPIIntentCheckout cfupiIntentCheckout = new CFUPIIntentCheckout.CFUPIIntentBuilder()
                                        // Use either the enum or the application package names to order the UPI apps as per your needed
                                        // Remove both if you want to use the default order which cashfree provides based on the popularity
                                        // NOTE - only one is needed setOrder or setOrderUsingPackageName
                                        .setOrder(Arrays.asList(CFUPIIntentCheckout.CFUPIApps.BHIM, CFUPIIntentCheckout.CFUPIApps.PHONEPE))
                                        .setOrderUsingPackageName(Arrays.asList("com.dreamplug.androidapp", "in.org.npci.upiapp"))
                                        .build();

            CFUPIIntentCheckoutPayment cfupiIntentCheckoutPayment = new CFUPIIntentCheckoutPayment.CFUPIIntentPaymentBuilder()
                                .setSession(cfSession)
                                .setCfUPIIntentCheckout(cfupiIntentCheckout)
                                .setCfIntentTheme(cfTheme)
                                .build();
            CFPaymentGatewayService.getInstance().doPayment(UPIIntentCheckoutActivity.this, cfupiIntentCheckoutPayment);
        } catch (CFException exception) {
            exception.printStackTrace();
        }
    }
}
package com.cashfree.sdk_sample.kotlin

import androidx.appcompat.app.AppCompatActivity
import com.cashfree.pg.core.api.callback.CFCheckoutResponseCallback
import com.cashfree.pg.core.api.CFSession
import android.os.Bundle
import com.cashfree.sdk_sample.R
import com.cashfree.pg.api.CFPaymentGatewayService
import android.content.Intent
import android.app.Activity
import com.cashfree.pg.core.api.utils.CFErrorResponse
import android.text.TextUtils
import android.util.Log
import android.widget.Toast
import com.cashfree.pg.core.api.CFSession.CFSessionBuilder
import com.cashfree.pg.core.api.exception.CFException
import com.cashfree.pg.ui.api.upi.intent.CFIntentTheme
import com.cashfree.pg.ui.api.upi.intent.CFIntentTheme.CFIntentThemeBuilder
import com.cashfree.pg.ui.api.upi.intent.CFUPIIntentCheckout
import com.cashfree.pg.ui.api.upi.intent.CFUPIIntentCheckout.CFUPIIntentBuilder
import com.cashfree.pg.ui.api.upi.intent.CFUPIIntentCheckoutPayment
import com.cashfree.pg.ui.api.upi.intent.CFUPIIntentCheckoutPayment.CFUPIIntentPaymentBuilder

class UPIIntentActivity : AppCompatActivity(), CFCheckoutResponseCallback {
    var orderID = "ORDER_ID"
    var token = "TOKEN"
    var cfEnvironment = CFSession.Environment.SANDBOX
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_drop_checkout)
        try {
            CFPaymentGatewayService.getInstance().setCheckoutCallback(this)
            doDropCheckoutPayment()
        } catch (e: CFException) {
            e.printStackTrace()
        }
    }

    override fun onPaymentVerify(orderID: String) {
        Log.d("onPaymentVerify", "verifyPayment triggered")
    }

    override fun onPaymentFailure(cfErrorResponse: CFErrorResponse, orderID: String) {
        Log.e("onPaymentFailure $orderID", cfErrorResponse.message)
    }

    fun doDropCheckoutPayment() {
        try {
            val cfSession = CFSessionBuilder()
                .setEnvironment(cfEnvironment)
                .setPaymentSessionID(token)
                .setOrderId(orderID)
                .build()
            val cfTheme = CFIntentThemeBuilder()
                .setPrimaryTextColor("#000000")
                .setBackgroundColor("#FFFFFF")
                .build()
            val cfupiIntentCheckout =
                CFUPIIntentBuilder() // Use either the enum or the application package names to order the UPI apps as per your needed
                    // Remove both if you want to use the default order which cashfree provides based on the popularity
                    // NOTE - only one is needed setOrder or setOrderUsingPackageName
                    //                                        .setOrderUsingPackageName(Arrays.asList("com.dreamplug.androidapp", "in.org.npci.upiapp"))
                    //                                        .setOrder(Arrays.asList(CFUPIIntentCheckout.CFUPIApps.BHIM, CFUPIIntentCheckout.CFUPIApps.PHONEPE))
                    .build()
            val cfupiIntentCheckoutPayment = CFUPIIntentPaymentBuilder()
                .setSession(cfSession)
                .setCfUPIIntentCheckout(cfupiIntentCheckout)
                .setCfIntentTheme(cfTheme)
                .build()
            CFPaymentGatewayService.getInstance().doPayment(this@UPIIntentActivity, cfupiIntentCheckoutPayment)
        } catch (exception: CFException) {
            exception.printStackTrace()
        }
    }
}

📘

Verify Payment

As a best practise you should always verify the payment status from your backend. Refer here for details steps on how to verify payment.


Resources

Cashfree UPI intent Simulator App