Non-Seamless Flow - iOS
The Tridentity SDK will handle the GUI and business logic. These Integration steps will be applicable for banks who are on Native Framework.
1. SDK Integration
Embed SDK
- Drag the
TridentitySDK.xcframeworkinto your Xcode project. - Link the framework:
- Select your project target.
- Navigate to General > Framework, Libraries, and Embedded Content.
- Choose Embed & Sign.
- Integrate Firebase if push notifications are required.
Add Pod Dependency
Add the following pods and run pod install:
pod 'PayUIndia-Analytics', '~> 4.0'
pod 'PayUIndia-CrashReporter', '~> 4.0'Permissions Required
Permission | Description |
|---|---|
Location
| For location-based services |
Push Notification
| Required for transaction notifications |
2. Configuration of SDK
Set up the necessary client details within the SDK. The SDK will perform essential security checks, and if any validation fails, a callback will provide specific error codes and messages. In such cases, terminate the enrollment flow to ensure security compliance.
Parameters
Parameter | Description |
|---|---|
clientId
| Client ID provided through offline channels |
environment
| Can be set to "UAT" (default) or "PROD" |
themeConfig
| Optional theme configuration in JSON/dictionary format |
Code Example
let configData: [String: Any] = ["clientId": "yourClientId", "environment": "UAT", "themeConfig": themeConfig]
TridentitySDKInterface.shared.configureSDK(jsonObject: configData) { success, response in
if success {
print("SDK configured successfully: \(response)")
} else {
print("Configuration error: \(response)")
// Terminate the enrollment flow
}
}Sample Responses
Success Response:
["code": 200, "message": "SDK configured successfully"]Failure Response:
["code": 10, "message": "Push notifications are disabled"]3. Implement TridentSDKDelegate
Ensure that your class adopts the TridentSDKDelegate protocol to handle callbacks for various SDK interfaces, with the exception of the customer status check. This implementation is crucial for processing SDK responses and updates effectively.
Sample Code
extension YourClass: TridentSDKDelegate {
func fetchStatus(data: [String: Any]) {
if let statusCode = data["code"] as? Int {
switch statusCode {
case 200:
// Handle success
case 400:
// Handle API/network failure
default:
// Handle other errors
}
}
}
func showCustomerStatus(data: [String: Any]) {
if let statusCode = data["code"] as? Int {
switch statusCode {
case 200:
// Handle success
case 400:
// Handle API/network failure
default:
// Handle other errors
}
}
}
func sdkStatusUpdate(data: [String: Any]) {
if let statusCode = data["code"] as? Int,
let dataKey = data["dataKey"] as? String {
switch dataKey {
case "registerFCMData":
if statusCode == 200 {
// Handle successful FCM token registration
}
case "historyData":
if statusCode == 200 {
// Process the successfully retrieved transaction history
}
case "deregistrationData":
if statusCode == 200 {
// Handle successful customer deregistration
}
default:
// Handle other data keys
}
}
}
}4. Register FCM
To enable push notifications for transaction processing, you need to register the FCM token. This should be done whenever the FCM token is refreshed.
Parameters
Parameter | Description |
|---|---|
fcmToken
| Token generated by Firebase Messaging Service |
statusDelegate
| The class implementing TridentSDKDelegate |
Code Example
TridentitySDKInterface.shared.registerFCM(fcmToken: fcmToken, statusDelegate: self)Sample Response
{
"dataKey": "registerFCMData",
"status": "SUCCESS",
"code": 200,
"message": "Successfully Updated FCM token"
}5. Handling User Registration
The initiateRegistration method in the TridentitySDKInterface is used to manage user registration.
Parameters
Parameter | Description |
|---|---|
jsonObject
| Dictionary containing registration parameters (e.g., mobileNumber) |
presenter
| UIViewController to present the registration interface |
completionHandler
| Closure to handle registration result |
Code Example
let userDetails: [String: Any] = ["mobileNumber": "user'sMobileNumber"]
TridentitySDKInterface.shared.initiateRegistration(jsonObject: userDetails, presenter: viewController) { success, response in
if success {
print("User registered successfully")
} else {
print("Registration failed: \(response)")
}
}6. Check Customer Status
Use this method to obtain the registration status of a customer within the Tridentity System. Ensure that you prepend the mobile number with "91".
Device Identification
You may need to pass the device identifier to various SDK methods for registration status.
let uid = UIDevice.current.identifierForVendor?.uuidStringCode Example
let json: [String: Any] = ["mobileNumber": "91***", "uid": "####"]
TridentitySDKInterface.shared.checkRegistrationStatus(jsonObject: json, completionHandler: {})Sample Response
["subParam": {
customerStatus = "registration_comm_success";
}, "message": "Customer status retrieved", "status": "SUCCESS", "code": 200]Registration Status Handling
-
Successful Registration: The status
customerStatus: registration_comm_successindicates a successful registration. -
Successful Registration with Activation Delay: Status values like
registration_comm_11_failmean registration is successful, but services activate within 24 hours. -
Failure: Any other status indicates registration failure.
7. Transaction History
To retrieve transaction data, invoke the method with optional limit and offset parameters.
- Offset (Page Number): Specifies the page number. An offset of 0 fetches the first records.
- Limit (Number of Records per Request): Maximum records returned per page. A limit of 10 retrieves up to 10 records.
Defaults and Constraints:
- Defaults are 10 for
limitand 0 foroffset. - Maximum limit is 50.
Examples:
- First Page:
offset: 0,limit: 10- Retrieves the first 10 records. - Second Page:
offset: 1,limit: 10- Retrieves records 11 through 20.
Adjust parameters to efficiently page through transaction records.
Parameters
Parameter | Description |
|---|---|
limit
| Number of records per request (default 10, max 50) |
offset
| Page number to retrieve (0-based, default 0) |
statusDelegate
| The class implementing TridentSDKDelegate |
Sample Code
let param: [String: Any] = ["limit": 5, "offset": 0]
TridentitySDKInterface.shared.fetchTransactionHistory(jsonObject: param, statusDelegate: self)Sample Response
{
"code": 200,
"subParam": {
"offset": 0,
"totalCount": 21,
"txnHistory": [
{
"amount": 23,
"authType": "PUSH",
"expiryTime": 1721177553000,
"merchant": "Amez standard QA 111306",
"reason": "RazyPay Transaction Request of Rs: 23 at Amez standard QA 111306",
"status": "EXPIRED",
"timeStamp": 1721177493000,
"title": "",
"txnId": "c12b2487-cc65-4c9f-b31a-f60731ece16a"
}
]
},
"status": "SUCCESS",
"message": "Successfully retrieved txn-history",
"dataKey": "historyData"
}8. Process Transaction
Upon receiving an FCM notification, use this method to process the transaction status based on the authentication action:
Parameters
Parameter | Description |
|---|---|
notificationInfo
| Dictionary with the notification payload |
presenter
| View controller to present the transaction UI |
Code Example
Example Payload:
let notificationInfo: [AnyHashable: Any] = [
"aps": ["alert": "You have a new message!", "badge": 1],
"customDataKey": "customValue"
]TridentitySDKInterface.shared.processTransaction(notificationInfo: notificationInfo, presenter: viewController)Important Notes
Expiration: The transaction expires 60 seconds after receipt, so timely processing is crucial.
9. De-Registration
To remove a customer's registration from the system, use the following method:
Parameters
Parameter | Description |
|---|---|
statusDelegate
| The class implementing TridentSDKDelegate |
Code Example
TridentitySDKInterface.shared.deRegisterUser(statusDelegate: self)Sample Response
["dataKey": "deregistrationData", "message": "Device Deregistered Successfully", "status": "SUCCESS", "code": 200]- UI Customization
The SDK allows UI customizations through a configuration object passed in as themeConfig.
UI Customization Parameters
| Parameter | Description | Example |
|---|---|---|
LabelCustomizationoptional |
Configurations: HeaderCustomization,TextCustomization. Sub Components: textColor, fontSize | labelConfigObject |
ToolbarCustomizationoptional |
Configurations: backgroundColor, textColor, fontSize | toolbarConfigObject |
ButtonCustomizationoptional |
Configurations: primaryButtonCustomization, secondaryButtonCustomization. Sub Components: enabledBackgroundColor, enabledTextColor, disabledBackgroundColor, disabledTextColor, fontSize, cornerRadius | buttonConfigObject |
Text Customization Parameters
| Configurations Supported | UI Sub Components |
|---|---|
| consentScreenConfiguration | consentPopUpRegisterButtonText, consentPopUpSkipButtonText |
| tncScreenConfiguration | consentPopUpOkButtonText |
| bottomSheetPermissionPopupConfiguration | topHeaderText, topSubHeaderText, headerTextForContents, subTextForContents, buttonTextForAllowPermissions, buttonTextForSkipPermissions |
| simBindingScreenConfiguration | appBarText, topHeaderText, topSubHeaderText, headerTextForContents, subTextForContents, textForFullScreenSubContent, buttonTextForProceed |
| bottomSheetSimBindingProcessingPopupConfiguration | topHeaderText, topSubHeaderText, headerTextForContents, subTextForContents, numberVerificationProcessingText, numberVerifiedText, biometricSetupText, biometricVerifiedText |
| bottomSheetRegistrationSuccessfulPopupConfiguration | topHeaderText, topSubHeaderText, headerTextForContents, subTextForContents, buttonText |
| bottomSheetFailureScreenConfiguration | topHeaderText, topSubHeaderText, headerTextForContents, subTextForContents, buttonText |
| transactionHistoryScreenConfiguration | appBarText, topHeaderText, topSubHeaderText, headerTextForContents, subTextForContents, bottomBarTransactionsText, bottomBarOfflineOTPText |
| offlineOTPScreenConfiguration | appBarText, topHeaderText, topSubHeaderText, headerTextForContents, subTextForContents, copyText |
| bottomSheetAuthenticationPopupConfiguration | topHeaderText, topSubHeaderText, headerTextForContents, subTextForContents, declineButtontext, swipeToPayButtonText |
| deRegPopupConfiguration | topHeaderText, topSubHeaderText, headerTextForContents, subTextForContents, okButtonText, cancelButtonText |
Sample Code
// MARK: - ========== UI CUSTOMIZATION ==========
// Toolbar Customization
let toolbarCustomization = ToolbarThemeCustomization(
textColor: "#FFFFFF",
fontName: "Avenir-Medium",
fontSize: 10,
backgroundColor: "#F26522"
)
// Label Customization
let labelCustomization = LabelCustomization(
headingCustomization: HeadingThemeCustomization(
textColor: "#25272C",
fontName: "Avenir-Heavy",
fontSize: 18,
backgroundColor: "#FFFFFF"
),
subHeadingCustomization: SubHeadingThemeCustomization(
textColor: "#25272C",
fontName: "Avenir-Book",
fontSize: 14,
backgroundColor: "#FFFFFF"
)
)
// Button Customization
let buttonCustomization = ButtonCustomization(
primaryButtonCustomization: PrimaryCustomButtonCustomization(
enabledBackgroundColor: "#9C27B0",
enabledTextColor: "#FFFFFF",
disabledBackgroundColor: "#9e9e9d",
disabledTextColor: "#FFFFFF"
),
secondaryButtonCustomization: SecondaryCustomButtonCustomization(
enabledBackgroundColor: "#E02020",
enabledTextColor: "#FFFFFF",
disabledBackgroundColor: "#E3361C",
disabledTextColor: "#FFFFFF"
),
fontName: "Avenir-Medium",
fontSize: 18,
buttonTextTransform: .default,
cornerRadius: 50
)
// UI Customization
let uiCustomization = UICustomization(
processingCircleColor: "#66676B",
buttonCustomization: buttonCustomization,
toolbarCustomization: toolbarCustomization,
labelCustomization: labelCustomization
)
// MARK: - ========== TEXT CUSTOMIZATION ==========
// Consent Screen Configuration
let consentScreenConfiguration = ConsentScreenConfiguration(
consentPopUpRegisterButtonText: "Register",
consentPopUpSkipButtonText: "Skip for now, I'll do it later"
)
// Terms & Conditions Screen Configuration
let tncScreenConfiguration = TNCScreenConfiguration(
consentPopUpOkButtonText: "OK"
)
// Permission Popup Configuration
let bottomSheetPermissionPopupConfiguration = BottomSheetPermissionPopupConfiguration(
topHeaderText: "Permissions Required",
topSubHeaderText: "We need access to proceed",
headerTextForContents: "Why We Need This",
subTextForContents: "This permission ensures full functionality.",
buttonTextForAllowPermissions: "Allow",
buttonTextForSkipPermissions: "Skip"
)
// SIM Binding Screen Configuration
let simBindingScreenConfiguration = SimBindingScreenConfiguration(
appBarText: "Registration",
topHeaderText: "Bind Your SIM",
topSubHeaderText: "For Secure Access",
headerTextForContents: "Benefits of Binding",
subTextForContents: "Faster, secure transactions.",
textForFullScreenSubContent: "We need to send an SMS to verify the Mobile Number. Select the SIM to send an SMS",
buttonTextForProceed: "Proceed"
)
// SIM Binding Processing Popup Configuration
let bottomSheetSimBindingProcessingPopupConfiguration = BottomSheetSimBindingProcessingPopupConfiguration(
topHeaderText: "Set-up Biometric",
topSubHeaderText: "Please wait",
headerTextForContents: "Verifying Details",
subTextForContents: "This may take a moment.",
numberVerificationProcessingText: "Please wait while we verify your mobile number...",
numberVerifiedText: "Mobile number successfully verified.",
biometricSetupText: "Biometric set-up",
biometricVerifiedText: "Finalizing your biometric set-up.."
)
// Registration Success Popup Configuration
let bottomSheetRegistrationSuccessfulPopupConfiguration = BottomSheetSuccessConfiguration(
topHeaderText: "",
topSubHeaderText: "",
headerTextForContents: "Congratulations",
subTextForContents: "Flash Pay is setup now! All future payments can be done via your biometric verification.",
buttonText: "TAKING BACK TO MERCHANT"
)
// Failure Screen Configuration
let bottomSheetFailureScreenConfiguration = BottomSheetFailureConfiguration(
topHeaderText: "Failed!",
topSubHeaderText: "",
headerTextForContents: "Could not verify mobile number",
subTextForContents: "There was an error verifying your mobile number. Please try again.",
buttonText: "TAKING BACK TO MERCHANT"
)
// Transaction History Screen Configuration
let transactionHistoryScreenConfiguration = TransactionHistoryScreenConfiguration(
appBarText: "Card Authentication Services",
topHeaderText: "Authentication History",
topSubHeaderText: "",
headerTextForContents: "",
subTextForContents: "",
bottomBarTransactionsText: "Transactions",
bottomBarOfflineOTPText: "Offline OTP"
)
// Offline OTP Screen Configuration
let offlineOTPScreenConfiguration = OfflineOTPScreenConfiguration(
appBarText: "Card Authentication Services",
topHeaderText: "Offline OTP",
topSubHeaderText: "",
headerTextForContents: "",
subTextForContents: "",
copyText: "Copy to Clipboard"
)
// Authentication Popup Configuration
let bottomSheetAuthenticationPopupConfiguration = BottomSheetAuthenticationPopupConfiguration(
topHeaderText: "",
topSubHeaderText: "",
headerTextForContents: "Swipe To Pay",
subTextForContents: "",
declineButtontext: "Decline",
swipeToPayButtonText: "Swipe to Pay"
)
// De-Registration Popup Configuration
let deRegPopupConfiguration = DeRegPopupConfiguration(
topHeaderText: "",
topSubHeaderText: "",
headerTextForContents: "De-Register",
subTextForContents: "This action will De-Register from Secure Pay. Is this what you intended to do?",
okButtonText: "OK",
cancelButtonText: "Cancel"
)
// Text Customization
let textCustomization = TextCustomization(
consentScreenConfiguration: consentScreenConfiguration,
tncScreenConfiguration: tncScreenConfiguration,
bottomSheetPermissionPopupConfiguration: bottomSheetPermissionPopupConfiguration,
simBindingScreenConfiguration: simBindingScreenConfiguration,
bottomSheetSimBindingProcessingPopupConfiguration: bottomSheetSimBindingProcessingPopupConfiguration,
bottomSheetRegistrationSuccessfulPopupConfiguration: bottomSheetRegistrationSuccessfulPopupConfiguration,
bottomSheetFailureScreenConfiguration: bottomSheetFailureScreenConfiguration,
transactionHistoryScreenConfiguration: transactionHistoryScreenConfiguration,
offlineOTPScreenConfiguration: offlineOTPScreenConfiguration,
bottomSheetAuthenticationPopupConfiguration: bottomSheetAuthenticationPopupConfiguration,
deRegPopupConfiguration: deRegPopupConfiguration
)
// MARK: - ========== THEME CONFIG ==========
let themeConfig = ThemeModel(
uiCustomization: uiCustomization,
textCustomization: textCustomization
)
// MARK: - ========== CONFIGURE SDK ==========
let json: [String: Any] = [
"clientId": "your_client_id",
"environment": "uat",
"themeConfig": themeConfig
]
TridentitySDKInterface.shared.configureSDK(jsonObject: json) { success, response in
print("SDK configured: \(success)")
}10. Callback Success/Error Codes
The table lists possible callback success and error codes, and their reasons:
| Code | Reason |
|---|---|
| 300 | Biometric authentication disabled due to changes in device biometric settings. Please re-register to continue payments without OTP |
| 301 | Biometric Authentication failed. Limit exceeded due to incorrect attempts |
| 302 | Device is not compatible for biometric authentication. Please try registration from another device. |
| 303 | Biometric is disbaled. Please enable the same to register for biometric authentication |
| 304 | Too many biometric attempts. Please wait or use PIN/password to unlock. |
| 305 | Biometric authentication disabled due to app reinstallation or data deletion. Please re-register to continue payments without OTP |
| 306 | Invalid mobile number. Please enter a valid number. |
| 307 | SDK not configured. Please initialize the SDK with valid configuration parameters before making API calls. |
| 308 | Invalid parameters provided. Please check your input and try again. |
| 331 | Device Debugging detected. For security, please disable to proceed. |
| 333 | Biometric authentication disabled due to changes in device security settings. Please re-register to continue payments without OTP |
| 334 | Screen recording observed. |
| 335 | App toggling observed. Please try registration again |
| 336 | Device is reverse engineered |
| 338 | Customer not registered. Please complete the registration process to continue. |
| 361 | No network connection available. Please check your internet connection and try again |
| 362 | Biometric authentication has timed out. Redirecting to OTP authentication |
| 363 | Biometric authentication timed out. Please try in future Payments again to enrol for biometric |
| 364 | The system timed out the SDK session after a period of app inactivity. |
| 365 | Unable to send SMS. Please check your phone number and network connection, then try again later. |
| 367 | Device is in airplane mode. Please turn off airplane mode and try again |
| 370 | SMS sending cancelled. Please try registering again later.SMS sending cancelled. Please try registering again later. |
| 371 | Unable to send SMS. Please try registering again later. |
| 372 | Cannot present registration screen. Invalid navigation view controller argument. |
| 373 | Unable to process server response. |
| 390 | Biometric authentication disabled due to sim movement. Please re-register to continue payments without OTP |
| 400 | We encountered an error loading this page. Please try again. |
| 200 | Configuration Successful |
Updated about 3 hours ago