Cordova UPI Bolt UI SDK
PayU UPI Bolt SDK will provide a simpler and more efficient payment experience to the merchants. It will eliminate any third-party redirection and higher success rate. Profile management including accounts and balances for users. Enhancing the overall customer experience and decreasing customer drop-offs.
Advantages
- One-click payment journey and no hassle of redirection to a third-party UPI application.
- Quick completion of transactions because of direct integration with the bank.
- Seamless user experience to the customers with in-app payment.
- Easy to integrate and get the advantage of existing customer profiles created with banks.
- 5-6% higher success rate and better transaction conversion.
- Merchants can take advantage of a complete user funnel to understand user behavior.
User Journeys in PayU UPI Bolt
Registration and Pay
- Merchant Application can do the User registration for customers who are coming first time for PayU UPI Bolt. The Registration can be done during the checkout process or it can be called in a separate user journey. In case of Merchant is using PayU Checkout Pro SDK, PayU will take care of customer registration.
- Once the registration process is initiated, the user will be asked to accept the SMS sending permissions required to verify the SIM card. If the phone has dual SIM, the SIM card selection screen will be shown to customers to select the specific SIM card.
- After the device verification, UPI ID creation and the Bank selection will be done. Add bank journey will be completed after adding a bank account connected to the same mobile number used for device verification.
- Finally, customers can do a transaction using the added bank account. In case the customer is using the bank account for the first time they will need to set the MPIN as well.
- Finally, customers can make a transaction using the added bank account. If the customer is using the bank account for the first time, he will also need to set the MPIN.

Pay
- Customers who are already registered with PayU UPI Bolt can make a One-click payment.
- The customer needs to select the already added bank account and enter the MPIN and the transaction will be completed.
- The customer can also check the balance before making a transaction to avoid low-balance transaction failure.

Profile Management Journey
- Customers can add new bank accounts, set MPIN, change MPIN, reset MPIN, delete accounts, and check the balance of already added bank accounts.
- Transaction history can be seen and queries can be raised and resolved within the PayU UI Bolt SDK.
- Customers can see all the raised disputes from the Dispute history screen.
- Customers can also deregister their all accounts with PayU UI Bolt SDK.

Steps to Integrate PayU Bolt SDK
Prerequisites
Supported iOS deployment target - iOS 17 and above.
Merchants who want to integrate only PayU UPI Bolt with their app. They can manage the checkout options on their checkout screen. Although they can use PayU UPI Bolt UI SDK for customer registration, payment, and profile management.
To include the PayU UPI Bolt UI SDK in your project, add the following dependency to your package.json file:
UAT:
cordova plugin add [email protected]PRODUCTION:
cordova plugin add [email protected]Ensure that the application's minimum development target is set to version 13 or higher.
iOS Integration
To include the PayU UPI Bolt UI SDK in your project, add the following code snippet to your podfile.
Supported iOS deployment target - iOS 17 and above.
The following xcframework files will be provided by PayU during onboarding:
- NPCI - CommonLibrary.xcframework
- AXIS - OlivePayLibrary.xcframework
Add these framework in your project. The added framework is similar to the following screeshot:

In Build Settings > Framework Search Path, add $(PROJECT_DIR)/Frameworks if it is not added automatically by Xcode.

