UPI Bolt UI SDK Integration - Ionic
PayU UPI Bolt SDK offers a simpler and more efficient payment experience for merchants. It eliminates any third-party redirection, enhances the success rate, and improves the overall customer experience by reducing drop-offs.
Prerequisites
• iOS Deployment Target: iOS 17 and above • Android: Minimum supported configurations
iOS Integration
Sample code
Step 1: Add the following to your project:
npm add [email protected]Step 2: Set the minimum development target to iOS 13 or higher.
Step 3: Include the following xcframework files provided by PayU during onboarding:
• NPCI - CommonLibrary.xcframework
• AXIS - OlivePayLibrary.xcframework
Step 4: Modify Build Settings:
Add $(PROJECT_DIR)/Frameworks under Framework Search Path (if Xcode doesn't add it automatically).
Step 5: Include additional dependencies in the podfile:
pod 'PayUIndia-UPIBoltCoreKit', '1.0.0-alpha.7'Android Integration
Step 1: Add the following permissions in the AndroidManifest.xml:
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />Step 2: Include the library dependencies in build.gradle:
implementation 'in.payu:payu-upi-bolt-core-sdk:0.0.1-dev4'
implementation(files('libs/SecureComponent-release-prod_05062024_9d3904ab.aar'))Step 3: Add AAR file:
Place SecureComponent-release-prod_05062024_9d3904ab.aar under <your_project>/android/app/libs.
SDK Methods and Configurations
Initialize SDK
Import the Plugin
import { PayUUPIBoltUICapacitorPlugin } from 'payu-upi-bolt-ui-capacitor';Configuration Parameters
| Parameter | Description |
|---|---|
merchantNamemandatory
|
StringMerchant's name. |
merchantKeymandatory
|
StringMerchant key provided by PayU. |
phonemandatory
|
StringCustomer's phone number for registration. |
emailmandatory
|
StringCustomer email address. |
refIdmandatory
|
StringUnique reference ID for tracking the transaction. |
pluginTypesmandatory
|
Array<String>Supported plugin types (e.g., AXIS, HDFC, BHIM). |
clientIdmandatory
|
StringUnique client ID. |
issuingBanksoptional
|
Array<String>List of issuing banks supported (e.g., AXIS or HDFC). |
excludedBanksIINsoptional
|
Array<String>List of banks to exclude using IIN values. |
isProductionmandatory
|
BooleanEnvironment configuration: true for production, false for staging. |
Sample Code
const config = {
merchantName: "<merchantName>",
merchantKey: "<merchantKey>",
phone: "<phone>",
email: "<email>",
refId: "<refId>",
pluginTypes: ["<pluginType>"],
clientId: "<clientId>",
issuingBanks: ["<issuingBanks>"],
excludedBanksIINs: ["<excludedBanksIIN>"],
isProduction: <isProduction>,
};
// Initialize the SDK
PayUUPIBoltUICapacitorPlugin.initSDK({ config: JSON.stringify(config) });
// Clear SDK Instance
PayUUPIBoltUICapacitorPlugin.reset();Clear SDK Cache
PayUUPIBoltUICapacitorPlugin.clearCache({ pg: "<pg>" });Request Parameters
| Parameter | Description |
|---|---|
pgmandatory
|
StringPayment Gateway. |
Plugin Registration Status
PayUUPIBoltUICapacitorPlugin.isRegistered({ pg: "<pg>" });UPI Management
PayUUPIBoltUICapacitorPlugin.openUPIManagement({ screenType: "<screenType>" });Request Parameters
| Parameter | Description |
|---|---|
screenTypemandatory
|
StringSpecifies the type of management screen. Valid values: • ALL • TRANSACTIONHISTORY • MANAGEUPIACCOUNTS • DISPUTE • DEREGISTERUPI |
Register and Pay
Payment Parameters
| Parameter | Description |
|---|---|
amountmandatory
|
StringTransaction amount. |
productInfomandatory
|
StringInformation about the product or service. |
firstNamemandatory
|
StringCustomer's first name. |
surlmandatory
|
StringAndroid success URL. |
furlmandatory
|
StringAndroid failure URL. |
ios_surlmandatory
|
StringiOS success URL. |
ios_furlmandatory
|
StringiOS failure URL. |
initiationModemandatory
|
StringMode of initiation (e.g., "10"). |
purposemandatory
|
StringPurpose code (e.g., "00"). |
txnIdmandatory
|
StringUnique transaction ID. |
udf1 - udf6optional
|
AnyUser-defined fields for additional transaction metadata. |
isCCTxnEnabledoptional
|
BooleanEnables card fallback if supported – true or false. |
Sample Code
const paymentParams = {
amount: "<amount>",
productInfo: "<productInfo>",
firstName: "<firstName>",
surl: "<successUrl>",
furl: "<failureUrl>",
ios_surl: "<iosSuccessUrl>",
ios_furl: "<iosFailureUrl>",
initiationMode: "<initiationMode>",
purpose: "<purpose>",
txnId: "<txnId>",
isCCTxnEnabled: <trueOrFalse>,
};
PayUUPIBoltUICapacitorPlugin.registerAndPay({ paymentParams: JSON.stringify(paymentParams)});Hash Generation
Hash Parameters
| Parameter | Description |
|---|---|
hashStringmandatory
|
StringString to be signed dynamically. |
hashNamemandatory
|
StringIndicates the type of hash. |
postSaltoptional
|
StringAdditional salt that can be appended to the hash if provided. |
Sample Code
const handleHashGeneration = async (map) => {
const hashData = map.hashString;
const hashName = map.hashName;
// Fetch hash from your server
const hash = <fetch_hash_from_server>;
const hashMap = {
hashName: hashName,
[hashName]: hash
};
PayUUPIBoltUICapacitorPlugin.hashGenerated({ hashData: JSON.stringify(hashMap) });
};Listener Implementation
Setup Event Listeners
import { useEffect } from 'react';
import { Plugins } from '@capacitor/core';
useEffect(() => {
const listeners = [];
const addListener = (eventName, handler) => {
const listener = Plugins.PayUUPIBoltUICapacitorPlugin.addListener(eventName, handler);
listeners.push(listener);
};
// Success handler
const handleSuccess = (data) => {
console.log('Payment Success:', data);
// Handle success logic here
};
// Failure handler
const handleFailure = (data) => {
console.log('Payment Failure:', data);
// Handle failure logic here
};
// Hash generation handler
const handleHashGeneration = async (map) => {
const hashData = map.hashString;
const hashName = map.hashName;
const postSalt = map.postSalt || "";
// Generate hash on your server
const hash = await fetchHashFromServer(hashData, hashName, postSalt);
const hashMap = {
hashName: hashName,
[hashName]: hash
};
PayUUPIBoltUICapacitorPlugin.hashGenerated({
hashData: JSON.stringify(hashMap)
});
};
// Register listeners
addListener('onPayUSuccess', handleSuccess);
addListener('onPayUFailure', handleFailure);
addListener('generateHash', handleHashGeneration);
// Cleanup listeners on component unmount
return () => {
listeners.forEach(listener => listener.remove());
};
}, []);Error Codes and Messages
Response Codes
| Code | Message |
|---|---|
| 0 | Success |
| 1 | Fail / Invalid Response / Missing params |
| 2 | User cancelled the transaction |
| 100 | Transaction timeout |
| 103 | Handshake failed |
| 104 | UPI bolt not supported |
| 105 | Device not supported for UPI Bolt |
| 500 | Something went wrong |
| 501 | No internet connection |
| 502 | SDK not found |
SMS Hash Generation for Android OTP Auto-Read
To enable OTP auto-read functionality on Android, you need to generate an SMS hash for your application. Copy the following AppSignatureHelper class to your Android project:
Sample Code to Enable OTP auto-read functionality on Android
package com.payu.upipluginsampleapp;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.util.Base64;
import android.util.Log;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
public class AppSignatureHelper extends ContextWrapper {
public static final String TAG = AppSignatureHelper.class.getSimpleName();
private static final String HASH_TYPE = "SHA-256";
public static final int NUM_HASHED_BYTES = 9;
public static final int NUM_BASE64_CHAR = 11;
public AppSignatureHelper(Context context) {
super(context);
}
/**
* Get all the app signatures for the current package
* @return ArrayList of app signatures
*/
public ArrayList<String> getAppSignatures() {
ArrayList<String> appCodes = new ArrayList<>();
try {
String packageName = getPackageName();
PackageManager packageManager = getPackageManager();
Signature[] signatures = packageManager.getPackageInfo(packageName,
PackageManager.GET_SIGNATURES).signatures;
for (Signature signature : signatures) {
String hash = hash(packageName, signature.toCharsString());
if (hash != null) {
appCodes.add(String.format("%s", hash));
}
}
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Unable to find package to obtain hash.", e);
}
return appCodes;
}
private static String hash(String packageName, String signature) {
String appInfo = packageName + " " + signature;
try {
MessageDigest messageDigest = MessageDigest.getInstance(HASH_TYPE);
messageDigest.update(appInfo.getBytes(StandardCharsets.UTF_8));
byte[] hashSignature = messageDigest.digest();
// truncated into NUM_HASHED_BYTES
hashSignature = Arrays.copyOfRange(hashSignature, 0, NUM_HASHED_BYTES);
// encode into Base64
String base64Hash = Base64.encodeToString(hashSignature, Base64.NO_PADDING | Base64.NO_WRAP);
base64Hash = base64Hash.substring(0, NUM_BASE64_CHAR);
Log.d(TAG, String.format("pkg: %s -- hash: %s", packageName, base64Hash));
return base64Hash;
} catch (NoSuchAlgorithmException e) {
Log.e(TAG, "hash:NoSuchAlgorithm", e);
}
return null;
}
}Usage Example
// In your Android activity or application class
AppSignatureHelper appSignatureHelper = new AppSignatureHelper(this);
ArrayList<String> appSignatures = appSignatureHelper.getAppSignatures();
// Share the generated hash with PayU for configuration
for (String signature : appSignatures) {
Log.d("SMS_HASH", "App Signature: " + signature);
}Note: Share the generated SMS hash with PayU team for configuration to enable OTP auto-read functionality.
Updated 20 days ago
