React Native Platform - SDK Integration
To merchants who have built their app on the React Native platform, PhonePe provides a bridge to
conveniently integrate its SDK. In this document, we will highlight the steps required to integrate PhonePe SDK with React Native platform for your app. This platform helps merchants to build a seamless and responsive checkout experience for your 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. Once the customer completes the transaction, SDK gives
the response back to the merchant app -
Redirection Flow: In case the PhonePe app is not installed, an android web view will be launched
to complete the transaction. Once the customer completes the transaction, SDK gives the
response back to the merchant app
Follow the steps below to integrate PhonePe SDK in React Native app:
Android Project of React Native
- 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 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 PhonePeSDKManager and PhonePeSDKPackage in your project (see Appendix at the end
of this document). -
In the pre-existing MainApplication class while creating an instance of ReactNativeHost there is a
method getPackages(). In this method add PhonePeSDKPackage class in ReactPackage List. -
Update onActivityResult method in PhonePeSDKPackage class as per your response
the requirement in the react native app. -
Call startPaymentTransaction method from React Native app to invoke the PhonePe module.
React Native Code
- Import NativeModules and NativeEventEmitter from the react-native package
import { NativeModules, NativeEventEmitter } from 'react-native'
- Using NativeModule fetch the PhonePeSDKManager of Android project
const PhonePeSDKManager = NativeModules.PhonePeSDKManager;
- In react native app.js file implement the following piece of code to check whether the PhonePe
app is installed or not
const eventEmitterPhonePeCheck = new
NativeEventEmitter(NativeModules.PhonePeModule.doesPhonePeExists());
this.eventListenerPhonePeCheck =
eventEmitterPhonePeCheck.addListener('EventReminderPhonePeCheck', (event) =>
{
var display = event.CheckPhonePeInstalled;
/* Display PhonePe option in the checkout page only if variable display returns true */
console.log("Does PhonePe app is installed = "+display);
});
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.
- Start the process by calling PhonePeSDKManager.startPaymentTransaction with the appropriate
parameters
PhonePeSDKManager.startPaymentTransaction(base64EncodedBody, checksum, endpoint,
xCallbackUrl, uiCallbackHandler);
-
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. -
uiCallbackHandler - This is a react 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
PhonePeSDKManager.java
import android.app.Activity;
import android.content.Intent;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.facebook.react.bridge.ActivityEventListener;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
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;
import static android.app.Activity.RESULT_CANCELED;
import static android.app.Activity.RESULT_OK;
public class PhonePeSDKManager extends ReactContextBaseJavaModule implements
ActivityEventListener {
/**
* Global variables
*/
private static int PHONEPE_REQUEST = 777;
private Callback uiCallbackHandler;
/**
* Constructor
* @param reactContext
*/
public PhonePeSDKManager(@Nullable ReactApplicationContext reactContext) {
super(reactContext);
PhonePe.init(getReactApplicationContext());
reactContext.addActivityEventListener(this);
}
@NonNull
@Override
public String getName() {
return "PhonePeSDKManager";
}
/**
* Method to set whether PhonePe app is installed or not and send the event to the React Code
*/
@ReactMethod
public void doesPhonePeExists() {
try {
PhonePe.isUPIAccountRegistered(new ShowPhonePeCallback() {
@Override
public void onResponse(boolean b) {
WritableMap params = Arguments.createMap();
params = Arguments.createMap();
params.putBoolean("CheckPhonePeInstalled", b);
sendEvent(getReactApplicationContext(), "EventReminderPhonePeCheck", params);
}
});
} catch (PhonePeInitException e) {
e.printStackTrace();
}
}
/**
* Method to send the event to the React native code
* @param reactContext
* @param eventName
* @param params
*/
private void sendEvent(ReactContext reactContext,
String eventName,
@Nullable WritableMap params) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
}
/**
* Method to launch the PhonePe payment page from the React Native code
* @param base64Body
* @param checksum
* @param endPoint
* @param xCallbackUrl
* @param uiCallbackHandler
*/
@ReactMethod
public void startPaymentTransaction(String base64Body, String checksum, String endPoint,
String xCallbackUrl, Callback uiCallbackHandler) {
TransactionRequest mTransactionRequest;
this.uiCallbackHandler = uiCallbackHandler;
HashMap < String, String > headers = new HashMap();
headers.put("X-CHANNEL-ID", "phonepe_react_native_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(endPoint)
.setHeaders(headers)
.build();
} else {
mTransactionRequest = new TransactionRequestBuilder()
.setData(base64Body)
.setChecksum(checksum)
.setHeaders(headers)
.setUrl(endPoint)
.build();
}
try {
getReactApplicationContext().startActivityForResult(PhonePe.getTransactionIntent(mTransaction Request), 777, null);
} catch (PhonePeInitException e) {}
}
@Override
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
if (requestCode == PHONEPE_REQUEST) {
if (resultCode == RESULT_OK) {
this.uiCallbackHandler.invoke("User Completed");
} else if (resultCode == RESULT_CANCELED) {
this.uiCallbackHandler.invoke("User Cancelled");
}
}
}
@Override
public void onNewIntent(Intent intent) {}
}
PhonePeSDKPackage.java
import androidx.annotation.NonNull;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class PhonePeSDKPackage implements ReactPackage {
@NonNull
@Override
public List < NativeModule > createNativeModules(@NonNull ReactApplicationContext reactContext) {
List < NativeModule > modules = new ArrayList < > ();
modules.add(new PhonePeSDKManager(reactContext));
return modules;
}
@NonNull
@Override
public List < ViewManager > createViewManagers(@NonNull ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
Updated about 1 year ago