Also, add the following dependency to the podfile of your Xcode app if not exists.
UAT:
pod 'PayUIndia-UPIBoltCoreKit', '3.0.0-alpha.1'PRODUCTION:
pod 'PayUIndia-UPIBoltCoreKit', '1.1.0'Android Integration
Add the following permissions in your AndroidManifest file.
<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" />UAT:
implementation 'in.payu:payu-upi-bolt-core-sdk:0.0.6-SNAPSHOT'Project-level build.gradle :
allprojects {
repositories {
maven {url "https://central.sonatype.com/repository/maven-snapshots/"}
}
}PRODUCTION:
implementation 'in.payu:payu-upi-bolt-core-sdk:0.0.5’Add the following dependency in the build.gradle file of your android app module:
implementation(files('libs/SecureComponent-release-prod_05062024_9d3904ab.aar'))Add the given aar file in the libs folder of your android app module:
<your_project>/android/app/libs/SecureComponent-release-prod_05062024_9d3904ab.aarStep 1: Initialization
It is used to initialize the SDK. This method returns an object that will be used to access other methods available in PayUUPIBoltUI.
Initialize the SDK with configuration:
const config = {
merchantName: "<merchantName>", // String
merchantKey: "<merchantKey>" // String,
phone: "<phone>", // String
email: "<email>", // String
refId: "<refId>", // String
pluginTypes: ["<pluginType>"], // Array<String>
clientId: [<clientId>], // String
issuingBanks: ["<issuingBanks>"], // Array<String>
excludedBanksIINs: ["<excludedBanksIIN>"], // Array<String>
isProduction: <isProduction> // Bool
};
// To initialize the SDK
cordova.plugins.PayUUpiBoltUiCordova.initSDK(this.responseCallBack, config);
// To clear the SDK Instance
cordova.plugins.PayUUpiBoltUiCordova.reset(this.responseCallBack);
The following fields are needed as a request for this API:
| Parameter | Description | Example |
|---|---|---|
configmandatory |
Map PayUUPIBoltBaseConfig includes the below fields. |
{...} |
merchantNamemandatory |
String Merchant Name |
"MyStore Inc" |
merchantKeymandatory |
String PayU Merchant Key |
"gtKFFx" |
phonemandatory |
String Phone number for registration |
"+919876543210" |
emailmandatory |
String Customer Email Id |
"[email protected]" |
pluginTypesmandatory |
Array<String> List of Supported Plugin (Values - AXIS or HDFC or BHIM) |
["AXIS", "HDFC", "BHIM"] |
isProductionmandatory |
Boolean Prod - true, staging - false |
true |
excludedBanksIINsoptional |
Array<String> List of Bank's IIN to exclude |
["123456", "789012"] |
clientIdoptional |
String Unique client ID |
"CLIENT_001" |
refIdmandatory |
String Unique reference ID |
"REF_12345678" |
issuingBanksoptional |
Array<String> List of Issuing Bank's (Values - AXIS or HDFC) |
["AXIS", "HDFC"] |
Clear SDK Cache of PayUBolt SDK
The clearCache method is used to clear the cache corresponding to the passed PG value.
PayUUpiBoltUiCordova.clearCache(this.responseCallBack, pg);The following fields are needed as a request for this API:
Field | Definition |
|---|---|
pg
|
|
Response: `Refer to SDK Response JSON Format
Check Plugin Registration Status of PayUBolt SDK
The isRegistered method is used to check pg registration status.
cordova.plugins.PayUUpiBoltUiCordova.isRegistered(this.responseCallBack, pg);Field | Definition |
|---|---|
pg
|
|
Response: `Refer to SDK Response JSON Format
Callback: The callback will have the below response format.
Step 2. Check if UPI Bolt is Enabled
This method is used to check whether the upi bolt is enabled for the merchant or not.
cordova.plugins.PayUUpiBoltUiCordova.isUPIBoltEnabled(this.responseCallBack);Response: `Refer to SDK Response JSON Format
| Field | Definition |
|---|---|
| code | Integer Status code (Success = 0, Failure = 1) |
| message | String Message |
Step 3. Register and Pay
This API allows you to initialize registration and payment flow. It will internally authenticate and register the customer. After successful authentication and registration, the user will follow the payment journey. Once payment is completed, based on the payment status the merchant will get a callback through the listener.
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 currentTimeMillis = new Date().getTime();
const paymentParams = {
amount: "<amount>", // String
productInfo: "<productInfo>", // String
firstName: "<firstName>", // String
surl: "<successUrl>", // String (Android success URL)
furl: "<failureUrl>", // String (Android failure URL)
ios_surl: "<iosSuccessUrl>", // String (iOS success URL)
ios_furl: "<iosFailureUrl>", // String (iOS failure URL)
initiationMode: "<initiationMode>", // String (e.g., "10")
purpose: "<purpose>", // String (e.g., "00")
udf1: "<udf1>", // String (Optional)
udf2: "<udf2>", // String (Optional)
udf3: "<udf3>", // String (Optional)
udf4: "<udf4>", // String (Optional)
udf5: "<udf5>", // String (Optional)
txnId: "<txnId>", // String (Unique transaction ID)
isCCTxnEnabled: <trueOrFalse> // Boolean (Enable card fallback if supported)
};
cordova.plugins.PayUUpiBoltUiCordova.registerAndPay(responseCallBack, paymentParams);Response: Map Refer to SDK Response JSON Format.
| Field | Definition |
|---|---|
| result | Payment Response |
Step 4. Open UPI Management
This API allows you to manage UPI accounts and transaction history.
// Screen Types
const screenType = <screenType> // String
cordova.plugins.PayUUpiBoltUiCordova.openUPIManagement(responseCallBack, screenType);Request Parameters
| Parameter | Description |
|---|---|
screenTypemandatory
|
StringSpecifies the type of management screen. Valid values: • ALL • TRANSACTIONHISTORY • MANAGEUPIACCOUNTS • DISPUTE • DEREGISTERUPI |
Response: Map Refer to SDK Response JSON Format
Step 5. Listener/Callback logic
The listener/callback contains following methods where the merchant app will get the API response and hash-related callbacks.
var responseCallBack = function (response) {
console.log('responseCallBack:', JSON.stringify(response));
// 1. onPayUSuccess(Map response): Triggered when the payment is successful.
if ('onPayUSuccess' in response) {
showAlert(JSON.stringify(response));
return;
}
// 2. onPayUFailure(Map response): Triggered when the payment fails.
if ('onPayUFailure' in response) {
showAlert(JSON.stringify(response));
return;
}
// 3. onPayUCancel(Map response): Triggered when the user cancels the payment.
if ('onPayUCancel' in response) {
showAlert(JSON.stringify(response));
return;
}
// 4. onError(Map response): Triggered when an error occurs in the SDK.
if ('onError' in response) {
showAlert(JSON.stringify(response));
return;
}
// 5. isUPIBoltEnabled(Map response): Indicates whether the UPI Bolt SDK is enabled.
if ('isUPIBoltEnabled' in response) {
showAlert(JSON.stringify(response));
return;
}
// 6. onReset(Map response): Confirms that the SDK instance has been reset successfully.
if ('onReset' in response) {
showAlert(JSON.stringify(response));
return;
}
// 7. onClearCache(Map response): Confirms that the SDK cache has been cleared.
if ('onClearCache' in response) {
showAlert(JSON.stringify(response));
return;
}
// 8. onIsRegistered(Map response): Indicates the user's registration status with the plugin.
if ('onIsRegistered' in response) {
showAlert(JSON.stringify(response));
return;
}
// 9. onInitSDK(Map response): Triggered after SDK initialization, including any initialization errors.
if ('onInitSDK' in response) {
showAlert(JSON.stringify(response));
return;
}
// 10. generateHash(Map response): Triggered when the SDK requests hash generation.
if ('generateHash' in response) {
handleHashGeneration(response);
return;
}
}; Step 6. Hash Generation Logic
The PayU SDKs use hashes to ensure the security of the transaction and prevent any unauthorized intrusion or modification.
For generating and passing dynamic hashes, the merchant will receive a call from the generateHash method of PayUUPIBoltUiListener. The generateHash() method is called by the SDK each time it needs an individual hash.
/**
* Handles hash generation requested by the PayU UPI Bolt SDK.
*
* The merchant receives a JSON object containing details required to generate the hash.
* The following keys must be checked in the response:
* 1. hashString – The string that needs to be hashed
* 2. hashName – The name of the hash
* 3. postSalt – (Optional) Additional salt value
*
* Hash Generation Steps:
* - Append your merchant salt to the hashString
* - If postSalt is present, append it after the merchant salt
* - Generate the hash using the SHA-512 algorithm
* - Pass the generated hash back to the SDK using hashGenerated()
*/
function handleHashGeneration(response) {
const resultValue = response.generateHash;
const hashString = resultValue.hashString;
const hashName = resultValue.hashName;
const postSalt = resultValue.postSalt;
/*
* NOTE:
* For security reasons, hash generation should be done on the server.
* Fetch the generated hash from your backend using hashString.
*/
// Fetch the hash value from your server
const hash = <fetch_hash_from_server>;
// Prepare hash map to send back to SDK
const hashMap = {};
hashMap["hashName"] = hashName;
hashMap[hashName] = hash;
// Pass the generated hash to the PayU UPI Bolt SDK
cordova.plugins.PayUUpiBoltUiCordova.hashGenerated(hashMap);
}SDK Response JSON Format
| Field | Data Type | Definition |
|---|---|---|
| result | Any? | Contains response model if received success callback |
| code | Int | Ref. Response Codes and Messages section |
| message | String? | Ref. Response Codes and Messages section |
| responseType | Int | Ref. ResponseType : |
Error Codes and Error Message List
| Response 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
Copy AppSignatureHelper class given below in your 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;
/**
* This is a helper class to generate your message hash to be included in your SMS message.
*
* Without the correct hash, your app won't recieve the message callback. This only needs to be
* generated once per app and stored. Then you can remove this helper class from your code.
*/
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
*/
public ArrayList<String> getAppSignatures() {
ArrayList<String> appCodes = new ArrayList<>();
try {
// Get all package signatures for the current package
String packageName = getPackageName();
PackageManager packageManager = getPackageManager();
Signature[] signatures = packageManager.getPackageInfo(packageName,
PackageManager.GET_SIGNATURES).signatures;
// For each signature create a compatible hash
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;
}
}
Log the value generated by following statement
Log.d("appSignature", AppSignatureHelper(requireContext()).appSignatures[0])
Share the value to PayU team for configuring SMS hash at BE.
Updated about 1 hour ago
