diff --git a/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/android/build.gradle b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/android/build.gradle
index 2fba887c..c8806404 100644
--- a/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/android/build.gradle
+++ b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/android/build.gradle
@@ -1,28 +1,29 @@
buildscript {
- // Buildscript is evaluated before everything else so we can't use getExtOrDefault
- def kotlin_version = rootProject.ext.has('kotlinVersion') ? rootProject.ext.get('kotlinVersion') : project.properties['HyperswitchNetcetera3ds_kotlinVersion']
+ ext.getExtOrDefault = {name ->
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['HyperswitchNetcetera3ds_' + name]
+ }
repositories {
- google()
- mavenCentral()
+ google()
+ mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.5.3'
+ classpath "com.android.tools.build:gradle:8.7.2"
// noinspection DifferentKotlinGradleVersion
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}"
}
}
def isNewArchitectureEnabled() {
- return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
+ return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
}
-apply plugin: 'com.android.library'
-apply plugin: 'kotlin-android'
+apply plugin: "com.android.library"
+apply plugin: "kotlin-android"
if (isNewArchitectureEnabled()) {
- apply plugin: 'com.facebook.react'
+ apply plugin: "com.facebook.react"
}
def getExtOrDefault(name) {
@@ -33,14 +34,38 @@ def getExtOrIntegerDefault(name) {
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties['HyperswitchNetcetera3ds_' + name]).toInteger()
}
+def supportsNamespace() {
+ def parsed = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')
+ def major = parsed[0].toInteger()
+ def minor = parsed[1].toInteger()
+
+ // Namespace support was added in 7.3.0
+ return (major == 7 && minor >= 3) || major >= 8
+}
+
android {
- compileSdkVersion getExtOrIntegerDefault('compileSdkVersion')
+ if (supportsNamespace()) {
+ namespace "com.reactnativehyperswitchnetcetera3ds"
+
+ sourceSets {
+ main {
+ manifest.srcFile "src/main/AndroidManifestNew.xml"
+ }
+ }
+ }
+
+ compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
defaultConfig {
- minSdkVersion getExtOrIntegerDefault('minSdkVersion')
- targetSdkVersion getExtOrIntegerDefault('targetSdkVersion')
+ minSdkVersion getExtOrIntegerDefault("minSdkVersion")
+ targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
}
+
+ buildFeatures {
+ buildConfig true
+ }
+
buildTypes {
release {
minifyEnabled false
@@ -48,96 +73,37 @@ android {
}
lintOptions {
- disable 'GradleCompatible'
+ disable "GradleCompatible"
}
compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
+ sourceCompatibility JavaVersion.VERSION_17
+ targetCompatibility JavaVersion.VERSION_17
+ }
+
+ sourceSets {
+ main {
+ if (isNewArchitectureEnabled()) {
+ java.srcDirs += ["src/newarch"]
+ } else {
+ java.srcDirs += ["src/oldarch"]
+ }
+ }
}
}
repositories {
mavenCentral()
google()
-
- def found = false
- def defaultDir = null
- def androidSourcesName = 'React Native sources'
-
- if (rootProject.ext.has('reactNativeAndroidRoot')) {
- defaultDir = rootProject.ext.get('reactNativeAndroidRoot')
- } else {
- defaultDir = new File(
- projectDir,
- '/../../../node_modules/react-native/android'
- )
- }
-
- if (defaultDir.exists()) {
- maven {
- url defaultDir.toString()
- name androidSourcesName
- }
-
- logger.info(":${project.name}:reactNativeAndroidRoot ${defaultDir.canonicalPath}")
- found = true
- } else {
- def parentDir = rootProject.projectDir
-
- 1.upto(5, {
- if (found) return true
- parentDir = parentDir.parentFile
-
- def androidSourcesDir = new File(
- parentDir,
- 'node_modules/react-native'
- )
-
- def androidPrebuiltBinaryDir = new File(
- parentDir,
- 'node_modules/react-native/android'
- )
-
- if (androidPrebuiltBinaryDir.exists()) {
- maven {
- url androidPrebuiltBinaryDir.toString()
- name androidSourcesName
- }
-
- logger.info(":${project.name}:reactNativeAndroidRoot ${androidPrebuiltBinaryDir.canonicalPath}")
- found = true
- } else if (androidSourcesDir.exists()) {
- maven {
- url androidSourcesDir.toString()
- name androidSourcesName
- }
-
- logger.info(":${project.name}:reactNativeAndroidRoot ${androidSourcesDir.canonicalPath}")
- found = true
- }
- })
- }
-
- if (!found) {
- throw new GradleException(
- "${project.name}: unable to locate React Native android sources. " +
- "Ensure you have you installed React Native as a dependency in your project and try again."
- )
- }
}
-def kotlin_version = getExtOrDefault('kotlinVersion')
+def kotlin_version = getExtOrDefault("kotlinVersion")
dependencies {
- //noinspection GradleDynamicVersion
- implementation "com.facebook.react:react-native:+"
+ implementation "com.facebook.react:react-android"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
- implementation 'io.hyperswitch:netcetra-3ds:2.5.2.0'
- // TODO remove this
+ implementation "io.hyperswitch:netcetra-3ds:2.5.2.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.0"
-
-// From node_modules
}
if (isNewArchitectureEnabled()) {
diff --git a/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/android/gradle.properties b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/android/gradle.properties
index 4d814534..65d832d9 100644
--- a/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/android/gradle.properties
+++ b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/android/gradle.properties
@@ -1,5 +1,4 @@
-HyperswitchNetcetera3ds_kotlinVersion=1.7.0
+HyperswitchNetcetera3ds_kotlinVersion=1.9.22
HyperswitchNetcetera3ds_minSdkVersion=21
-HyperswitchNetcetera3ds_targetSdkVersion=31
-HyperswitchNetcetera3ds_compileSdkVersion=31
-HyperswitchNetcetera3ds_ndkversion=21.4.7075529
+HyperswitchNetcetera3ds_targetSdkVersion=34
+HyperswitchNetcetera3ds_compileSdkVersion=35
diff --git a/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/android/src/main/AndroidManifestNew.xml b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/android/src/main/AndroidManifestNew.xml
new file mode 100644
index 00000000..a2f47b60
--- /dev/null
+++ b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/android/src/main/AndroidManifestNew.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/android/src/main/java/com/reactnativehyperswitchnetcetera3ds/HyperswitchNetcetera3dsModule.kt b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/android/src/main/java/com/reactnativehyperswitchnetcetera3ds/HyperswitchNetcetera3dsModule.kt
index 191b9909..04458d58 100644
--- a/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/android/src/main/java/com/reactnativehyperswitchnetcetera3ds/HyperswitchNetcetera3dsModule.kt
+++ b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/android/src/main/java/com/reactnativehyperswitchnetcetera3ds/HyperswitchNetcetera3dsModule.kt
@@ -2,26 +2,24 @@ package com.reactnativehyperswitchnetcetera3ds
import android.app.Activity
import android.app.Application
-import androidx.annotation.Nullable
import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.Callback
import com.facebook.react.bridge.ReactApplicationContext
-import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
class HyperswitchNetcetera3dsModule(reactContext: ReactApplicationContext) :
- ReactContextBaseJavaModule(reactContext) {
+ HyperswitchNetcetera3dsSpec(reactContext) {
val hsNetceteraUtils = HsNetceteraUtils()
val applicationContext = reactApplicationContext.applicationContext as Application
private fun getActivity(): Activity? {
return currentActivity ?: reactApplicationContext.currentActivity
}
override fun getName(): String {
- return "HyperswitchNetcetera3ds"
+ return NAME
}
@ReactMethod
- fun initialiseNetceteraSDK(
+ override fun initialiseNetceteraSDK(
apiKey: String, hsSDKEnvironment: String, callback: Callback
) {
@@ -40,18 +38,18 @@ class HyperswitchNetcetera3dsModule(reactContext: ReactApplicationContext) :
}
@ReactMethod
- fun generateAReqParams(
+ override fun generateAReqParams(
messageVersion: String, directoryServerId: String, callback: Callback
) {
hsNetceteraUtils.generateAReqParams(getActivity(), messageVersion, directoryServerId, callback)
}
@ReactMethod
- fun recieveChallengeParamsFromRN(
+ override fun recieveChallengeParamsFromRN(
acsSignedContent: String,
acsRefNumber: String,
acsTransactionId: String,
- @Nullable threeDSRequestorAppURL: String?,
+ threeDSRequestorAppURL: String?,
threeDSServerTransId: String,
callback: Callback
) {
@@ -66,7 +64,11 @@ class HyperswitchNetcetera3dsModule(reactContext: ReactApplicationContext) :
}
@ReactMethod
- fun generateChallenge(callback: Callback) {
+ override fun generateChallenge(callback: Callback) {
hsNetceteraUtils.generateChallenge(getActivity(), 5, callback)
}
+
+ companion object {
+ const val NAME = "HyperswitchNetcetera3ds"
+ }
}
diff --git a/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/android/src/main/java/com/reactnativehyperswitchnetcetera3ds/HyperswitchNetcetera3dsPackage.kt b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/android/src/main/java/com/reactnativehyperswitchnetcetera3ds/HyperswitchNetcetera3dsPackage.kt
index d50626e2..26b1cc87 100644
--- a/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/android/src/main/java/com/reactnativehyperswitchnetcetera3ds/HyperswitchNetcetera3dsPackage.kt
+++ b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/android/src/main/java/com/reactnativehyperswitchnetcetera3ds/HyperswitchNetcetera3dsPackage.kt
@@ -1,16 +1,34 @@
package com.reactnativehyperswitchnetcetera3ds
-import com.facebook.react.ReactPackage
+import com.facebook.react.TurboReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
-import com.facebook.react.uimanager.ViewManager
+import com.facebook.react.module.model.ReactModuleInfo
+import com.facebook.react.module.model.ReactModuleInfoProvider
-class HyperswitchNetcetera3dsPackage : ReactPackage {
- override fun createNativeModules(reactContext: ReactApplicationContext): List {
- return listOf(HyperswitchNetcetera3dsModule(reactContext))
+class HyperswitchNetcetera3dsPackage : TurboReactPackage() {
+ override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
+ return if (name == HyperswitchNetcetera3dsModule.NAME) {
+ HyperswitchNetcetera3dsModule(reactContext)
+ } else {
+ null
}
+ }
- override fun createViewManagers(reactContext: ReactApplicationContext): List> {
- return emptyList()
+ override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
+ return ReactModuleInfoProvider {
+ val moduleInfos: MutableMap = HashMap()
+ val isTurboModule: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
+ moduleInfos[HyperswitchNetcetera3dsModule.NAME] = ReactModuleInfo(
+ HyperswitchNetcetera3dsModule.NAME,
+ HyperswitchNetcetera3dsModule.NAME,
+ false, // canOverrideExistingModule
+ false, // needsEagerInit
+ true, // hasConstants
+ false, // isCxxModule
+ isTurboModule
+ )
+ moduleInfos
}
+ }
}
diff --git a/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/android/src/newarch/java/com/reactnativehyperswitchnetcetera3ds/HyperswitchNetcetera3dsSpec.kt b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/android/src/newarch/java/com/reactnativehyperswitchnetcetera3ds/HyperswitchNetcetera3dsSpec.kt
new file mode 100644
index 00000000..c9b46e93
--- /dev/null
+++ b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/android/src/newarch/java/com/reactnativehyperswitchnetcetera3ds/HyperswitchNetcetera3dsSpec.kt
@@ -0,0 +1,6 @@
+package com.reactnativehyperswitchnetcetera3ds
+
+import com.facebook.react.bridge.ReactApplicationContext
+
+abstract class HyperswitchNetcetera3dsSpec internal constructor(context: ReactApplicationContext) :
+ NativeHyperswitchNetcetera3dsSpec(context)
diff --git a/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/android/src/oldarch/java/com/reactnativehyperswitchnetcetera3ds/HyperswitchNetcetera3dsSpec.kt b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/android/src/oldarch/java/com/reactnativehyperswitchnetcetera3ds/HyperswitchNetcetera3dsSpec.kt
new file mode 100644
index 00000000..3eaea3a0
--- /dev/null
+++ b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/android/src/oldarch/java/com/reactnativehyperswitchnetcetera3ds/HyperswitchNetcetera3dsSpec.kt
@@ -0,0 +1,32 @@
+package com.reactnativehyperswitchnetcetera3ds
+
+import com.facebook.react.bridge.Callback
+import com.facebook.react.bridge.ReactApplicationContext
+import com.facebook.react.bridge.ReactContextBaseJavaModule
+
+abstract class HyperswitchNetcetera3dsSpec internal constructor(context: ReactApplicationContext) :
+ ReactContextBaseJavaModule(context) {
+
+ abstract fun initialiseNetceteraSDK(
+ apiKey: String,
+ hsSDKEnvironment: String,
+ callback: Callback
+ )
+
+ abstract fun generateAReqParams(
+ messageVersion: String,
+ directoryServerId: String,
+ callback: Callback
+ )
+
+ abstract fun recieveChallengeParamsFromRN(
+ acsSignedContent: String,
+ acsRefNumber: String,
+ acsTransactionId: String,
+ threeDSRequestorAppURL: String?,
+ threeDSServerTransId: String,
+ callback: Callback
+ )
+
+ abstract fun generateChallenge(callback: Callback)
+}
diff --git a/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/ios/Source/HyperswitchChallengeManager.swift b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/ios/Source/HyperswitchChallengeManager.swift
index 99fab6f1..127ac401 100644
--- a/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/ios/Source/HyperswitchChallengeManager.swift
+++ b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/ios/Source/HyperswitchChallengeManager.swift
@@ -10,10 +10,10 @@ import ThreeDS_SDK
class HyperswitchChallengeManager: ChallengeStatusReceiver {
- var postChallengeCallback: RCTResponseSenderBlock?
+ var postChallengeCallback: (([String: Any]) -> Void)?
var map: [String: Any] = [:]
- func setPostHSChallengeCallback(_ callback: @escaping RCTResponseSenderBlock) {
+ func setPostHSChallengeCallback(_ callback: @escaping ([String: Any]) -> Void) {
self.postChallengeCallback = callback
}
@@ -21,21 +21,21 @@ class HyperswitchChallengeManager: ChallengeStatusReceiver {
// Handle successful or unsuccessful completion of challenge flow
map["status"] = "success";
map["message"] = "challenge completed successfully";
- postChallengeCallback?([map]);
+ postChallengeCallback?(map);
}
func cancelled() {
// Handle challenge canceled by the user
map["status"] = "error";
map["message"] = "challenge cancelled by user";
- postChallengeCallback?([map]);
+ postChallengeCallback?(map);
}
func timedout() {
// Handle challenge timeout
map["status"] = "error";
map["message"] = "challenge timeout";
- postChallengeCallback?([map]);
+ postChallengeCallback?(map);
}
func protocolError(protocolErrorEvent: ProtocolErrorEvent) {
@@ -69,7 +69,7 @@ class HyperswitchChallengeManager: ChallengeStatusReceiver {
map["status"] = "error";
map["message"] = message;
- postChallengeCallback?([map]);
+ postChallengeCallback?(map);
}
func runtimeError(runtimeErrorEvent: RuntimeErrorEvent) {
@@ -83,7 +83,7 @@ class HyperswitchChallengeManager: ChallengeStatusReceiver {
map["status"] = "error";
map["message"] = message;
- postChallengeCallback?([map]);
+ postChallengeCallback?(map);
}
}
diff --git a/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/ios/Source/HyperswitchNetcetera3ds-Bridging-Header.h b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/ios/Source/HyperswitchNetcetera3ds-Bridging-Header.h
deleted file mode 100644
index dea7ff6b..00000000
--- a/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/ios/Source/HyperswitchNetcetera3ds-Bridging-Header.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#import
-#import
diff --git a/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/ios/Source/HyperswitchNetcetera3ds.m b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/ios/Source/HyperswitchNetcetera3ds.m
deleted file mode 100644
index 1db39e92..00000000
--- a/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/ios/Source/HyperswitchNetcetera3ds.m
+++ /dev/null
@@ -1,31 +0,0 @@
-#import
-
-@interface RCT_EXTERN_MODULE(HyperswitchNetcetera3ds, NSObject)
-
-
-RCT_EXTERN_METHOD(initialiseNetceteraSDK:
- (NSString *)apiKey:
- (NSString *)hsSDKEnvironment:
- (RCTResponseSenderBlock)callback)
-
-RCT_EXTERN_METHOD(generateAReqParams:
- (NSString *)messageVersion:
- (NSString *)directoryServerId:
- (RCTResponseSenderBlock)callback)
-
-RCT_EXTERN_METHOD(recieveChallengeParamsFromRN:
- (NSString *)acsSignedContent:
- (NSString *)acsRefNumber:
- (NSString *)acsTransactionId:
- (nullable NSString *)threeDSRequestorAppURL:
- (NSString *)threeDSServerTransId:
- (RCTResponseSenderBlock)callback)
-
-RCT_EXTERN_METHOD(generateChallenge: (RCTResponseSenderBlock)callback)
-
-+ (BOOL)requiresMainQueueSetup
-{
- return NO;
-}
-
-@end
diff --git a/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/ios/Source/HyperswitchNetcetera3ds.mm b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/ios/Source/HyperswitchNetcetera3ds.mm
new file mode 100644
index 00000000..ceb6a285
--- /dev/null
+++ b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/ios/Source/HyperswitchNetcetera3ds.mm
@@ -0,0 +1,100 @@
+#import
+#import
+
+#ifdef RCT_NEW_ARCH_ENABLED
+#import "RNHyperswitchNetcetera3dsSpec.h"
+#endif
+
+#if __has_include()
+#import
+#else
+#import "react_native_hyperswitch_netcetera_3ds-Swift.h"
+#endif
+
+@interface HyperswitchNetcetera3ds : NSObject
+@end
+
+#ifdef RCT_NEW_ARCH_ENABLED
+@interface HyperswitchNetcetera3ds ()
+@end
+#endif
+
+@implementation HyperswitchNetcetera3ds {
+ HyperswitchNetcetera3dsImpl *_impl;
+}
+
+RCT_EXPORT_MODULE()
+
+- (instancetype)init
+{
+ if (self = [super init]) {
+ _impl = [HyperswitchNetcetera3dsImpl new];
+ }
+ return self;
+}
+
++ (BOOL)requiresMainQueueSetup
+{
+ return NO;
+}
+
+RCT_EXPORT_METHOD(initialiseNetceteraSDK:(NSString *)apiKey
+ hsSDKEnvironment:(NSString *)hsSDKEnvironment
+ callback:(RCTResponseSenderBlock)callback)
+{
+ [self->_impl initialiseNetceteraSDK:apiKey
+ hsSDKEnvironment:hsSDKEnvironment
+ callback:^(NSDictionary *status) {
+ callback(@[ status ]);
+ }];
+}
+
+RCT_EXPORT_METHOD(generateAReqParams:(NSString *)messageVersion
+ directoryServerId:(NSString *)directoryServerId
+ callback:(RCTResponseSenderBlock)callback)
+{
+ dispatch_async(dispatch_get_main_queue(), ^{
+ UIViewController *presentedViewController = RCTPresentedViewController();
+ [self->_impl generateAReqParams:messageVersion
+ directoryServerId:directoryServerId
+ from:presentedViewController
+ callback:^(NSDictionary *status,
+ NSDictionary *aReqParams) {
+ callback(aReqParams ? @[ status, aReqParams ] : @[ status ]);
+ }];
+ });
+}
+
+RCT_EXPORT_METHOD(recieveChallengeParamsFromRN:(NSString *)acsSignedContent
+ acsRefNumber:(NSString *)acsRefNumber
+ acsTransactionId:(NSString *)acsTransactionId
+ threeDSRequestorAppURL:(nullable NSString *)threeDSRequestorAppURL
+ threeDSServerTransId:(NSString *)threeDSServerTransId
+ callback:(RCTResponseSenderBlock)callback)
+{
+ [self->_impl recieveChallengeParamsFromRN:acsSignedContent
+ acsRefNumber:acsRefNumber
+ acsTransactionId:acsTransactionId
+ threeDSRequestorAppURL:threeDSRequestorAppURL
+ threeDSServerTransId:threeDSServerTransId
+ callback:^(NSDictionary *status) {
+ callback(@[ status ]);
+ }];
+}
+
+RCT_EXPORT_METHOD(generateChallenge:(RCTResponseSenderBlock)callback)
+{
+ [self->_impl generateChallenge:^(NSDictionary *status) {
+ callback(@[ status ]);
+ }];
+}
+
+#ifdef RCT_NEW_ARCH_ENABLED
+- (std::shared_ptr)getTurboModule:
+ (const facebook::react::ObjCTurboModule::InitParams &)params
+{
+ return std::make_shared(params);
+}
+#endif
+
+@end
diff --git a/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/ios/Source/HyperswitchNetcetera3ds.swift b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/ios/Source/HyperswitchNetcetera3ds.swift
index 0df444f2..715d4b83 100644
--- a/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/ios/Source/HyperswitchNetcetera3ds.swift
+++ b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/ios/Source/HyperswitchNetcetera3ds.swift
@@ -6,10 +6,10 @@
//
import Foundation
+import UIKit
import ThreeDS_SDK
-@objc(HyperswitchNetcetera3ds)
-class HyperswitchNetcetera3ds: NSObject {
+@objc public class HyperswitchNetcetera3dsImpl: NSObject {
private let challengeStatusReceiver: HyperswitchChallengeManager = HyperswitchChallengeManager()
private let threeDS2Service: ThreeDS2Service = ThreeDS2ServiceSDK()
@@ -22,9 +22,9 @@ class HyperswitchNetcetera3ds: NSObject {
private var hsSDKEnvironment: String?
@objc
- func initialiseNetceteraSDK(_ apiKey: String,
- _ hsSDKEnvironment: String,
- _ callback: @escaping RCTResponseSenderBlock) {
+ public func initialiseNetceteraSDK(_ apiKey: String,
+ hsSDKEnvironment: String,
+ callback: @escaping ([String: Any]) -> Void) {
var initStatus: [String:Any] = [:];
do {
@@ -66,7 +66,7 @@ class HyperswitchNetcetera3ds: NSObject {
guard let configParams = self.configParams else {
initStatus["status"] = "failure";
initStatus["message"] = "netcetera sdk initialization failed";
- callback([initStatus]);
+ callback(initStatus)
return
}
@@ -76,18 +76,18 @@ class HyperswitchNetcetera3ds: NSObject {
success: {
initStatus["status"] = "success"
initStatus["message"] = "netcetera sdk initialization successful"
- callback([initStatus])
+ callback(initStatus)
},
failure: { error in
if (error.localizedDescription == "The SDK is already initialized") {
initStatus["status"] = "success";
initStatus["message"] = "netcetera sdk initialization successful";
- callback([initStatus]);
+ callback(initStatus)
}
else{
initStatus["status"] = "failure";
initStatus["message"] = "netcetera sdk initialization failed";
- callback([initStatus]);
+ callback(initStatus)
}
})
}
@@ -95,23 +95,23 @@ class HyperswitchNetcetera3ds: NSObject {
var errMap: [String:Any] = [:];
errMap["status"] = "failure";
errMap["message"] = "Initialization failed:" + error.localizedDescription;
- callback([errMap]);
+ callback(errMap)
return
}
}
@objc
- func generateAReqParams(_ messageVersion: String,
- _ directoryServerId: String,
- _ callback: @escaping RCTResponseSenderBlock) {
-
+ public func generateAReqParams(_ messageVersion: String,
+ directoryServerId: String,
+ from viewController: UIViewController?,
+ callback: @escaping ([String: Any], [String: String]?) -> Void) {
DispatchQueue.main.async {
do {
//MARK: dont send nil here try [:]
let transaction = try self.threeDS2Service.createTransaction(directoryServerId: directoryServerId, messageVersion: messageVersion)
self.transaction = transaction
- self.vc = RCTPresentedViewController()
+ self.vc = viewController
self.progressView = try self.transaction?.getProgressView()
let authenticationParameters = try transaction.getAuthenticationRequestParameters()
@@ -126,23 +126,23 @@ class HyperswitchNetcetera3ds: NSObject {
var statusMap: [String: Any] = [:]
statusMap["status"] = "success"
statusMap["message"] = "AReq Params generation successful"
- callback([statusMap, authReqMap])
+ callback(statusMap, authReqMap)
} catch let error as NSError {
//MARK: don't send nil here try [:]
var statusMap: [String: Any] = [:]
statusMap["status"] = "error"
statusMap["message"] = "AReq Params generation failure. Error: \(error)"
- callback([statusMap])
+ callback(statusMap, nil)
}
}
}
@objc
- func recieveChallengeParamsFromRN(_ acsSignedContent: String,
- _ acsRefNumber: String,
- _ acsTransactionId: String,
- _ threeDSRequestorAppURL: String?,
- _ threeDSServerTransId: String,
- _ callback: @escaping RCTResponseSenderBlock) {
+ public func recieveChallengeParamsFromRN(_ acsSignedContent: String,
+ acsRefNumber: String,
+ acsTransactionId: String,
+ threeDSRequestorAppURL: String?,
+ threeDSServerTransId: String,
+ callback: @escaping ([String: Any]) -> Void) {
let challengeParameters = ChallengeParameters(
threeDSServerTransactionID: threeDSServerTransId,
acsTransactionID: acsTransactionId,
@@ -157,11 +157,11 @@ class HyperswitchNetcetera3ds: NSObject {
var statusMap: [String:Any] = [:]
statusMap["status"] = "success"
statusMap["message"] = "challenge params receive successful"
- callback([statusMap])
+ callback(statusMap)
}
@objc
- func generateChallenge(_ callback: @escaping RCTResponseSenderBlock) {
+ public func generateChallenge(_ callback: @escaping ([String: Any]) -> Void) {
challengeStatusReceiver.setPostHSChallengeCallback(callback)
DispatchQueue.global().async {
@@ -173,7 +173,7 @@ class HyperswitchNetcetera3ds: NSObject {
var map: [String: String] = [:]
map["status"] = "error"
map["message"] = "doChallenge call unsuccessful"
- callback([map])
+ callback(map)
return
}
@@ -187,7 +187,7 @@ class HyperswitchNetcetera3ds: NSObject {
var map: [String: String] = [:]
map["status"] = "error"
map["message"] = err.localizedDescription
- callback([map])
+ callback(map)
}
}
}
diff --git a/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/package.json b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/package.json
index d5a57bc9..4179280c 100644
--- a/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/package.json
+++ b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/package.json
@@ -1,10 +1,10 @@
{
"name": "@juspay-tech/react-native-hyperswitch-netcetera-3ds",
- "version": "0.2.2",
+ "version": "0.3.0",
"description": "React Native Hyperswitch Netcetera 3DS",
- "main": "lib/commonjs/index",
- "module": "lib/module/index",
- "types": "lib/typescript/index.d.ts",
+ "main": "./lib/module/index.js",
+ "module": "./lib/module/index.js",
+ "types": "./lib/typescript/src/index.d.ts",
"react-native": "src/index",
"source": "src/index",
"files": [
@@ -49,24 +49,21 @@
"author": "Hyperswitch",
"license": "Apache-2.0",
"devDependencies": {
- "@arkweid/lefthook": "^0.7.7",
- "@babel/eslint-parser": "^7.18.2",
"@commitlint/config-conventional": "^17.0.2",
- "@react-native-community/eslint-config": "^3.0.2",
+ "@react-native/babel-preset": "0.81.1",
"@release-it/conventional-changelog": "^10.0.1",
- "@types/jest": "^28.1.2",
- "@types/react": "~17.0.21",
- "@types/react-native": "0.68.0",
+ "@types/jest": "^29.5.14",
+ "@types/react": "^19.1.0",
"commitlint": "^17.0.2",
"eslint": "^8.4.1",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.0.0",
- "jest": "^28.1.1",
+ "jest": "^29.7.0",
"pod-install": "^0.1.0",
"prettier": "^2.0.5",
- "react": "17.0.2",
- "react-native": "0.68.2",
- "react-native-builder-bob": "^0.18.3",
+ "react": "19.1.0",
+ "react-native": "0.81.1",
+ "react-native-builder-bob": "^0.40.13",
"release-it": "^19.0.5",
"typescript": "^5.9.2"
},
@@ -75,7 +72,7 @@
},
"peerDependencies": {
"react": "*",
- "react-native": "*"
+ "react-native": ">=0.72.0"
},
"jest": {
"preset": "react-native",
@@ -88,8 +85,12 @@
"source": "src",
"output": "lib",
"targets": [
- "commonjs",
- "module",
+ [
+ "module",
+ {
+ "esm": true
+ }
+ ],
[
"typescript",
{
@@ -100,5 +101,21 @@
},
"publishConfig": {
"access": "public"
+ },
+ "exports": {
+ ".": {
+ "source": "./src/index.tsx",
+ "types": "./lib/typescript/src/index.d.ts",
+ "default": "./lib/module/index.js"
+ },
+ "./package.json": "./package.json"
+ },
+ "codegenConfig": {
+ "name": "RNHyperswitchNetcetera3dsSpec",
+ "type": "modules",
+ "jsSrcsDir": "src",
+ "android": {
+ "javaPackageName": "com.reactnativehyperswitchnetcetera3ds"
+ }
}
}
diff --git a/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/react-native-hyperswitch-netcetera-3ds.podspec b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/react-native-hyperswitch-netcetera-3ds.podspec
index 1c893566..f82d66e9 100644
--- a/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/react-native-hyperswitch-netcetera-3ds.podspec
+++ b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/react-native-hyperswitch-netcetera-3ds.podspec
@@ -1,36 +1,21 @@
require "json"
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
-folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
Pod::Spec.new do |s|
- s.name = "react-native-hyperswitch-netcetera-3ds"
- s.version = package["version"]
- s.summary = package["description"]
- s.homepage = package["homepage"]
- s.license = package["license"]
- s.authors = package["author"]
+ s.name = "react-native-hyperswitch-netcetera-3ds"
+ s.version = package["version"]
+ s.summary = package["description"]
+ s.homepage = package["homepage"]
+ s.license = package["license"]
+ s.authors = package["author"]
- s.platforms = { :ios => "10.0" }
- s.source = { :git => "https://github.com/juspay/react-native-hyperswitch-libraries.git", :branch => "main" }
-
- s.source_files = "ios/Source/**/*.{h,m,mm,swift}"
- s.vendored_frameworks = "ios/Frameworks/ThreeDS_SDK.xcframework"
+ s.platforms = { :ios => "13.4" }
+ s.swift_version = '5.0'
+ s.requires_arc = true
+ s.source = { :git => "https://github.com/juspay/react-native-hyperswitch-libraries.git", :branch => "main" }
+ s.source_files = "ios/Source/**/*.{h,m,mm,swift}"
+ s.vendored_frameworks = "ios/Frameworks/ThreeDS_SDK.xcframework"
- s.dependency "React-Core"
-
- # Don't install the dependencies when we run `pod install` in the old architecture.
- if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
- s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
- s.pod_target_xcconfig = {
- "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
- "CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
- }
-
- s.dependency "React-Codegen"
- s.dependency "RCT-Folly"
- s.dependency "RCTRequired"
- s.dependency "RCTTypeSafety"
- s.dependency "ReactCommon/turbomodule/core"
- end
+ install_modules_dependencies(s)
end
diff --git a/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/src/NativeHyperswitchNetcetera3ds.ts b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/src/NativeHyperswitchNetcetera3ds.ts
new file mode 100644
index 00000000..72b17f3b
--- /dev/null
+++ b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/src/NativeHyperswitchNetcetera3ds.ts
@@ -0,0 +1,43 @@
+import type {TurboModule} from 'react-native';
+import {TurboModuleRegistry} from 'react-native';
+
+export type NetceteraStatus = {
+ status: string;
+ message: string;
+};
+
+export type NetceteraAReqParams = {
+ deviceData: string;
+ messageVersion: string;
+ sdkTransId: string;
+ sdkAppId: string;
+ sdkEphemeralKey: string;
+ sdkReferenceNo: string;
+};
+
+export interface Spec extends TurboModule {
+ initialiseNetceteraSDK(
+ apiKey: string,
+ hsSDKEnvironment: string,
+ callback: (status: NetceteraStatus) => void
+ ): void;
+ // Native invokes the callback with (status, aReqParams) in that order.
+ generateAReqParams(
+ messageVersion: string,
+ directoryServerId: string,
+ callback: (status: NetceteraStatus, aReqParams: NetceteraAReqParams) => void
+ ): void;
+ // Parameter order matches the native method (threeDSRequestorAppURL comes
+ // before threeDSServerTransId); the public JS wrapper reorders.
+ recieveChallengeParamsFromRN(
+ acsSignedContent: string,
+ acsRefNumber: string,
+ acsTransactionId: string,
+ threeDSRequestorAppURL: string | null,
+ threeDSServerTransId: string,
+ callback: (status: NetceteraStatus) => void
+ ): void;
+ generateChallenge(callback: (status: NetceteraStatus) => void): void;
+}
+
+export default TurboModuleRegistry.get('HyperswitchNetcetera3ds');
diff --git a/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/src/index.tsx b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/src/index.tsx
index 725ebccc..a42e3f6e 100644
--- a/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/src/index.tsx
+++ b/packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds/src/index.tsx
@@ -1,15 +1,30 @@
-import { NativeModules } from 'react-native';
+import NativeHyperswitchNetcetera3ds from './NativeHyperswitchNetcetera3ds';
-const HyperswitchNetcetera3ds = NativeModules.HyperswitchNetcetera3ds || null;
-const isAvailable =
- HyperswitchNetcetera3ds && HyperswitchNetcetera3ds.initialiseNetceteraSDK;
+// TurboModuleRegistry.get resolves the TurboModule on the new architecture
+// and falls back to the legacy NativeModules entry on the old architecture,
+// so this single code path supports both.
+const isAvailable = NativeHyperswitchNetcetera3ds != null;
+
+export type statusType = {
+ status: string;
+ message: string;
+};
+
+export type AReqParams = {
+ deviceData: string;
+ messageVersion: string;
+ sdkTransId: string;
+ sdkAppId: string;
+ sdkEphemeralKey: any;
+ sdkReferenceNo: string;
+};
function initialiseNetceteraSDK(
apiKey: string,
hsSDKEnvironment: string,
callback: (status: statusType) => void
) {
- return HyperswitchNetcetera3ds.initialiseNetceteraSDK(
+ return NativeHyperswitchNetcetera3ds?.initialiseNetceteraSDK(
apiKey,
hsSDKEnvironment,
callback
@@ -19,9 +34,9 @@ function initialiseNetceteraSDK(
function generateAReqParams(
messageVersion: string,
directoryServerId: string,
- callback: (aReqParams: AReqParams, status: statusType) => void
+ callback: (status: statusType, aReqParams: AReqParams) => void
) {
- return HyperswitchNetcetera3ds.generateAReqParams(
+ return NativeHyperswitchNetcetera3ds?.generateAReqParams(
messageVersion,
directoryServerId,
callback
@@ -29,40 +44,27 @@ function generateAReqParams(
}
function recieveChallengeParamsFromRN(
- acsSignedContent: String,
- acsRefNumber: String,
- acsTransactionId: String,
- threeDSServerTransId: String,
+ acsSignedContent: string,
+ acsRefNumber: string,
+ acsTransactionId: string,
+ threeDSServerTransId: string,
callback: (status: statusType) => void,
- threeDSRequestorAppURL?: String
+ threeDSRequestorAppURL?: string
) {
- return HyperswitchNetcetera3ds.recieveChallengeParamsFromRN(
+ return NativeHyperswitchNetcetera3ds?.recieveChallengeParamsFromRN(
acsSignedContent,
acsRefNumber,
acsTransactionId,
- threeDSRequestorAppURL,
+ threeDSRequestorAppURL ?? null,
threeDSServerTransId,
callback
);
}
+
function generateChallenge(callback: (status: statusType) => void) {
- return HyperswitchNetcetera3ds.generateChallenge(callback);
+ return NativeHyperswitchNetcetera3ds?.generateChallenge(callback);
}
-export type statusType = {
- status: string;
- message: string;
-};
-
-export type AReqParams = {
- deviceData: string;
- messageVersion: string;
- sdkTransId: string;
- sdkAppId: string;
- sdkEphemeralKey: any;
- sdkReferenceNo: string;
-};
-
export {
isAvailable,
initialiseNetceteraSDK,
diff --git a/packages/@juspay-tech/react-native-hyperswitch-paypal/android/build.gradle b/packages/@juspay-tech/react-native-hyperswitch-paypal/android/build.gradle
index 868fdd50..3c7f4b34 100644
--- a/packages/@juspay-tech/react-native-hyperswitch-paypal/android/build.gradle
+++ b/packages/@juspay-tech/react-native-hyperswitch-paypal/android/build.gradle
@@ -16,9 +16,17 @@ buildscript {
}
+def isNewArchitectureEnabled() {
+ return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
+}
+
apply plugin: "com.android.library"
apply plugin: "kotlin-android"
+if (isNewArchitectureEnabled()) {
+ apply plugin: "com.facebook.react"
+}
+
def getExtOrIntegerDefault(name) {
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["ReactNativeHyperswitchPaypal_" + name]).toInteger()
@@ -32,6 +40,11 @@ android {
defaultConfig {
minSdkVersion getExtOrIntegerDefault("minSdkVersion")
targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
+ buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
+ }
+
+ buildFeatures {
+ buildConfig true
}
buildTypes {
@@ -52,6 +65,16 @@ android {
kotlinOptions {
jvmTarget = '17'
}
+
+ sourceSets {
+ main {
+ if (isNewArchitectureEnabled()) {
+ java.srcDirs += ["src/newarch"]
+ } else {
+ java.srcDirs += ["src/oldarch"]
+ }
+ }
+ }
}
repositories {
@@ -67,3 +90,11 @@ dependencies {
implementation "com.paypal.android:paypal-web-payments:2.3.0"
implementation "com.paypal.android:payment-buttons:2.3.0"
}
+
+if (isNewArchitectureEnabled()) {
+ react {
+ jsRootDir = file("../src/")
+ libraryName = "HyperswitchPaypal"
+ codegenJavaPackageName = "com.juspaytech.reactnativehyperswitchpaypal"
+ }
+}
diff --git a/packages/@juspay-tech/react-native-hyperswitch-paypal/android/src/main/java/com/juspaytech/reactnativehyperswitchpaypal/PaypalButtonViewManager.kt b/packages/@juspay-tech/react-native-hyperswitch-paypal/android/src/main/java/com/juspaytech/reactnativehyperswitchpaypal/PaypalButtonViewManagerImpl.kt
similarity index 63%
rename from packages/@juspay-tech/react-native-hyperswitch-paypal/android/src/main/java/com/juspaytech/reactnativehyperswitchpaypal/PaypalButtonViewManager.kt
rename to packages/@juspay-tech/react-native-hyperswitch-paypal/android/src/main/java/com/juspaytech/reactnativehyperswitchpaypal/PaypalButtonViewManagerImpl.kt
index 741bc780..e58a4eff 100644
--- a/packages/@juspay-tech/react-native-hyperswitch-paypal/android/src/main/java/com/juspaytech/reactnativehyperswitchpaypal/PaypalButtonViewManager.kt
+++ b/packages/@juspay-tech/react-native-hyperswitch-paypal/android/src/main/java/com/juspaytech/reactnativehyperswitchpaypal/PaypalButtonViewManagerImpl.kt
@@ -1,30 +1,21 @@
package com.juspaytech.reactnativehyperswitchpaypal
-import com.facebook.react.module.annotations.ReactModule
-import com.facebook.react.uimanager.SimpleViewManager
import com.facebook.react.uimanager.ThemedReactContext
-import com.facebook.react.uimanager.annotations.ReactProp
import com.paypal.android.paymentbuttons.PayPalButtonColor
import com.paypal.android.paymentbuttons.PayPalButtonLabel
import com.paypal.android.paymentbuttons.PaymentButtonSize
-@ReactModule(name = PaypalButtonViewManager.NAME)
-class PaypalButtonViewManager : SimpleViewManager() {
+object PaypalButtonViewManagerImpl {
+ const val NAME = "PaypalButton"
- override fun getName(): String {
- return NAME
- }
-
- public override fun createViewInstance(context: ThemedReactContext): PaypalButtonView {
+ fun createViewInstance(context: ThemedReactContext): PaypalButtonView {
return PaypalButtonView(context)
}
- public override fun onAfterUpdateTransaction(view: PaypalButtonView) {
- super.onAfterUpdateTransaction(view)
+ fun onAfterUpdateTransaction(view: PaypalButtonView) {
view.addButton()
}
- @ReactProp(name = "buttonColor")
fun setButtonColor(view: PaypalButtonView, value: String?) {
view.buttonColor = when (value) {
"GOLD" -> PayPalButtonColor.GOLD
@@ -36,7 +27,6 @@ class PaypalButtonViewManager : SimpleViewManager() {
}
}
- @ReactProp(name = "buttonLabel")
fun setButtonLabel(view: PaypalButtonView, value: String?) {
view.buttonLabel = when (value) {
"CHECKOUT" -> PayPalButtonLabel.CHECKOUT
@@ -46,7 +36,6 @@ class PaypalButtonViewManager : SimpleViewManager() {
}
}
- @ReactProp(name = "buttonSize")
fun setButtonSize(view: PaypalButtonView, value: String?) {
view.buttonSize = when (value) {
"SMALL" -> PaymentButtonSize.SMALL
@@ -55,12 +44,7 @@ class PaypalButtonViewManager : SimpleViewManager() {
}
}
- @ReactProp(name = "borderRadius", defaultDouble = 0.0)
fun setBorderRadius(view: PaypalButtonView, value: Double) {
view.customCornerRadius = value.toFloat()
}
-
- companion object {
- const val NAME = "PaypalButton"
- }
}
diff --git a/packages/@juspay-tech/react-native-hyperswitch-paypal/android/src/main/java/com/juspaytech/reactnativehyperswitchpaypal/ReactNativeHyperswitchPaypalModule.kt b/packages/@juspay-tech/react-native-hyperswitch-paypal/android/src/main/java/com/juspaytech/reactnativehyperswitchpaypal/ReactNativeHyperswitchPaypalModule.kt
index bcf144c2..88b13604 100644
--- a/packages/@juspay-tech/react-native-hyperswitch-paypal/android/src/main/java/com/juspaytech/reactnativehyperswitchpaypal/ReactNativeHyperswitchPaypalModule.kt
+++ b/packages/@juspay-tech/react-native-hyperswitch-paypal/android/src/main/java/com/juspaytech/reactnativehyperswitchpaypal/ReactNativeHyperswitchPaypalModule.kt
@@ -6,13 +6,12 @@ import android.os.Looper
import android.util.Log
import com.facebook.react.bridge.Callback
import com.facebook.react.bridge.ReactApplicationContext
-import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.bridge.WritableNativeMap
import org.json.JSONObject
class ReactNativeHyperswitchPaypalModule(reactContext: ReactApplicationContext) :
- ReactContextBaseJavaModule(reactContext),
+ ReactNativeHyperswitchPaypalSpec(reactContext),
PayPalPendingResult.PayPalResultCallback {
private var currentCallback: Callback? = null
@@ -21,7 +20,7 @@ class ReactNativeHyperswitchPaypalModule(reactContext: ReactApplicationContext)
override fun getName(): String = NAME
@ReactMethod
- fun launchPayPal(requestObj: String, callback: Callback) {
+ override fun launchPayPal(requestObj: String, callback: Callback) {
try {
val json = JSONObject(requestObj)
diff --git a/packages/@juspay-tech/react-native-hyperswitch-paypal/android/src/main/java/com/juspaytech/reactnativehyperswitchpaypal/ReactNativeHyperswitchPaypalPackage.kt b/packages/@juspay-tech/react-native-hyperswitch-paypal/android/src/main/java/com/juspaytech/reactnativehyperswitchpaypal/ReactNativeHyperswitchPaypalPackage.kt
index b140a2c5..2d4a9e62 100644
--- a/packages/@juspay-tech/react-native-hyperswitch-paypal/android/src/main/java/com/juspaytech/reactnativehyperswitchpaypal/ReactNativeHyperswitchPaypalPackage.kt
+++ b/packages/@juspay-tech/react-native-hyperswitch-paypal/android/src/main/java/com/juspaytech/reactnativehyperswitchpaypal/ReactNativeHyperswitchPaypalPackage.kt
@@ -1,17 +1,41 @@
package com.juspaytech.reactnativehyperswitchpaypal
-import android.util.Log
-import com.facebook.react.ReactPackage
+import com.facebook.react.TurboReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
+import com.facebook.react.module.model.ReactModuleInfo
+import com.facebook.react.module.model.ReactModuleInfoProvider
import com.facebook.react.uimanager.ViewManager
-class ReactNativeHyperswitchPaypalPackage : ReactPackage {
- override fun createNativeModules(reactContext: ReactApplicationContext): List {
- return listOf(ReactNativeHyperswitchPaypalModule(reactContext))
+class ReactNativeHyperswitchPaypalPackage : TurboReactPackage() {
+ override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
+ return if (name == ReactNativeHyperswitchPaypalModule.NAME) {
+ ReactNativeHyperswitchPaypalModule(reactContext)
+ } else {
+ null
+ }
}
- override fun createViewManagers(reactContext: ReactApplicationContext): List> {
+ override fun createViewManagers(
+ reactContext: ReactApplicationContext
+ ): List> {
return listOf(PaypalButtonViewManager())
}
+
+ override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
+ return ReactModuleInfoProvider {
+ val moduleInfos: MutableMap = HashMap()
+ val isTurboModule: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
+ moduleInfos[ReactNativeHyperswitchPaypalModule.NAME] = ReactModuleInfo(
+ ReactNativeHyperswitchPaypalModule.NAME,
+ ReactNativeHyperswitchPaypalModule.NAME,
+ false, // canOverrideExistingModule
+ false, // needsEagerInit
+ true, // hasConstants
+ false, // isCxxModule
+ isTurboModule
+ )
+ moduleInfos
+ }
+ }
}
diff --git a/packages/@juspay-tech/react-native-hyperswitch-paypal/android/src/newarch/java/com/juspaytech/reactnativehyperswitchpaypal/PaypalButtonViewManager.kt b/packages/@juspay-tech/react-native-hyperswitch-paypal/android/src/newarch/java/com/juspaytech/reactnativehyperswitchpaypal/PaypalButtonViewManager.kt
new file mode 100644
index 00000000..a3c73124
--- /dev/null
+++ b/packages/@juspay-tech/react-native-hyperswitch-paypal/android/src/newarch/java/com/juspaytech/reactnativehyperswitchpaypal/PaypalButtonViewManager.kt
@@ -0,0 +1,55 @@
+package com.juspaytech.reactnativehyperswitchpaypal
+
+import com.facebook.react.module.annotations.ReactModule
+import com.facebook.react.uimanager.SimpleViewManager
+import com.facebook.react.uimanager.ThemedReactContext
+import com.facebook.react.uimanager.ViewManagerDelegate
+import com.facebook.react.uimanager.annotations.ReactProp
+import com.facebook.react.viewmanagers.PaypalButtonManagerDelegate
+import com.facebook.react.viewmanagers.PaypalButtonManagerInterface
+
+@ReactModule(name = PaypalButtonViewManagerImpl.NAME)
+class PaypalButtonViewManager :
+ SimpleViewManager(),
+ PaypalButtonManagerInterface {
+
+ private val delegate: ViewManagerDelegate =
+ PaypalButtonManagerDelegate(this)
+
+ override fun getDelegate(): ViewManagerDelegate {
+ return delegate
+ }
+
+ override fun getName(): String {
+ return PaypalButtonViewManagerImpl.NAME
+ }
+
+ public override fun createViewInstance(context: ThemedReactContext): PaypalButtonView {
+ return PaypalButtonViewManagerImpl.createViewInstance(context)
+ }
+
+ public override fun onAfterUpdateTransaction(view: PaypalButtonView) {
+ super.onAfterUpdateTransaction(view)
+ PaypalButtonViewManagerImpl.onAfterUpdateTransaction(view)
+ }
+
+ @ReactProp(name = "buttonColor")
+ override fun setButtonColor(view: PaypalButtonView, value: String?) {
+ PaypalButtonViewManagerImpl.setButtonColor(view, value)
+ }
+
+ @ReactProp(name = "buttonLabel")
+ override fun setButtonLabel(view: PaypalButtonView, value: String?) {
+ PaypalButtonViewManagerImpl.setButtonLabel(view, value)
+ }
+
+ @ReactProp(name = "buttonSize")
+ override fun setButtonSize(view: PaypalButtonView, value: String?) {
+ PaypalButtonViewManagerImpl.setButtonSize(view, value)
+ }
+
+ @ReactProp(name = "borderRadius", defaultDouble = 0.0)
+ override fun setBorderRadius(view: PaypalButtonView, value: Double) {
+ PaypalButtonViewManagerImpl.setBorderRadius(view, value)
+ }
+}
diff --git a/packages/@juspay-tech/react-native-hyperswitch-paypal/android/src/newarch/java/com/juspaytech/reactnativehyperswitchpaypal/ReactNativeHyperswitchPaypalSpec.kt b/packages/@juspay-tech/react-native-hyperswitch-paypal/android/src/newarch/java/com/juspaytech/reactnativehyperswitchpaypal/ReactNativeHyperswitchPaypalSpec.kt
new file mode 100644
index 00000000..5c4da2a3
--- /dev/null
+++ b/packages/@juspay-tech/react-native-hyperswitch-paypal/android/src/newarch/java/com/juspaytech/reactnativehyperswitchpaypal/ReactNativeHyperswitchPaypalSpec.kt
@@ -0,0 +1,6 @@
+package com.juspaytech.reactnativehyperswitchpaypal
+
+import com.facebook.react.bridge.ReactApplicationContext
+
+abstract class ReactNativeHyperswitchPaypalSpec internal constructor(context: ReactApplicationContext) :
+ NativeHyperswitchPaypalSpec(context)
diff --git a/packages/@juspay-tech/react-native-hyperswitch-paypal/android/src/oldarch/java/com/juspaytech/reactnativehyperswitchpaypal/PaypalButtonViewManager.kt b/packages/@juspay-tech/react-native-hyperswitch-paypal/android/src/oldarch/java/com/juspaytech/reactnativehyperswitchpaypal/PaypalButtonViewManager.kt
new file mode 100644
index 00000000..6d784ac3
--- /dev/null
+++ b/packages/@juspay-tech/react-native-hyperswitch-paypal/android/src/oldarch/java/com/juspaytech/reactnativehyperswitchpaypal/PaypalButtonViewManager.kt
@@ -0,0 +1,43 @@
+package com.juspaytech.reactnativehyperswitchpaypal
+
+import com.facebook.react.module.annotations.ReactModule
+import com.facebook.react.uimanager.SimpleViewManager
+import com.facebook.react.uimanager.ThemedReactContext
+import com.facebook.react.uimanager.annotations.ReactProp
+
+@ReactModule(name = PaypalButtonViewManagerImpl.NAME)
+class PaypalButtonViewManager : SimpleViewManager() {
+
+ override fun getName(): String {
+ return PaypalButtonViewManagerImpl.NAME
+ }
+
+ public override fun createViewInstance(context: ThemedReactContext): PaypalButtonView {
+ return PaypalButtonViewManagerImpl.createViewInstance(context)
+ }
+
+ public override fun onAfterUpdateTransaction(view: PaypalButtonView) {
+ super.onAfterUpdateTransaction(view)
+ PaypalButtonViewManagerImpl.onAfterUpdateTransaction(view)
+ }
+
+ @ReactProp(name = "buttonColor")
+ fun setButtonColor(view: PaypalButtonView, value: String?) {
+ PaypalButtonViewManagerImpl.setButtonColor(view, value)
+ }
+
+ @ReactProp(name = "buttonLabel")
+ fun setButtonLabel(view: PaypalButtonView, value: String?) {
+ PaypalButtonViewManagerImpl.setButtonLabel(view, value)
+ }
+
+ @ReactProp(name = "buttonSize")
+ fun setButtonSize(view: PaypalButtonView, value: String?) {
+ PaypalButtonViewManagerImpl.setButtonSize(view, value)
+ }
+
+ @ReactProp(name = "borderRadius", defaultDouble = 0.0)
+ fun setBorderRadius(view: PaypalButtonView, value: Double) {
+ PaypalButtonViewManagerImpl.setBorderRadius(view, value)
+ }
+}
diff --git a/packages/@juspay-tech/react-native-hyperswitch-paypal/android/src/oldarch/java/com/juspaytech/reactnativehyperswitchpaypal/ReactNativeHyperswitchPaypalSpec.kt b/packages/@juspay-tech/react-native-hyperswitch-paypal/android/src/oldarch/java/com/juspaytech/reactnativehyperswitchpaypal/ReactNativeHyperswitchPaypalSpec.kt
new file mode 100644
index 00000000..5984d963
--- /dev/null
+++ b/packages/@juspay-tech/react-native-hyperswitch-paypal/android/src/oldarch/java/com/juspaytech/reactnativehyperswitchpaypal/ReactNativeHyperswitchPaypalSpec.kt
@@ -0,0 +1,11 @@
+package com.juspaytech.reactnativehyperswitchpaypal
+
+import com.facebook.react.bridge.Callback
+import com.facebook.react.bridge.ReactApplicationContext
+import com.facebook.react.bridge.ReactContextBaseJavaModule
+
+abstract class ReactNativeHyperswitchPaypalSpec internal constructor(context: ReactApplicationContext) :
+ ReactContextBaseJavaModule(context) {
+
+ abstract fun launchPayPal(requestObj: String, callback: Callback)
+}
diff --git a/packages/@juspay-tech/react-native-hyperswitch-paypal/ios/PaypalButtonComponentView.mm b/packages/@juspay-tech/react-native-hyperswitch-paypal/ios/PaypalButtonComponentView.mm
new file mode 100644
index 00000000..74b221f3
--- /dev/null
+++ b/packages/@juspay-tech/react-native-hyperswitch-paypal/ios/PaypalButtonComponentView.mm
@@ -0,0 +1,75 @@
+#ifdef RCT_NEW_ARCH_ENABLED
+
+#import
+#import
+
+#import
+#import
+
+#if __has_include()
+#import
+#else
+#import "ReactNativeHyperswitchPaypal-Swift.h"
+#endif
+
+using namespace facebook::react;
+
+@interface PaypalButtonComponentView : RCTViewComponentView
+@end
+
+@implementation PaypalButtonComponentView {
+ PaypalButtonView *_view;
+}
+
++ (ComponentDescriptorProvider)componentDescriptorProvider
+{
+ return concreteComponentDescriptorProvider();
+}
+
+- (instancetype)initWithFrame:(CGRect)frame
+{
+ if (self = [super initWithFrame:frame]) {
+ static const auto defaultProps = std::make_shared();
+ _props = defaultProps;
+ _view = [[PaypalButtonView alloc] initWithFrame:frame];
+ self.contentView = _view;
+ }
+ return self;
+}
+
+- (void)prepareForRecycle
+{
+ [super prepareForRecycle];
+ static const auto defaultProps = std::make_shared();
+ _props = defaultProps;
+}
+
+- (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &)oldProps
+{
+ const auto &oldViewProps = *std::static_pointer_cast(_props);
+ const auto &newViewProps = *std::static_pointer_cast(props);
+
+ if (oldViewProps.buttonColor != newViewProps.buttonColor && !newViewProps.buttonColor.empty()) {
+ _view.buttonColor = RCTNSStringFromString(newViewProps.buttonColor);
+ }
+ if (oldViewProps.buttonLabel != newViewProps.buttonLabel && !newViewProps.buttonLabel.empty()) {
+ _view.buttonLabel = RCTNSStringFromString(newViewProps.buttonLabel);
+ }
+ if (oldViewProps.buttonSize != newViewProps.buttonSize && !newViewProps.buttonSize.empty()) {
+ _view.buttonSize = RCTNSStringFromString(newViewProps.buttonSize);
+ }
+ if (oldViewProps.borderRadius != newViewProps.borderRadius) {
+ _view.borderRadius = newViewProps.borderRadius;
+ }
+
+ [super updateProps:props oldProps:oldProps];
+}
+
+@end
+
+Class PaypalButtonCls(void)
+{
+ return PaypalButtonComponentView.class;
+}
+
+#endif // RCT_NEW_ARCH_ENABLED
diff --git a/packages/@juspay-tech/react-native-hyperswitch-paypal/ios/PaypalButtonView.swift b/packages/@juspay-tech/react-native-hyperswitch-paypal/ios/PaypalButtonView.swift
index efe9c117..9b6aa565 100644
--- a/packages/@juspay-tech/react-native-hyperswitch-paypal/ios/PaypalButtonView.swift
+++ b/packages/@juspay-tech/react-native-hyperswitch-paypal/ios/PaypalButtonView.swift
@@ -1,33 +1,33 @@
import UIKit
import PayPal
-class PaypalButtonView: UIView {
+@objc public class PaypalButtonView: UIView {
private var payPalButton: PayPalButton?
private var containerView: UIView?
- @objc dynamic var buttonColor: String = "gold" {
+ @objc public dynamic var buttonColor: String = "gold" {
didSet { updateButton() }
}
- @objc dynamic var buttonLabel: String = "paypal" {
+ @objc public dynamic var buttonLabel: String = "paypal" {
didSet { updateButton() }
}
- @objc dynamic var buttonSize: String = "medium" {
+ @objc public dynamic var buttonSize: String = "medium" {
didSet { updateButton() }
}
- @objc dynamic var borderRadius: Double = 0 {
+ @objc public dynamic var borderRadius: Double = 0 {
didSet { updateButton() }
}
- override init(frame: CGRect) {
+ public override init(frame: CGRect) {
super.init(frame: frame)
setupButton()
}
- required init?(coder: NSCoder) {
+ public required init?(coder: NSCoder) {
super.init(coder: coder)
setupButton()
}
@@ -119,11 +119,11 @@ class PaypalButtonView: UIView {
reactView.reactSubviews().first?.perform(#selector(UIView.didMoveToWindow))
}
- override var intrinsicContentSize: CGSize {
+ public override var intrinsicContentSize: CGSize {
return CGSize(width: UIView.noIntrinsicMetric, height: 48)
}
- override func layoutSubviews() {
+ public override func layoutSubviews() {
super.layoutSubviews()
payPalButton?.layoutSubviews()
}
diff --git a/packages/@juspay-tech/react-native-hyperswitch-paypal/ios/ReactNativeHyperswitchPaypal.mm b/packages/@juspay-tech/react-native-hyperswitch-paypal/ios/ReactNativeHyperswitchPaypal.mm
index 155a69ba..e1eb8804 100644
--- a/packages/@juspay-tech/react-native-hyperswitch-paypal/ios/ReactNativeHyperswitchPaypal.mm
+++ b/packages/@juspay-tech/react-native-hyperswitch-paypal/ios/ReactNativeHyperswitchPaypal.mm
@@ -1,13 +1,61 @@
#import
#import
-@interface RCT_EXTERN_MODULE(HyperswitchPaypal, NSObject)
+#ifdef RCT_NEW_ARCH_ENABLED
+#import "RNHyperswitchPaypalSpec.h"
+#endif
-RCT_EXTERN_METHOD(launchPayPal:(NSString *)requestObj
+#if __has_include()
+#import
+#else
+#import "ReactNativeHyperswitchPaypal-Swift.h"
+#endif
+
+@interface HyperswitchPaypal : NSObject
+@end
+
+#ifdef RCT_NEW_ARCH_ENABLED
+@interface HyperswitchPaypal ()
+@end
+#endif
+
+@implementation HyperswitchPaypal {
+ HyperswitchPaypalImpl *_impl;
+}
+
+RCT_EXPORT_MODULE()
+
+- (instancetype)init
+{
+ if (self = [super init]) {
+ _impl = [HyperswitchPaypalImpl new];
+ }
+ return self;
+}
+
++ (BOOL)requiresMainQueueSetup
+{
+ return YES;
+}
+
+RCT_EXPORT_METHOD(launchPayPal:(NSString *)requestObj
callback:(RCTResponseSenderBlock)callback)
+{
+ [self->_impl launchPayPal:requestObj callback:callback];
+}
+
+#ifdef RCT_NEW_ARCH_ENABLED
+- (std::shared_ptr)getTurboModule:
+ (const facebook::react::ObjCTurboModule::InitParams &)params
+{
+ return std::make_shared(params);
+}
+#endif
@end
+#ifndef RCT_NEW_ARCH_ENABLED
+
@interface RCT_EXTERN_MODULE(PaypalButton, RCTViewManager)
RCT_EXPORT_VIEW_PROPERTY(buttonColor, NSString)
@@ -16,3 +64,5 @@ @interface RCT_EXTERN_MODULE(PaypalButton, RCTViewManager)
RCT_EXPORT_VIEW_PROPERTY(borderRadius, double)
@end
+
+#endif // !RCT_NEW_ARCH_ENABLED
diff --git a/packages/@juspay-tech/react-native-hyperswitch-paypal/ios/ReactNativeHyperswitchPaypal.swift b/packages/@juspay-tech/react-native-hyperswitch-paypal/ios/ReactNativeHyperswitchPaypal.swift
index c0c80913..d7b59a00 100644
--- a/packages/@juspay-tech/react-native-hyperswitch-paypal/ios/ReactNativeHyperswitchPaypal.swift
+++ b/packages/@juspay-tech/react-native-hyperswitch-paypal/ios/ReactNativeHyperswitchPaypal.swift
@@ -1,17 +1,11 @@
+import Foundation
import PayPal
-@objc(HyperswitchPaypal)
-class ReactNativeHyperswitchPaypal: NSObject {
+@objc public class HyperswitchPaypalImpl: NSObject {
private static let TAG = "HyperswitchPaypal"
- @objc
- static func requiresMainQueueSetup() -> Bool {
- return true
- }
-
- @objc(launchPayPal:callback:)
- func launchPayPal(_ requestObj: String, callback: @escaping RCTResponseSenderBlock) {
+ @objc public func launchPayPal(_ requestObj: String, callback: @escaping ([Any]) -> Void) {
guard let data = requestObj.data(using: .utf8),
let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else {
diff --git a/packages/@juspay-tech/react-native-hyperswitch-paypal/package.json b/packages/@juspay-tech/react-native-hyperswitch-paypal/package.json
index 10d9cb18..6ec16d77 100644
--- a/packages/@juspay-tech/react-native-hyperswitch-paypal/package.json
+++ b/packages/@juspay-tech/react-native-hyperswitch-paypal/package.json
@@ -1,6 +1,6 @@
{
"name": "@juspay-tech/react-native-hyperswitch-paypal",
- "version": "1.0.2",
+ "version": "1.1.0",
"description": "react native hyperswitch paypal",
"source": "./src/index.tsx",
"main": "./lib/module/index.js",
@@ -84,7 +84,7 @@
},
"peerDependencies": {
"react": "*",
- "react-native": "*"
+ "react-native": ">=0.72.0"
},
"workspaces": [
"../../../example"
@@ -150,5 +150,18 @@
"type": "legacy-module",
"languages": "kotlin-swift",
"version": "0.49.8"
+ },
+ "codegenConfig": {
+ "name": "RNHyperswitchPaypalSpec",
+ "type": "all",
+ "jsSrcsDir": "src",
+ "android": {
+ "javaPackageName": "com.juspaytech.reactnativehyperswitchpaypal"
+ },
+ "ios": {
+ "componentProvider": {
+ "PaypalButton": "PaypalButtonComponentView"
+ }
+ }
}
}
diff --git a/packages/@juspay-tech/react-native-hyperswitch-paypal/src/NativeHyperswitchPaypal.ts b/packages/@juspay-tech/react-native-hyperswitch-paypal/src/NativeHyperswitchPaypal.ts
new file mode 100644
index 00000000..d74af7a7
--- /dev/null
+++ b/packages/@juspay-tech/react-native-hyperswitch-paypal/src/NativeHyperswitchPaypal.ts
@@ -0,0 +1,18 @@
+import type {TurboModule} from 'react-native';
+import {TurboModuleRegistry} from 'react-native';
+
+export type PayPalNativeResult = {
+ status: string;
+ orderId?: string;
+ payerId?: string;
+ error_message?: string;
+};
+
+export interface Spec extends TurboModule {
+ launchPayPal(
+ requestObj: string,
+ callback: (result: PayPalNativeResult) => void
+ ): void;
+}
+
+export default TurboModuleRegistry.get('HyperswitchPaypal');
diff --git a/packages/@juspay-tech/react-native-hyperswitch-paypal/src/PaypalButtonNativeComponent.android.ts b/packages/@juspay-tech/react-native-hyperswitch-paypal/src/PaypalButtonNativeComponent.android.ts
deleted file mode 100644
index 05c531c3..00000000
--- a/packages/@juspay-tech/react-native-hyperswitch-paypal/src/PaypalButtonNativeComponent.android.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { requireNativeComponent, type ViewProps } from 'react-native';
-
-interface NativeProps extends ViewProps {
- buttonColor?: string;
- buttonLabel?: string;
- buttonSize?: string;
- borderRadius?: number;
-}
-
-export default requireNativeComponent('PaypalButton');
diff --git a/packages/@juspay-tech/react-native-hyperswitch-paypal/src/PaypalButtonNativeComponent.ts b/packages/@juspay-tech/react-native-hyperswitch-paypal/src/PaypalButtonNativeComponent.ts
new file mode 100644
index 00000000..bf426d07
--- /dev/null
+++ b/packages/@juspay-tech/react-native-hyperswitch-paypal/src/PaypalButtonNativeComponent.ts
@@ -0,0 +1,19 @@
+// Deep imports keep the compiled output loadable on old-architecture React
+// Native consumers down to 0.72, where the root exports for
+// codegenNativeComponent/CodegenTypes do not exist at runtime.
+import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
+import type {Double} from 'react-native/Libraries/Types/CodegenTypes';
+import type {HostComponent, ViewProps} from 'react-native';
+
+export interface NativeProps extends ViewProps {
+ buttonColor?: string;
+ buttonLabel?: string;
+ buttonSize?: string;
+ borderRadius?: Double;
+}
+
+// codegenNativeComponent works on both architectures: static view config +
+// Fabric on the new architecture, Paper view config lookup on the old one.
+export default codegenNativeComponent(
+ 'PaypalButton'
+) as HostComponent;
diff --git a/packages/@juspay-tech/react-native-hyperswitch-paypal/src/codegen-shims.d.ts b/packages/@juspay-tech/react-native-hyperswitch-paypal/src/codegen-shims.d.ts
new file mode 100644
index 00000000..979f212e
--- /dev/null
+++ b/packages/@juspay-tech/react-native-hyperswitch-paypal/src/codegen-shims.d.ts
@@ -0,0 +1,28 @@
+// Ambient declarations for react-native deep imports used by the codegen
+// specs. The runtime modules exist on every supported React Native version,
+// but the strict TypeScript API of newer versions does not expose their
+// types. This file is not part of any codegen spec (name matches neither
+// Native* nor *NativeComponent).
+declare module 'react-native/Libraries/Utilities/codegenNativeComponent' {
+ import type {HostComponent} from 'react-native';
+
+ type Options = {
+ interfaceOnly?: boolean;
+ paperComponentName?: string;
+ paperComponentNameDeprecated?: string;
+ excludedPlatforms?: ReadonlyArray<'iOS' | 'android'>;
+ };
+
+ export default function codegenNativeComponent(
+ componentName: string,
+ options?: Options
+ ): HostComponent;
+}
+
+declare module 'react-native/Libraries/Types/CodegenTypes' {
+ export type Double = number;
+ export type Float = number;
+ export type Int32 = number;
+ export type UnsafeObject = object;
+ export type WithDefault = T | undefined;
+}
diff --git a/packages/@juspay-tech/react-native-hyperswitch-paypal/src/index.tsx b/packages/@juspay-tech/react-native-hyperswitch-paypal/src/index.tsx
index 6f3dcb29..35bfa233 100644
--- a/packages/@juspay-tech/react-native-hyperswitch-paypal/src/index.tsx
+++ b/packages/@juspay-tech/react-native-hyperswitch-paypal/src/index.tsx
@@ -1,8 +1,14 @@
-import { NativeModules } from 'react-native';
+import NativeHyperswitchPaypal from './NativeHyperswitchPaypal';
-const { HyperswitchPaypal } = NativeModules;
+// TurboModuleRegistry.get resolves the TurboModule on the new architecture
+// and falls back to the legacy NativeModules entry on the old architecture,
+// so this single code path supports both.
+export const isAvailable = NativeHyperswitchPaypal != null;
-export const isAvailable = !!HyperswitchPaypal;
+import PaypalButtonNativeComponent from './PaypalButtonNativeComponent';
+
+export const PaypalButton = PaypalButtonNativeComponent;
+export type {NativeProps as PaypalButtonProps} from './PaypalButtonNativeComponent';
export type PayPalResult = {
status: string;
@@ -23,12 +29,12 @@ export function launchPayPal(
requestObj: string,
callback: (result: PayPalResult) => void
): void {
- if (!HyperswitchPaypal) {
+ if (!NativeHyperswitchPaypal) {
callback({
status: 'failed',
error_message: 'PayPal module not available',
});
return;
}
- return HyperswitchPaypal.launchPayPal(requestObj, callback);
+ return NativeHyperswitchPaypal.launchPayPal(requestObj, callback);
}
diff --git a/packages/@juspay-tech/react-native-hyperswitch-scancard/android/build.gradle b/packages/@juspay-tech/react-native-hyperswitch-scancard/android/build.gradle
index a82d41cc..66fb5734 100644
--- a/packages/@juspay-tech/react-native-hyperswitch-scancard/android/build.gradle
+++ b/packages/@juspay-tech/react-native-hyperswitch-scancard/android/build.gradle
@@ -1,18 +1,17 @@
buildscript {
- // Buildscript is evaluated before everything else so we can't use getExtOrDefault
- def kotlin_version = rootProject.ext.has('kotlinVersion') ? rootProject.ext.get('kotlinVersion') : project.properties['HyperswitchScancard_kotlinVersion']
+ ext.getExtOrDefault = {name ->
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['HyperswitchScancard_' + name]
+ }
repositories {
google()
mavenCentral()
}
-
dependencies {
- classpath 'com.android.tools.build:gradle:3.5.3'
+ classpath "com.android.tools.build:gradle:8.7.2"
// noinspection DifferentKotlinGradleVersion
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
- classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.0'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}"
}
}
@@ -20,12 +19,11 @@ def isNewArchitectureEnabled() {
return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
}
-apply plugin: 'com.android.library'
-apply plugin: 'kotlin-android'
-
+apply plugin: "com.android.library"
+apply plugin: "kotlin-android"
if (isNewArchitectureEnabled()) {
- apply plugin: 'com.facebook.react'
+ apply plugin: "com.facebook.react"
}
def getExtOrDefault(name) {
@@ -36,19 +34,42 @@ def getExtOrIntegerDefault(name) {
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties['HyperswitchScancard_' + name]).toInteger()
}
+def supportsNamespace() {
+ def parsed = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')
+ def major = parsed[0].toInteger()
+ def minor = parsed[1].toInteger()
+
+ // Namespace support was added in 7.3.0
+ return (major == 7 && minor >= 3) || major >= 8
+}
+
android {
+ if (supportsNamespace()) {
+ namespace "com.reactnativehyperswitchscancard"
+
+ sourceSets {
+ main {
+ manifest.srcFile "src/main/AndroidManifestNew.xml"
+ }
+ }
+ }
viewBinding {
enabled = true
}
- compileSdkVersion getExtOrIntegerDefault('compileSdkVersion')
+ compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
defaultConfig {
- minSdkVersion getExtOrIntegerDefault('minSdkVersion')
- targetSdkVersion getExtOrIntegerDefault('targetSdkVersion')
+ minSdkVersion getExtOrIntegerDefault("minSdkVersion")
+ targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
}
+
+ buildFeatures {
+ buildConfig true
+ }
+
buildTypes {
release {
minifyEnabled false
@@ -56,81 +77,34 @@ android {
}
lintOptions {
- disable 'GradleCompatible'
+ disable "GradleCompatible"
}
compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
+ sourceCompatibility JavaVersion.VERSION_17
+ targetCompatibility JavaVersion.VERSION_17
+ }
+
+ sourceSets {
+ main {
+ if (isNewArchitectureEnabled()) {
+ java.srcDirs += ["src/newarch"]
+ } else {
+ java.srcDirs += ["src/oldarch"]
+ }
+ }
}
}
repositories {
mavenCentral()
google()
-
- def found = false
- def defaultDir = null
- def androidSourcesName = 'React Native sources'
-
- if (rootProject.ext.has('reactNativeAndroidRoot')) {
- defaultDir = rootProject.ext.get('reactNativeAndroidRoot')
- } else {
- defaultDir = new File(projectDir,
- '/../../../node_modules/react-native/android')
- }
-
- if (defaultDir.exists()) {
- maven {
- url defaultDir.toString()
- name androidSourcesName
- }
-
- logger.info(":${project.name}:reactNativeAndroidRoot ${defaultDir.canonicalPath}")
- found = true
- } else {
- def parentDir = rootProject.projectDir
-
- 1.upto(5, {
- if (found) return true
- parentDir = parentDir.parentFile
-
- def androidSourcesDir = new File(parentDir,
- 'node_modules/react-native')
-
- def androidPrebuiltBinaryDir = new File(parentDir,
- 'node_modules/react-native/android')
-
- if (androidPrebuiltBinaryDir.exists()) {
- maven {
- url androidPrebuiltBinaryDir.toString()
- name androidSourcesName
- }
-
- logger.info(":${project.name}:reactNativeAndroidRoot ${androidPrebuiltBinaryDir.canonicalPath}")
- found = true
- } else if (androidSourcesDir.exists()) {
- maven {
- url androidSourcesDir.toString()
- name androidSourcesName
- }
-
- logger.info(":${project.name}:reactNativeAndroidRoot ${androidSourcesDir.canonicalPath}")
- found = true
- }
- })
- }
-
- if (!found) {
- throw new GradleException("${project.name}: unable to locate React Native android sources. " + "Ensure you have you installed React Native as a dependency in your project and try again.")
- }
}
-def kotlin_version = getExtOrDefault('kotlinVersion')
+def kotlin_version = getExtOrDefault("kotlinVersion")
dependencies {
- //noinspection GradleDynamicVersion
- implementation "com.facebook.react:react-native:+"
+ implementation "com.facebook.react:react-android"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "io.hyperswitch:hyperswitch-sdk-android-scancard:1.0.0"
}
diff --git a/packages/@juspay-tech/react-native-hyperswitch-scancard/android/src/main/AndroidManifestNew.xml b/packages/@juspay-tech/react-native-hyperswitch-scancard/android/src/main/AndroidManifestNew.xml
new file mode 100644
index 00000000..a2f47b60
--- /dev/null
+++ b/packages/@juspay-tech/react-native-hyperswitch-scancard/android/src/main/AndroidManifestNew.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/packages/@juspay-tech/react-native-hyperswitch-scancard/android/src/main/java/com/reactnativehyperswitchscancard/HyperswitchScancardModule.kt b/packages/@juspay-tech/react-native-hyperswitch-scancard/android/src/main/java/com/reactnativehyperswitchscancard/HyperswitchScancardModule.kt
index e6d6e78b..d05bf434 100644
--- a/packages/@juspay-tech/react-native-hyperswitch-scancard/android/src/main/java/com/reactnativehyperswitchscancard/HyperswitchScancardModule.kt
+++ b/packages/@juspay-tech/react-native-hyperswitch-scancard/android/src/main/java/com/reactnativehyperswitchscancard/HyperswitchScancardModule.kt
@@ -4,20 +4,19 @@ import androidx.fragment.app.FragmentActivity
import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.Callback
import com.facebook.react.bridge.ReactApplicationContext
-import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import io.hyperswitch.scancard.ScanCardCallback
import io.hyperswitch.scancard.ScanCardManager
class HyperswitchScancardModule(reactContext: ReactApplicationContext) :
- ReactContextBaseJavaModule(reactContext) {
+ HyperswitchScancardSpec(reactContext) {
override fun getName(): String {
- return "HyperswitchScancard"
+ return NAME
}
@ReactMethod
- fun launchScanCard(scanCardRequest: String, callBack: Callback) {
+ override fun launchScanCard(scanCardRequest: String, callback: Callback) {
(currentActivity as? FragmentActivity)?.let {
ScanCardManager.launch(it, object : ScanCardCallback {
override fun onScanResult(result: Map) {
@@ -34,9 +33,13 @@ class HyperswitchScancardModule(reactContext: ReactApplicationContext) :
val map = Arguments.createMap()
map.putString("status", result["status"] as String? ?: "Failed")
map.putMap("data", dataMap)
- callBack.invoke(map)
+ callback.invoke(map)
}
})
}
}
+
+ companion object {
+ const val NAME = "HyperswitchScancard"
+ }
}
diff --git a/packages/@juspay-tech/react-native-hyperswitch-scancard/android/src/main/java/com/reactnativehyperswitchscancard/HyperswitchScancardPackage.kt b/packages/@juspay-tech/react-native-hyperswitch-scancard/android/src/main/java/com/reactnativehyperswitchscancard/HyperswitchScancardPackage.kt
index 13903cc3..80ac340c 100644
--- a/packages/@juspay-tech/react-native-hyperswitch-scancard/android/src/main/java/com/reactnativehyperswitchscancard/HyperswitchScancardPackage.kt
+++ b/packages/@juspay-tech/react-native-hyperswitch-scancard/android/src/main/java/com/reactnativehyperswitchscancard/HyperswitchScancardPackage.kt
@@ -1,16 +1,34 @@
package com.reactnativehyperswitchscancard
-import com.facebook.react.ReactPackage
+
+import com.facebook.react.TurboReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
-import com.facebook.react.uimanager.ViewManager
-
+import com.facebook.react.module.model.ReactModuleInfo
+import com.facebook.react.module.model.ReactModuleInfoProvider
-class HyperswitchScancardPackage : ReactPackage {
- override fun createNativeModules(reactContext: ReactApplicationContext): List {
- return listOf(HyperswitchScancardModule(reactContext))
+class HyperswitchScancardPackage : TurboReactPackage() {
+ override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
+ return if (name == HyperswitchScancardModule.NAME) {
+ HyperswitchScancardModule(reactContext)
+ } else {
+ null
}
+ }
- override fun createViewManagers(reactContext: ReactApplicationContext): List> {
- return emptyList()
+ override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
+ return ReactModuleInfoProvider {
+ val moduleInfos: MutableMap = HashMap()
+ val isTurboModule: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
+ moduleInfos[HyperswitchScancardModule.NAME] = ReactModuleInfo(
+ HyperswitchScancardModule.NAME,
+ HyperswitchScancardModule.NAME,
+ false, // canOverrideExistingModule
+ false, // needsEagerInit
+ true, // hasConstants
+ false, // isCxxModule
+ isTurboModule
+ )
+ moduleInfos
}
+ }
}
diff --git a/packages/@juspay-tech/react-native-hyperswitch-scancard/android/src/newarch/java/com/reactnativehyperswitchscancard/HyperswitchScancardSpec.kt b/packages/@juspay-tech/react-native-hyperswitch-scancard/android/src/newarch/java/com/reactnativehyperswitchscancard/HyperswitchScancardSpec.kt
new file mode 100644
index 00000000..0ee92ddf
--- /dev/null
+++ b/packages/@juspay-tech/react-native-hyperswitch-scancard/android/src/newarch/java/com/reactnativehyperswitchscancard/HyperswitchScancardSpec.kt
@@ -0,0 +1,6 @@
+package com.reactnativehyperswitchscancard
+
+import com.facebook.react.bridge.ReactApplicationContext
+
+abstract class HyperswitchScancardSpec internal constructor(context: ReactApplicationContext) :
+ NativeHyperswitchScancardSpec(context)
diff --git a/packages/@juspay-tech/react-native-hyperswitch-scancard/android/src/oldarch/java/com/reactnativehyperswitchscancard/HyperswitchScancardSpec.kt b/packages/@juspay-tech/react-native-hyperswitch-scancard/android/src/oldarch/java/com/reactnativehyperswitchscancard/HyperswitchScancardSpec.kt
new file mode 100644
index 00000000..96857fc4
--- /dev/null
+++ b/packages/@juspay-tech/react-native-hyperswitch-scancard/android/src/oldarch/java/com/reactnativehyperswitchscancard/HyperswitchScancardSpec.kt
@@ -0,0 +1,11 @@
+package com.reactnativehyperswitchscancard
+
+import com.facebook.react.bridge.Callback
+import com.facebook.react.bridge.ReactApplicationContext
+import com.facebook.react.bridge.ReactContextBaseJavaModule
+
+abstract class HyperswitchScancardSpec internal constructor(context: ReactApplicationContext) :
+ ReactContextBaseJavaModule(context) {
+
+ abstract fun launchScanCard(scanCardRequest: String, callback: Callback)
+}
diff --git a/packages/@juspay-tech/react-native-hyperswitch-scancard/ios/Source/HyperswitchScancard-Bridging-Header.h b/packages/@juspay-tech/react-native-hyperswitch-scancard/ios/Source/HyperswitchScancard-Bridging-Header.h
deleted file mode 100644
index dea7ff6b..00000000
--- a/packages/@juspay-tech/react-native-hyperswitch-scancard/ios/Source/HyperswitchScancard-Bridging-Header.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#import
-#import
diff --git a/packages/@juspay-tech/react-native-hyperswitch-scancard/ios/Source/HyperswitchScancard.m b/packages/@juspay-tech/react-native-hyperswitch-scancard/ios/Source/HyperswitchScancard.m
deleted file mode 100644
index 468ffa37..00000000
--- a/packages/@juspay-tech/react-native-hyperswitch-scancard/ios/Source/HyperswitchScancard.m
+++ /dev/null
@@ -1,12 +0,0 @@
-#import
-
-@interface RCT_EXTERN_MODULE(HyperswitchScancard, NSObject)
-
-RCT_EXTERN_METHOD(launchScanCard: (NSString)rnMessage :(RCTResponseSenderBlock)rnCallback)
-
-+ (BOOL)requiresMainQueueSetup
-{
- return NO;
-}
-
-@end
diff --git a/packages/@juspay-tech/react-native-hyperswitch-scancard/ios/Source/HyperswitchScancard.mm b/packages/@juspay-tech/react-native-hyperswitch-scancard/ios/Source/HyperswitchScancard.mm
new file mode 100644
index 00000000..a9367e25
--- /dev/null
+++ b/packages/@juspay-tech/react-native-hyperswitch-scancard/ios/Source/HyperswitchScancard.mm
@@ -0,0 +1,65 @@
+#import
+#import
+
+#ifdef RCT_NEW_ARCH_ENABLED
+#import "RNHyperswitchScancardSpec.h"
+#endif
+
+#if __has_include()
+#import
+#else
+#import "react_native_hyperswitch_scancard-Swift.h"
+#endif
+
+@interface HyperswitchScancard : NSObject
+@end
+
+#ifdef RCT_NEW_ARCH_ENABLED
+@interface HyperswitchScancard ()
+@end
+#endif
+
+@implementation HyperswitchScancard {
+ HyperswitchScancardImpl *_impl;
+}
+
+RCT_EXPORT_MODULE()
+
+- (instancetype)init
+{
+ if (self = [super init]) {
+ _impl = [HyperswitchScancardImpl new];
+ }
+ return self;
+}
+
++ (BOOL)requiresMainQueueSetup
+{
+ return NO;
+}
+
+RCT_EXPORT_METHOD(launchScanCard:(NSString *)scanCardRequest
+ callback:(RCTResponseSenderBlock)callback)
+{
+ dispatch_async(dispatch_get_main_queue(), ^{
+ UIViewController *presentedViewController = RCTPresentedViewController();
+ if (presentedViewController == nil) {
+ callback(@[ @{@"status" : @"Failed"} ]);
+ return;
+ }
+ [self->_impl launchScanCardFrom:presentedViewController
+ callback:^(NSDictionary *response) {
+ callback(@[ response ]);
+ }];
+ });
+}
+
+#ifdef RCT_NEW_ARCH_ENABLED
+- (std::shared_ptr)getTurboModule:
+ (const facebook::react::ObjCTurboModule::InitParams &)params
+{
+ return std::make_shared(params);
+}
+#endif
+
+@end
diff --git a/packages/@juspay-tech/react-native-hyperswitch-scancard/ios/Source/HyperswitchScancard.swift b/packages/@juspay-tech/react-native-hyperswitch-scancard/ios/Source/HyperswitchScancard.swift
index 4a393bda..5ad48027 100644
--- a/packages/@juspay-tech/react-native-hyperswitch-scancard/ios/Source/HyperswitchScancard.swift
+++ b/packages/@juspay-tech/react-native-hyperswitch-scancard/ios/Source/HyperswitchScancard.swift
@@ -1,35 +1,30 @@
import Foundation
+import UIKit
import HyperswitchScanCard
+@objc public class HyperswitchScancardImpl: NSObject {
-@objc(HyperswitchScancard)
-class HyperswitchScancard: NSObject {
-
- @objc
- func launchScanCard(_ rnMessage: String, _ rnCallback: @escaping RCTResponseSenderBlock) {
-
- DispatchQueue.main.async {
- var message: [String:Any] = [:]
- var callback: [String:Any] = [:]
- let cardScanSheet = CardScanSheet()
- cardScanSheet.present(from: RCTPresentedViewController()!) { result in
-
- switch result {
- case .completed(var card as ScannedCard?):
- message["pan"] = card?.pan
- message["expiryMonth"] = card?.expiryMonth
- message["expiryYear"] = card?.expiryYear
- callback["status"] = "Succeeded"
- callback["data"] = message
- case .canceled:
- callback["status"] = "Cancelled"
- case .failed(let error):
- callback["status"] = "Failed"
- }
- rnCallback([callback])
+ @objc public func launchScanCard(from viewController: UIViewController,
+ callback: @escaping ([String: Any]) -> Void) {
+ var message: [String: Any] = [:]
+ var response: [String: Any] = [:]
+ let cardScanSheet = CardScanSheet()
+ cardScanSheet.present(from: viewController) { result in
+
+ switch result {
+ case .completed(let card as ScannedCard?):
+ message["pan"] = card?.pan
+ message["expiryMonth"] = card?.expiryMonth
+ message["expiryYear"] = card?.expiryYear
+ response["status"] = "Succeeded"
+ response["data"] = message
+ case .canceled:
+ response["status"] = "Cancelled"
+ case .failed:
+ response["status"] = "Failed"
}
+ callback(response)
}
}
}
-
diff --git a/packages/@juspay-tech/react-native-hyperswitch-scancard/package.json b/packages/@juspay-tech/react-native-hyperswitch-scancard/package.json
index 8a2b7b1c..090f23bc 100644
--- a/packages/@juspay-tech/react-native-hyperswitch-scancard/package.json
+++ b/packages/@juspay-tech/react-native-hyperswitch-scancard/package.json
@@ -1,10 +1,10 @@
{
"name": "@juspay-tech/react-native-hyperswitch-scancard",
- "version": "0.2.3",
+ "version": "0.3.0",
"description": "React Native Hyperswitch ScanCard",
- "main": "lib/commonjs/index",
- "module": "lib/module/index",
- "types": "lib/typescript/src/index.d.ts",
+ "main": "./lib/module/index.js",
+ "module": "./lib/module/index.js",
+ "types": "./lib/typescript/src/index.d.ts",
"exports": {
".": {
"source": "./src/index.tsx",
@@ -85,7 +85,7 @@
},
"peerDependencies": {
"react": "*",
- "react-native": "*",
+ "react-native": ">=0.72.0",
"react-native-webview": "*"
},
"jest": {
@@ -148,5 +148,13 @@
"languages": "kotlin-objc",
"type": "turbo-module",
"version": "0.54.5"
+ },
+ "codegenConfig": {
+ "name": "RNHyperswitchScancardSpec",
+ "type": "modules",
+ "jsSrcsDir": "src",
+ "android": {
+ "javaPackageName": "com.reactnativehyperswitchscancard"
+ }
}
}
diff --git a/packages/@juspay-tech/react-native-hyperswitch-scancard/react-native-hyperswitch-scancard.podspec b/packages/@juspay-tech/react-native-hyperswitch-scancard/react-native-hyperswitch-scancard.podspec
index 3541cb8d..2875fcb1 100644
--- a/packages/@juspay-tech/react-native-hyperswitch-scancard/react-native-hyperswitch-scancard.podspec
+++ b/packages/@juspay-tech/react-native-hyperswitch-scancard/react-native-hyperswitch-scancard.podspec
@@ -1,7 +1,6 @@
require "json"
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
-folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
Pod::Spec.new do |s|
s.name = "react-native-hyperswitch-scancard"
@@ -11,7 +10,7 @@ Pod::Spec.new do |s|
s.license = package["license"]
s.authors = package["author"]
- s.platforms = { :ios => "13.0" }
+ s.platforms = { :ios => "13.4" }
s.swift_version = '5.0'
s.requires_arc = true
s.source = { :git => "https://github.com/juspay/react-native-hyperswitch-libraries.git", :branch => "main" }
@@ -20,20 +19,8 @@ Pod::Spec.new do |s|
s.source_files = "ios/Source/**/*.{h,m,mm,swift}"
s.vendored_frameworks = "ios/Frameworks/HyperswitchScanCard.xcframework"
- s.dependency "React-Core"
-
- # Don't install the dependencies when we run `pod install` in the old architecture.
- if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
- s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
- s.pod_target_xcconfig = {
- "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
- "CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
- }
-
- s.dependency "React-Codegen"
- s.dependency "RCT-Folly"
- s.dependency "RCTRequired"
- s.dependency "RCTTypeSafety"
- s.dependency "ReactCommon/turbomodule/core"
- end
+ # Wires up React-Core plus, when the consumer enables the new architecture,
+ # codegen/Fabric/TurboModule dependencies and compiler flags
+ # (RCT_NEW_ARCH_ENABLED). Available on React Native >= 0.71.
+ install_modules_dependencies(s)
end
diff --git a/packages/@juspay-tech/react-native-hyperswitch-scancard/src/NativeHyperswitchScancard.ts b/packages/@juspay-tech/react-native-hyperswitch-scancard/src/NativeHyperswitchScancard.ts
new file mode 100644
index 00000000..a5ac4c19
--- /dev/null
+++ b/packages/@juspay-tech/react-native-hyperswitch-scancard/src/NativeHyperswitchScancard.ts
@@ -0,0 +1,20 @@
+import type {TurboModule} from 'react-native';
+import {TurboModuleRegistry} from 'react-native';
+
+export type ScanCardResponse = {
+ status?: string;
+ data?: {
+ pan?: string;
+ expiryMonth?: string;
+ expiryYear?: string;
+ };
+};
+
+export interface Spec extends TurboModule {
+ launchScanCard(
+ scanCardRequest: string,
+ callback: (response: ScanCardResponse) => void
+ ): void;
+}
+
+export default TurboModuleRegistry.get('HyperswitchScancard');
diff --git a/packages/@juspay-tech/react-native-hyperswitch-scancard/src/index.tsx b/packages/@juspay-tech/react-native-hyperswitch-scancard/src/index.tsx
index 11ab53c0..7b0d34d2 100644
--- a/packages/@juspay-tech/react-native-hyperswitch-scancard/src/index.tsx
+++ b/packages/@juspay-tech/react-native-hyperswitch-scancard/src/index.tsx
@@ -1,8 +1,10 @@
-import { NativeModules } from 'react-native';
+import NativeHyperswitchScancard from './NativeHyperswitchScancard';
+import type {ScanCardResponse} from './NativeHyperswitchScancard';
-const HyperswitchScancard = NativeModules.HyperswitchScancard || null;
-
-const isAvailable = HyperswitchScancard && HyperswitchScancard.launchScanCard;
+// TurboModuleRegistry.get resolves the TurboModule on the new architecture
+// and falls back to the legacy NativeModules entry on the old architecture,
+// so this single code path supports both.
+const isAvailable = NativeHyperswitchScancard != null;
export interface ScanCardReturnType {
status: string;
@@ -16,26 +18,23 @@ interface ScanCardData {
}
function launchScanCard(callback: (s: ScanCardReturnType) => void): void {
- if (isAvailable) {
- return HyperswitchScancard.launchScanCard(
- '',
- (response: Record) => {
- const status = response.status || 'Default';
- const data: ScanCardData | undefined = response.data;
- const scanData: ScanCardReturnType = {
- status,
- data: data
- ? {
- pan: data.pan || '',
- expiryMonth: data.expiryMonth || '',
- expiryYear: data.expiryYear || '',
- }
- : undefined,
- };
- callback(scanData);
- }
- );
+ if (NativeHyperswitchScancard) {
+ NativeHyperswitchScancard.launchScanCard('', (response: ScanCardResponse) => {
+ const status = response.status || 'Default';
+ const data = response.data;
+ const scanData: ScanCardReturnType = {
+ status,
+ data: data
+ ? {
+ pan: data.pan || '',
+ expiryMonth: data.expiryMonth || '',
+ expiryYear: data.expiryYear || '',
+ }
+ : undefined,
+ };
+ callback(scanData);
+ });
}
}
-export { isAvailable, launchScanCard };
+export {isAvailable, launchScanCard};
diff --git a/yarn.lock b/yarn.lock
index 5d9f816d..aed6c1ee 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4994,29 +4994,26 @@ __metadata:
version: 0.0.0-use.local
resolution: "@juspay-tech/react-native-hyperswitch-netcetera-3ds@workspace:packages/@juspay-tech/react-native-hyperswitch-netcetera-3ds"
dependencies:
- "@arkweid/lefthook": ^0.7.7
- "@babel/eslint-parser": ^7.18.2
"@commitlint/config-conventional": ^17.0.2
- "@react-native-community/eslint-config": ^3.0.2
+ "@react-native/babel-preset": 0.81.1
"@release-it/conventional-changelog": ^10.0.1
- "@types/jest": ^28.1.2
- "@types/react": ~17.0.21
- "@types/react-native": 0.68.0
+ "@types/jest": ^29.5.14
+ "@types/react": ^19.1.0
commitlint: ^17.0.2
eslint: ^8.4.1
eslint-config-prettier: ^8.5.0
eslint-plugin-prettier: ^4.0.0
- jest: ^28.1.1
+ jest: ^29.7.0
pod-install: ^0.1.0
prettier: ^2.0.5
- react: 17.0.2
- react-native: 0.68.2
- react-native-builder-bob: ^0.18.3
+ react: 19.1.0
+ react-native: 0.81.1
+ react-native-builder-bob: ^0.40.13
release-it: ^19.0.5
typescript: ^5.9.2
peerDependencies:
react: "*"
- react-native: "*"
+ react-native: ">=0.72.0"
languageName: unknown
linkType: soft
@@ -5164,7 +5161,7 @@ __metadata:
typescript: ^5.9.2
peerDependencies:
react: "*"
- react-native: "*"
+ react-native: ">=0.72.0"
react-native-webview: "*"
languageName: unknown
linkType: soft