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
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
|
String Merchant's name. |
merchantKeymandatory
|
String Merchant key provided by PayU. |
phonemandatory
|
String Customer's phone number for registration. |
emailmandatory
|
String Customer email address. |
refIdmandatory
|
String Unique reference ID for tracking the transaction. |
pluginTypesmandatory
|
Array<String> Supported plugin types (e.g., AXIS, HDFC, BHIM). |
clientIdmandatory
|
String Unique 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
|
Boolean Environment 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
|
String Payment Gateway. |
Plugin Registration Status
PayUUPIBoltUICapacitorPlugin.isRegistered({ pg: "<pg>" });
UPI Management
PayUUPIBoltUICapacitorPlugin.openUPIManagement({ screenType: "<screenType>" });
Request Parameters
Parameter | Description |
---|---|
screenTypemandatory
|
String Specifies the type of management screen. Valid values: • ALL • TRANSACTIONHISTORY • MANAGEUPIACCOUNTS • DISPUTE • DEREGISTERUPI |
Register and Pay
Payment Parameters
Parameter | Description |
---|---|
amountmandatory
|
String Transaction amount. |
productInfomandatory
|
String Information about the product or service. |
firstNamemandatory
|
String Customer's first name. |
surlmandatory
|
String Android success URL. |
furlmandatory
|
String Android failure URL. |
ios_surlmandatory
|
String iOS success URL. |
ios_furlmandatory
|
String iOS failure URL. |
initiationModemandatory
|
String Mode of initiation (e.g., "10"). |
purposemandatory
|
String Purpose code (e.g., "00"). |
txnIdmandatory
|
String Unique transaction ID. |
udf1 - udf6optional
|
Any User-defined fields for additional transaction metadata. |
isCCTxnEnabledoptional
|
Boolean Enables 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
|
String String to be signed dynamically. |
hashNamemandatory
|
String Indicates the type of hash. |
postSaltoptional
|
String Additional 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:
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 18 days ago