Ionic Platform - SDK Integration
To merchants who have built their app on an ionic platform, PhonePe provides a bridge to conveniently integrate PhonePe SDK for the Android platform. In this document, we will highlight the steps required to integrate PhonePe SDK with an Ionic bridge for your app. This bridge helps you build a seamless and responsive checkout experience for your Android application.
This integration will support the following flows:
-
App Flow: In case the PhonePe app is installed, The bottom pop up PhonePe payment page
called QCLite flow will be launched to complete the transaction and give the response back to
your app. -
Redirection Flow: In case the PhonePe app is not installed, The android web view will be
launched to complete the transaction and give the response back to your app.
Android Project of Ionic app
- Add the below code to 'repositories' section of your project level build.gradle file
// Top-level build file where you can add configuration options common to all sub-projects/modules.
allprojects {
repositories {
google()
maven {
url "https://phonepe.mycloudrepo.io/public/repositories/phonepe-intentsdk-snapshots"
}
}
}
//https://dash.readme.com/project/phonepe-docs/v1/docs/android-pg-sdk-integration Top-level build file where you can add configuration options common to all sub-projects/modules.
allprojects {
repositories {
google()
maven {
url "https://phonepe.mycloudrepo.io/public/repositories/phonepe-intentsdk-android"
}
}
}
- Add the below line to the 'dependencies' section of your app build.gradle.
implementation 'phonepe.intentsdk.android.snapshot:IntentSDK:1.6.8-478638-SNAPSHOT@aar’
implementation 'phonepe.intentsdk.android.release:IntentSDK:1.6.8@aar’
For, SDK version 1.6.8
We have compileSdkVersion: 28, minSdkVersion: 21, targetSdkVersion: 28
- 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"/>
<!-- The value will be the MID-->
<meta-data
android:name="com.phonepe.android.sdk.MerchantId"
android:value="MID"/>
<!-- Get the App Id from PhonePe-->
<meta-data
android:name="com.phonepe.android.sdk.AppId"
android:value="<your app id given by PhonePe>"/>
-
Add PhonePeSDKPlugin to your project (see Appendix at the end of this document).
-
In the pre-existing MainApplication class while creating an instance of IonicHost there is a method
onCreate(). In this method add PhonePeSDKPlugin class in ionic Package List. -
Update handleOnActivityResult method in PhonePeSDKPlugin class as per your response
the requirement in the ionic native app. -
Call the startPaymentTransaction method from your Ionic Native app to invoke the PhonePe module.
Ionic Native Code
- Import Plugins from the capacitor package.
import { Plugins } from '@capacitor/core';
- Declare PhonePeSDKPlugin as per the ionic standards.
const { PhonePeSDKPlugin } = Plugins;
- In the ionic app.js
PhonePeSDKPlugin.doesPhonePeExists();
const isPhonePeAvailableListener =
Plugins.PhonePeSDKPlugin.addListener('isPhonePeAvailableListener', (value:any) =>
{
/* Display PhonePe option in the checkout page only if variable display returns true */
console.log('myPluginEvent was fired = '+value.isPhonePeAvailable);
});
Note
Install the PhonePe PreProd app. Refer to this link.
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.Remove the listener from the PhonePeSDKPlugin object:
isPhonePeAvailableListener.remove();
- Initiate the payment process by calling PhonePeSDKPlugin.startPaymentTransaction with the
appropriate parameters.
var data =
{
"base64EncodedData": “/* Pass the encoded base 64 data*/“,
"checksum": “/“* Pass the checksum value */,
"endpoint": “/* “End point */“,
"xCallbackUrl": “/* Pass the server url */“
};
PhonePeSDKPlugin.startPaymentTransaction(data);
-
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.
- Once you receive the UI callback from the handleOnActivityResult method. Kindly perform the
following:
-
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
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
package io.ionic.starter;
import android.content.Intent;
import com.getcapacitor.JSObject;
import com.getcapacitor.NativePlugin;
import com.getcapacitor.Plugin;
import com.getcapacitor.PluginCall;
import com.getcapacitor.PluginMethod;
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 java.util.HashMap;
@NativePlugin(
requestCodes = {
PhonePeSDKPlugin.PHONEPE_REQUEST
} // register request code(s) for
intent results
)
public class PhonePeSDKPlugin extends Plugin {
/**
* variables
*/
public static final int PHONEPE_REQUEST = 777;
public void load() {
// Called when the plugin is first constructed in the bridge
PhonePe.init(getContext());
}
/**
* Method to set whether PhonePe app is installed or not and send the event to the Ionic Code
*/
@PluginMethod
public void doesPhonePeExists(PluginCall call) {
try {
PhonePe.isUPIAccountRegistered(new ShowPhonePeCallback() {
@Override
public void onResponse(boolean b) {
JSObject mJSObject = new JSObject();
mJSObject.put("isPhonePeAvailable", "" + b);
notifyListeners("isPhonePeAvailableListener", mJSObject);
}
});
} catch (PhonePeInitException e) {
e.printStackTrace();
}
}
/**
* Method to launch the PhonePe payment page from the Ionic Native code
* @param call
*/
@PluginMethod
public void startPaymentTransaction(PluginCall call) {
saveCall(call);
String base64Body = call.getString("base64EncodedData");
String checksum = call.getString("checksum");
String endPoint = call.getString("endpoint");
String xCallbackUrl = call.getString("xCallbackUrl");
HashMap < String, String > headers = new HashMap();
headers.put("X-CHANNEL-ID", "phonepe_ionic_sdk");
TransactionRequest mTransactionRequest;
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(endPoint)
.setHeaders(headers)
.build();
} else {
mTransactionRequest = new TransactionRequestBuilder()
.setData(base64Body)
.setChecksum(checksum)
.setHeaders(headers)
.setUrl(endPoint)
.build();
}
try {
startActivityForResult(call, PhonePe.getTransactionIntent(mTransactionRequest), 777);
} catch (PhonePeInitException e) {}
call.success();
}
// in order to handle the intents result, you have to @Override handleOnActivityResult
@Override
protected void handleOnActivityResult(int requestCode, int resultCode, Intent data) {
super.handleOnActivityResult(requestCode, resultCode, data);
// Get the previously saved call
PluginCall savedCall = getSavedCall();
if (savedCall == null) {
return;
}
if (requestCode == PHONEPE_REQUEST) {
// Send the UI callback to the ionic app
}
}
}
MainActivity.java
package io.ionic.starter;
import android.os.Bundle;
import com.getcapacitor.BridgeActivity;
import com.getcapacitor.Plugin;
import java.util.ArrayList;
public class MainActivity extends BridgeActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Initializes the Bridge
this.init(savedInstanceState, new ArrayList < Class << ? extends Plugin >> () {
{
// Additional plugins you've installed go here
add(PhonePeSDKPlugin.class);
}
});
}
}
Updated about 1 year ago