Cordova Platform - SDK Integration

To merchants who have built their app on a Cordova platform, PhonePe provides a bridge to conveniently integrate PhonePe SDK for both Android. On this page, we will highlight the steps required to integrate PhonePe SDK with Cordova plugin for your app. This bridge will help you to build a seamless and responsive checkout experience for your Android application.

This integration will support the following flows:

  • UPI Intent Flow: In case the PhonePe app is installed, PhonePe intent flow will be launched to complete the transaction and send the response back to your app

  • Redirection Flow: In case the PhonePe app is not installed, PhonePe SDK will open a web-view
    to process transactions and give a response back to your app

Android Project of Cordova Plug-In

  1. Add the line below to the ‘repositories’ section of your project-level build.gradle file.
maven {
    url "https://phonepe.mycloudrepo.io/public/repositories/phonepe-intentsdk-android"
}
  1. Add the line below to the ‘dependencies’ section of your app build.gradle.
implementation 'phonepe.intentsdk.android.release:IntentSDK:1.6.4'
implementation 'com.google.android.gms:play-services-ads-identifier:16.0.0'
  1. Add below lines of code inside the application tag in the AndroidManifest.xml file
<!-- Keep it false in production environment-->
<meta-data
    android:name="com.phonepe.android.sdk.Debuggable"
    android:value="true"/>

<!-- Keep it false in production environment-->
<meta-data
    android:name="com.phonepe.android.sdk.isUAT"
    android:value="true"/>

<!-- Get the App Id from PhonePe-->
<meta-data
  android:name="com.phonepe.android.sdk.AppId"
  android:value="<your app id given by PhonePe>"/>
  1. Add PhonePeSDKPlugin to your project (see Appendix at the end of this document).

  2. Add the OnActivityResult method in the PhonePeSDKPlugin class as per your response requirement in the cordova plug-in.

  3. Call Cordova.exec() method from your Cordova Native app to invoke the PhonePe module.

Cordova Plug-In code

  1. In the .js file add the following to check whether PhonePe app is installed or Not:
Cordova.exec(success, error, "PhonePeSDKPlugin", "shouldShow");

function success(result)
{
    // If the result is true then Display PhonePe option in the check out page. If result is false then Do not
    display the PhonePe option in the checkout page
    alert(result);
};

function error(result)
{
    // Something went wrong
    alert(result);
};

🚧

Note

  1. Install the PhonePe PreProd app. Refer to this link.

  2. If returns true then display the PhonePe option on the checkout page or if returns false then
    do not display the PhonePe option on the checkout page.

  1. In the .js file add the following to initiate the payment process:
Cordova.exec(success, error, "PhonePeSDKPlugin", "startPaymentTransaction",
[“base64EncodedData”,”x-verify value” , ”end point” , “x-“callback-url optional parameter“]);
  • base64EncodedBody - pass the encoded payload request

  • checksum - pass the checksum value

  • endPoint - pass the endpoint

  • xCallbackUrl - This can be “” or else you can send your custom callback URL where you
    will receive the server to server callback response to your custom callback URL. Once
    the response is received you have to validate the checksum and invalid amount. Refer to this
    link for more details.

  • success/error - This is a Cordova plugin method that will receive a user interface
    callback response from the startPaymentTransaction method.

function uiCallbackHandler(data)
{
    /*This callback indicates only about completion of UI flow.
    Inform your server to make the transaction
    status call to get the status. Update your app with the
    success/failure status.*/
}

🚧

Note

  • If data returns User Completed it indicates the payment has been completed.
  • If data returns User Cancelled it indicates the payment has been canceled just in case if the user presses the back button or aborts the transaction.
  • Inform merchant server about the completion of the transaction flow from merchant app

  • Merchant server should check the status with server to server callback or make the Check
    Transaction Status API call to the PhonePe server to check the transaction status (Even
    for User Cancelled callback)

  • The app should get the transaction status from the backend

  • Based on the result, the merchant must inform the user about the success or failure status
    of the transaction

🚧

Note

Kindly maintain the parameter order sequence

References

  • For Accept Payment API, Refer to this link.

  • Use the Check Transaction Status API to check the status of the payment transaction. Refer to
    this link.

  • For refund API, Refer to this link.

Appendix

PhonePeSDKPlugin.java

import android.content.Intent;
import com.phonepe.intent.sdk.api.PhonePe;
import com.phonepe.intent.sdk.api.PhonePeInitException;
import com.phonepe.intent.sdk.api.ShowPhonePeCallback;
import com.phonepe.intent.sdk.api.TransactionRequest;
import com.phonepe.intent.sdk.api.TransactionRequestBuilder;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;
import org.json.JSONArray;
import org.json.JSONException;
import java.util.HashMap;
import static android.app.Activity.RESULT_CANCELED;
import static android.app.Activity.RESULT_OK;
/**
 * This class echoes a string called from JavaScript.
 */
public class PhonePeSDKPlugin extends CordovaPlugin {
    /**
     * Global variables
     */
    public static int PHONEPE_REQUEST = 777;
    public static CallbackContext uiCallbackHandler;
    @Override
    public boolean execute(String action, JSONArray data, CallbackContext uiCallbackHandler)
    throws JSONException {
        // Initiate PhonePe SDK
        PhonePe.init(cordova.getContext());
        this.uiCallbackHandler = uiCallbackHandler;
        if (action.equalsIgnoreCase("shouldShow")) {
            try {
                PhonePe.isUPIAccountRegistered(new ShowPhonePeCallback() {
                    @Override
                    public void onResponse(boolean b) {
                        uiCallbackHandler.success("" + b);
                    }
                });
            } catch (PhonePeInitException e) {
                e.printStackTrace();
            }
            return true;
        } else if (action.equalsIgnoreCase("startPaymentTransaction")) {
            String base64Body = data.getString(0);
            String checksum = data.getString(1);
            String apiEndPoint = data.getString(2);
            String xCallbackUrl = data.getString(3); // Optional parameter
            TransactionRequest mTransactionRequest;
            HashMap < String, String > headers = new HashMap();
            headers.put("X-CHANNEL-ID", "phonepe_cordova_sdk");
            if (xCallbackUrl != null && xCallbackUrl.length() != 0 && !xCallbackUrl.isEmpty()) {
                headers.put("X-CALLBACK-URL", xCallbackUrl);
                headers.put("X-CALL-MODE", "POST");
                mTransactionRequest = new TransactionRequestBuilder()
                    .setData(base64Body)
                    .setChecksum(checksum)
                    .setUrl(apiEndPoint)
                    .setHeaders(headers)
                    .build();
            } else {
                mTransactionRequest = new TransactionRequestBuilder()
                    .setData(base64Body)
                    .setChecksum(checksum)
                    .setHeaders(headers)
                    .setUrl(apiEndPoint)
                    .build();
            }
            try {
                cordova.startActivityForResult(this,
                    PhonePe.getTransactionIntent(mTransactionRequest), PHONEPE_REQUEST);
            } catch (PhonePeInitException e) {
                e.printStackTrace();
            }
            return true;
        }
        return false;
    }
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        if (requestCode == PHONEPE_REQUEST) {
            if (resultCode == RESULT_OK) {
                this.uiCallbackHandler.success("User Completed");
            } else if (resultCode == RESULT_CANCELED) {
                this.uiCallbackHandler.success("User Cancelled");
            }
        }
    }
}