From 3deabf3f06e638874325fe5e24734a7377f7cc0d Mon Sep 17 00:00:00 2001 From: Cesar Sosa <101717495+cesar-sosa-hol@users.noreply.github.com> Date: Mon, 20 Apr 2026 21:48:34 +0200 Subject: [PATCH 1/4] upgrade to 2.5.0 native sdk --- CLAUDE.md | 2 +- README.md | 6 ++--- android/build.gradle | 2 +- .../com/mobilepaymentssdkreactnative/Utils.kt | 26 ++++++++++++++----- docs/KOTLIN_COMPATIBILITY.md | 6 ++--- example/android/app/build.gradle | 3 ++- example/android/build.gradle | 2 +- .../project.pbxproj | 16 ------------ example/ios/Podfile.lock | 16 ++++++------ ios/Podfile | 2 +- ios/Podfile.lock | 8 +++--- mobile-payments-sdk-react-native.podspec | 4 +-- package.json | 2 +- src/models/objects.ts | 2 -- 14 files changed, 46 insertions(+), 51 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 0e9560d..77a2bd2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -43,7 +43,7 @@ The SDK follows a standard React Native bridge pattern with four feature manager ## Platform Constraints -- **iOS**: Min deployment target 16. Depends on `SquareMobilePaymentsSDK ~> 2.4.0` and `MockReaderUI ~> 2.4.0`. +- **iOS**: Min deployment target 16. Depends on `SquareMobilePaymentsSDK ~> 2.5.0` and `MockReaderUI ~> 2.5.0`. - **Android**: Min SDK 28, Compile/Target SDK 35. Kotlin 2.2.21. Proguard must be disabled (`minifyEnabled: false`). - **Kotlin 2.2.x**: React Native 0.75.x Gradle plugin doesn't natively support Kotlin 2.2.x — requires `patch-package` workaround (see `docs/KOTLIN_COMPATIBILITY.md`). - Not compatible with Expo Go (requires native code). diff --git a/README.md b/README.md index 354c9f1..52244a8 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@ Mobile Payments SDK for React Native supports the following SDK versions: - * [iOS](https://developer.squareup.com/docs/mobile-payments-sdk/ios#1-install-the-sdk-and-dependencies): 2.4.0 and above - * [Android](https://developer.squareup.com/docs/mobile-payments-sdk/android#1-install-the-sdk-and-dependencies): 2.4.0 and above + * [iOS](https://developer.squareup.com/docs/mobile-payments-sdk/ios#1-install-the-sdk-and-dependencies): 2.5.0 and above + * [Android](https://developer.squareup.com/docs/mobile-payments-sdk/android#1-install-the-sdk-and-dependencies): 2.5.0 and above ## Review requirements Before getting started, please review the Requirements and Limitations and Device Compatibility sections to ensure that the SDK can be used in your project: @@ -14,7 +14,7 @@ Before getting started, please review the Requirements and Limitations and Devic ## Android: Kotlin 2.2.x Compatibility -Mobile Payments SDK 2.4.0 requires Kotlin 2.2.21, which is not yet supported by React Native's Gradle plugin (0.75.x and earlier). Android builds will fail unless you apply a small patch to your project. See the [Kotlin Compatibility Workaround](docs/KOTLIN_COMPATIBILITY.md) for step-by-step instructions. +Mobile Payments SDK 2.5.0 requires Kotlin 2.2.21, which is not yet supported by React Native's Gradle plugin (0.75.x and earlier). Android builds will fail unless you apply a small patch to your project. See the [Kotlin Compatibility Workaround](docs/KOTLIN_COMPATIBILITY.md) for step-by-step instructions. ## Installation ```sh diff --git a/android/build.gradle b/android/build.gradle index ce48653..72b6f7e 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -88,7 +88,7 @@ repositories { } def kotlin_version = getExtOrDefault("kotlinVersion") -def squareSdkVersion = "2.4.0" +def squareSdkVersion = "2.5.0" dependencies { // For < 0.71, this will be from the local maven repo diff --git a/android/src/main/java/com/mobilepaymentssdkreactnative/Utils.kt b/android/src/main/java/com/mobilepaymentssdkreactnative/Utils.kt index 5941367..3fb560d 100644 --- a/android/src/main/java/com/mobilepaymentssdkreactnative/Utils.kt +++ b/android/src/main/java/com/mobilepaymentssdkreactnative/Utils.kt @@ -292,15 +292,10 @@ private fun Card.Brand.toBrandString(): String = Card.Brand.JCB -> "JCB" Card.Brand.CHINA_UNIONPAY -> "CHINA_UNIONPAY" Card.Brand.SQUARE_GIFT_CARD -> "SQUARE_GIFT_CARD" - Card.Brand.ALIPAY -> "ALIPAY" - Card.Brand.CASH_APP -> "CASH_APP" Card.Brand.EFTPOS -> "EFTPOS" Card.Brand.FELICA -> "FELICA" Card.Brand.INTERAC -> "INTERAC" Card.Brand.SQUARE_CAPITAL_CARD -> "SQUARE_CAPITAL_CARD" - Card.Brand.SUICA -> "SUICA" - Card.Brand.ID -> "ID" - Card.Brand.QUICPAY -> "QUICPAY" } private fun Card.CoBrand.toCoBrandString(): String = @@ -356,8 +351,10 @@ fun ReaderInfo.toReaderInfoMap(): WritableMap { putString("serialNumber", serialNumber) putString("name", name) putMap("batteryStatus", batteryStatus?.toBatteryStatusMap()) - putString("firmwareVersion", firmwareVersion) - putInt("firmwarePercent", firmwarePercent ?: 0) + putMap( + "firmwareInfo", + firmwareInfo.toFirmwareInfoMap() + ) putArray("supportedCardEntryMethods", WritableNativeArray().apply { supportedCardEntryMethods.forEach { pushString(it.toEntryMethodString()) @@ -368,6 +365,21 @@ fun ReaderInfo.toReaderInfoMap(): WritableMap { } } +fun ReaderInfo.ReaderFirmwareInfo.toFirmwareInfoMap(): WritableMap { + return WritableNativeMap().apply { + putString("version", version) + putInt("updatePercentage", updateStatus.toPercent() ?: 0) + } +} + +fun ReaderInfo.FirmwareUpdateStatus.toPercent() : Int? { + return when(this) { + is ReaderInfo.FirmwareUpdateStatus.None -> null + is ReaderInfo.FirmwareUpdateStatus.InProgress -> this.updatePercentage + is ReaderInfo.FirmwareUpdateStatus.Pending -> null + } +} + fun CardEntryMethod.toEntryMethodString(): String { return when(this) { CardEntryMethod.EMV -> "EMV" diff --git a/docs/KOTLIN_COMPATIBILITY.md b/docs/KOTLIN_COMPATIBILITY.md index 3e6a877..f42cea3 100644 --- a/docs/KOTLIN_COMPATIBILITY.md +++ b/docs/KOTLIN_COMPATIBILITY.md @@ -1,8 +1,8 @@ # Kotlin 2.2.x Compatibility Workaround for React Native -Mobile Payments SDK 2.4.0 requires **Kotlin 2.2.21**, which introduces a breaking change with React Native's Gradle plugin (versions 0.75.x and earlier). The `KotlinTopLevelExtension` class was removed in Kotlin 2.2.x, causing the Android build to fail during Gradle configuration. +Mobile Payments SDK 2.5.0 requires **Kotlin 2.2.21**, which introduces a breaking change with React Native's Gradle plugin (versions 0.75.x and earlier). The `KotlinTopLevelExtension` class was removed in Kotlin 2.2.x, causing the Android build to fail during Gradle configuration. -This guide explains how to apply a patch to your project so you can use Mobile Payments SDK 2.4.0 with React Native until React Native itself adds support for Kotlin 2.2.x. +This guide explains how to apply a patch to your project so you can use Mobile Payments SDK 2.5.0 with React Native until React Native itself adds support for Kotlin 2.2.x. > **Note:** This workaround is temporary. Once React Native releases a version with Kotlin 2.2.x support, you can remove the patch and `patch-package` dependency. @@ -111,7 +111,7 @@ Applying patches... ### 5. Build your project -Your Android build should now succeed with Kotlin 2.2.21 and Mobile Payments SDK 2.4.0. +Your Android build should now succeed with Kotlin 2.2.21 and Mobile Payments SDK 2.5.0. ## Removing the Workaround diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 64d1aa5..d8c87a3 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -120,6 +120,7 @@ android { packaging { resources { excludes += "/META-INF/{AL2.0,LGPL2.1}" + pickFirsts += "META-INF/versions/9/OSGI-INF/MANIFEST.MF" } } } @@ -127,7 +128,7 @@ android { dependencies { // The version of react-native is set by the React Native Gradle Plugin implementation("com.facebook.react:react-android") - // Mobile Payments SDK 2.4.0 + // Mobile Payments SDK 2.5.0 implementation("com.squareup.sdk:mobile-payments-sdk:$squareSdkVersion") implementation("com.squareup.sdk:mockreader-ui:$squareSdkVersion") if (hermesEnabled.toBoolean()) { diff --git a/example/android/build.gradle b/example/android/build.gradle index dda9f60..5bad0b1 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -6,7 +6,7 @@ buildscript { targetSdkVersion = 35 ndkVersion = "26.1.10909125" kotlinVersion = "2.2.21" - squareSdkVersion = "2.4.0" + squareSdkVersion = "2.5.0" } repositories { google() diff --git a/example/ios/MobilePaymentsSdkReactNativeExample.xcodeproj/project.pbxproj b/example/ios/MobilePaymentsSdkReactNativeExample.xcodeproj/project.pbxproj index 87772f4..f424111 100644 --- a/example/ios/MobilePaymentsSdkReactNativeExample.xcodeproj/project.pbxproj +++ b/example/ios/MobilePaymentsSdkReactNativeExample.xcodeproj/project.pbxproj @@ -338,14 +338,10 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-MobilePaymentsSdkReactNativeExample-MobilePaymentsSdkReactNativeExampleTests/Pods-MobilePaymentsSdkReactNativeExample-MobilePaymentsSdkReactNativeExampleTests-resources-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - ); name = "[CP] Copy Pods Resources"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-MobilePaymentsSdkReactNativeExample-MobilePaymentsSdkReactNativeExampleTests/Pods-MobilePaymentsSdkReactNativeExample-MobilePaymentsSdkReactNativeExampleTests-resources-${CONFIGURATION}-output-files.xcfilelist", ); - outputPaths = ( - ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-MobilePaymentsSdkReactNativeExample-MobilePaymentsSdkReactNativeExampleTests/Pods-MobilePaymentsSdkReactNativeExample-MobilePaymentsSdkReactNativeExampleTests-resources.sh\"\n"; @@ -359,14 +355,10 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-MobilePaymentsSdkReactNativeExample/Pods-MobilePaymentsSdkReactNativeExample-resources-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - ); name = "[CP] Copy Pods Resources"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-MobilePaymentsSdkReactNativeExample/Pods-MobilePaymentsSdkReactNativeExample-resources-${CONFIGURATION}-output-files.xcfilelist", ); - outputPaths = ( - ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-MobilePaymentsSdkReactNativeExample/Pods-MobilePaymentsSdkReactNativeExample-resources.sh\"\n"; @@ -419,14 +411,10 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-MobilePaymentsSdkReactNativeExample-MobilePaymentsSdkReactNativeExampleTests/Pods-MobilePaymentsSdkReactNativeExample-MobilePaymentsSdkReactNativeExampleTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-MobilePaymentsSdkReactNativeExample-MobilePaymentsSdkReactNativeExampleTests/Pods-MobilePaymentsSdkReactNativeExample-MobilePaymentsSdkReactNativeExampleTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); - outputPaths = ( - ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-MobilePaymentsSdkReactNativeExample-MobilePaymentsSdkReactNativeExampleTests/Pods-MobilePaymentsSdkReactNativeExample-MobilePaymentsSdkReactNativeExampleTests-frameworks.sh\"\n"; @@ -440,14 +428,10 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-MobilePaymentsSdkReactNativeExample/Pods-MobilePaymentsSdkReactNativeExample-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-MobilePaymentsSdkReactNativeExample/Pods-MobilePaymentsSdkReactNativeExample-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); - outputPaths = ( - ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-MobilePaymentsSdkReactNativeExample/Pods-MobilePaymentsSdkReactNativeExample-frameworks.sh\"\n"; diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index a2c7c20..b0abc12 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -7,11 +7,11 @@ PODS: - hermes-engine (0.75.3): - hermes-engine/Pre-built (= 0.75.3) - hermes-engine/Pre-built (0.75.3) - - mobile-payments-sdk-react-native (2026.2.1): + - mobile-payments-sdk-react-native (2026.3.4): - DoubleConversion - glog - hermes-engine - - MockReaderUI (~> 2.4.0) + - MockReaderUI (~> 2.5.0) - RCT-Folly (= 2024.01.01.00) - RCTRequired - RCTTypeSafety @@ -28,9 +28,9 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - SquareMobilePaymentsSDK (~> 2.4.0) + - SquareMobilePaymentsSDK (~> 2.5.0) - Yoga - - MockReaderUI (2.4.0) + - MockReaderUI (2.5.0) - Permission-BluetoothPeripheral (3.10.1): - RNPermissions - Permission-LocationAccuracy (3.10.1): @@ -1581,7 +1581,7 @@ PODS: - ReactCommon/turbomodule/core - Yoga - SocketRocket (0.7.0) - - SquareMobilePaymentsSDK (2.4.0) + - SquareMobilePaymentsSDK (2.5.0) - Yoga (0.0.0) DEPENDENCIES: @@ -1823,8 +1823,8 @@ SPEC CHECKSUMS: fmt: 4c2741a687cc09f0634a2e2c72a838b99f1ff120 glog: 69ef571f3de08433d766d614c73a9838a06bf7eb hermes-engine: 8d2103d6c0176779aea4e25df6bb1410f9946680 - mobile-payments-sdk-react-native: 161fbdf5a7a5cd788224a78d361c08c5d2a3fb8c - MockReaderUI: e527a5bc446b95e8cd5ddb4c565fc7d614d38a0f + mobile-payments-sdk-react-native: b32d25a22d460063b2c705d86740998613d10e3e + MockReaderUI: 651252bf60bffc2699866448a6fb7250c06be785 Permission-BluetoothPeripheral: 34ab829f159c6cf400c57bac05f5ba1b0af7a86e Permission-LocationAccuracy: 30c5421911024b28d8916db5cbd728097da54434 Permission-LocationAlways: af165dee8a5a5888df6764f9f6ba98b112893709 @@ -1891,7 +1891,7 @@ SPEC CHECKSUMS: RNScreens: 35bb8e81aeccf111baa0ea01a54231390dbbcfd9 RNVectorIcons: 182892e7d1a2f27b52d3c627eca5d2665a22ee28 SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d - SquareMobilePaymentsSDK: 53cd315a537037377cd364edc874bf75782239eb + SquareMobilePaymentsSDK: 61d783cb2ef4b238731f4433a42028d95c77893c Yoga: 4ef80d96a5534f0e01b3055f17d1e19a9fc61b63 PODFILE CHECKSUM: 81d2f9e3393262e2bc7a99478a8e3a6741f0482e diff --git a/ios/Podfile b/ios/Podfile index de7ee10..3c7c3ba 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -7,7 +7,7 @@ target 'RNMobilePaymentSDK' do use_frameworks! # Pods for RNMobilePaymentSDK - pod "SquareMobilePaymentsSDK", "~> 2.4.0" + pod "SquareMobilePaymentsSDK", "~> 2.5.0" target 'RNMobilePaymentSDKTests' do inherit! :search_paths # Pods for testing diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 4da1b9c..f9bce9d 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,16 +1,16 @@ PODS: - - SquareMobilePaymentsSDK (2.4.0) + - SquareMobilePaymentsSDK (2.5.0) DEPENDENCIES: - - SquareMobilePaymentsSDK (~> 2.4.0) + - SquareMobilePaymentsSDK (~> 2.5.0) SPEC REPOS: trunk: - SquareMobilePaymentsSDK SPEC CHECKSUMS: - SquareMobilePaymentsSDK: 53cd315a537037377cd364edc874bf75782239eb + SquareMobilePaymentsSDK: 61d783cb2ef4b238731f4433a42028d95c77893c -PODFILE CHECKSUM: 90edd7b3e424a600173ffd8b1fcb677878cc582e +PODFILE CHECKSUM: b2206f603fba9bc930b94625386c4dfad56fed65 COCOAPODS: 1.16.2 diff --git a/mobile-payments-sdk-react-native.podspec b/mobile-payments-sdk-react-native.podspec index d2a1077..3e46413 100644 --- a/mobile-payments-sdk-react-native.podspec +++ b/mobile-payments-sdk-react-native.podspec @@ -14,8 +14,8 @@ Pod::Spec.new do |s| s.platforms = { :ios => "16" } s.source = { :git => "https://github.com/square//mobile-payments-sdk-react-native.git", :tag => "#{s.version}" } - s.dependency "MockReaderUI", "~> 2.4.0" - s.dependency "SquareMobilePaymentsSDK", "~> 2.4.0" + s.dependency "MockReaderUI", "~> 2.5.0" + s.dependency "SquareMobilePaymentsSDK", "~> 2.5.0" s.source_files = "ios/**/*.{h,m,mm,swift}" diff --git a/package.json b/package.json index e7e7d76..8962f6f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mobile-payments-sdk-react-native", - "version": "2026.3.4", + "version": "2026.4.1", "description": "Mobile Payments SDK plug-in for React Native. Enables developers to build secure in-person payment solutions.", "source": "./src/index.tsx", "main": "./lib/commonjs/index.js", diff --git a/src/models/objects.ts b/src/models/objects.ts index 2226761..9c5939c 100644 --- a/src/models/objects.ts +++ b/src/models/objects.ts @@ -182,8 +182,6 @@ export type ReaderInfo = { serialNumber?: String; name: String; batteryStatus?: ReaderBatteryStatus; - firmwareVersion?: String; - firmwarePercent?: Number; supportedCardEntryMethods: CardEntryMethod[]; isForgettable: Boolean; isBlinkable: Boolean; From 4307a457341b33ad5e6ac5a4b9814ef2401dafe5 Mon Sep 17 00:00:00 2001 From: Cesar Sosa <101717495+cesar-sosa-hol@users.noreply.github.com> Date: Tue, 21 Apr 2026 22:02:05 +0200 Subject: [PATCH 2/4] add readersettings and preferredFirmwareUpdateTime --- .../MobilePaymentsSdkReactNativeModule.kt | 22 +++++++++++++++++++ .../com/mobilepaymentssdkreactnative/Utils.kt | 18 +++++++++++++++ ios/Extensions.swift | 18 +++++++++++++++ ios/MobilePaymentsSdkReactNative.mm | 9 ++++++++ ios/MobilePaymentsSdkReactNative.swift | 20 +++++++++++++++++ src/managers/reader.ts | 10 ++++++++- src/managers/settings.ts | 8 +++++++ src/models/objects.ts | 10 +++++++++ 8 files changed, 114 insertions(+), 1 deletion(-) diff --git a/android/src/main/java/com/mobilepaymentssdkreactnative/MobilePaymentsSdkReactNativeModule.kt b/android/src/main/java/com/mobilepaymentssdkreactnative/MobilePaymentsSdkReactNativeModule.kt index 50fc1fa..4a164cb 100644 --- a/android/src/main/java/com/mobilepaymentssdkreactnative/MobilePaymentsSdkReactNativeModule.kt +++ b/android/src/main/java/com/mobilepaymentssdkreactnative/MobilePaymentsSdkReactNativeModule.kt @@ -127,6 +127,22 @@ class MobilePaymentsSdkReactNativeModule(private val reactContext: ReactApplicat promise.resolve(settingsManager.getSdkSettings().sdkVersion) } + @ReactMethod + fun isShowingSettings(promise: Promise) { + reactContext.runOnUiQueueThread { + val settingsManager = MobilePaymentsSdk.settingsManager() + promise.resolve(settingsManager.isShowingSettings()) + } + } + + @ReactMethod + fun closeSettings(promise: Promise) { + reactContext.runOnUiQueueThread { + val settingsManager = MobilePaymentsSdk.settingsManager() + promise.resolve(settingsManager.closeSettings()) + } + } + @ReactMethod fun showMockReaderUI(promise: Promise) { if (!MobilePaymentsSdk.isSandboxEnvironment()) { @@ -360,6 +376,12 @@ class MobilePaymentsSdkReactNativeModule(private val reactContext: ReactApplicat } // --- + @ReactMethod + private fun readerSettings(promise: Promise) { + val readerManager = MobilePaymentsSdk.readerManager() + promise.resolve(readerManager.readerSettings.toReaderSettingsMap()) + } + private fun emitEvent(reactContext: ReactContext, eventName: String, map: WritableMap) { reactContext .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java) diff --git a/android/src/main/java/com/mobilepaymentssdkreactnative/Utils.kt b/android/src/main/java/com/mobilepaymentssdkreactnative/Utils.kt index 3fb560d..5dc5cb2 100644 --- a/android/src/main/java/com/mobilepaymentssdkreactnative/Utils.kt +++ b/android/src/main/java/com/mobilepaymentssdkreactnative/Utils.kt @@ -10,6 +10,8 @@ import com.squareup.sdk.mobilepayments.authorization.AuthorizedLocation import com.squareup.sdk.mobilepayments.cardreader.CardEntryMethod import com.squareup.sdk.mobilepayments.cardreader.ReaderChangedEvent import com.squareup.sdk.mobilepayments.cardreader.ReaderInfo +import com.squareup.sdk.mobilepayments.cardreader.ReaderSettings +import com.squareup.sdk.mobilepayments.core.TimeOfDay import com.squareup.sdk.mobilepayments.core.Result.Failure import com.squareup.sdk.mobilepayments.payment.AdditionalPaymentMethod import com.squareup.sdk.mobilepayments.payment.AdditionalPaymentMethod.Type @@ -465,3 +467,19 @@ fun ReaderChangedEvent.Change.toChangeString(): String { ReaderChangedEvent.Change.REMOVED -> "REMOVED" } } + +fun ReaderSettings.toReaderSettingsMap(): WritableMap { + return WritableNativeMap().apply { + putBoolean("isReducedChargingModeEnabled", isReducedChargingModeEnabled) + putMap("preferredFirmwareUpdateTime", preferredFirmwareUpdateTime + ?.toTimeOfDayMap() + ) + } +} + +fun TimeOfDay.toTimeOfDayMap(): WritableMap { + return WritableNativeMap().apply { + putInt("hour", hour) + putInt("minute", minute) + } +} diff --git a/ios/Extensions.swift b/ios/Extensions.swift index 5606e60..4cf30da 100644 --- a/ios/Extensions.swift +++ b/ios/Extensions.swift @@ -167,3 +167,21 @@ extension ReaderChange { } } } + +extension ReaderSettings { + func toMap() -> NSDictionary { + return [ + "isReducedChargingModeEnabled" : reducedChargingModeEnabled, + "preferredFirmwareUpdateTime" : preferredFirmwareUpdateTime?.toMap() ?? NSNull() + ] + } +} + +extension TimeOfDay { + func toMap() -> NSDictionary { + return [ + "hour" : hour, + "minute" : minute + ] + } +} diff --git a/ios/MobilePaymentsSdkReactNative.mm b/ios/MobilePaymentsSdkReactNative.mm index ad6e68e..60402f7 100644 --- a/ios/MobilePaymentsSdkReactNative.mm +++ b/ios/MobilePaymentsSdkReactNative.mm @@ -24,6 +24,12 @@ @interface RCT_EXTERN_MODULE(MobilePaymentsSdkReactNative, NSObject) RCT_EXTERN_METHOD(showSettings:(RCTPromiseResolveBlock)resolve withRejecter:(RCTPromiseRejectBlock)reject) +RCT_EXTERN_METHOD(isShowingSettings:(RCTPromiseResolveBlock)resolve + withRejecter:(RCTPromiseRejectBlock)reject) + +RCT_EXTERN_METHOD(closeSettings:(RCTPromiseResolveBlock)resolve + withRejecter:(RCTPromiseRejectBlock)reject) + RCT_EXTERN_METHOD(showMockReaderUI:(RCTPromiseResolveBlock)resolve withRejecter:(RCTPromiseRejectBlock)reject) @@ -103,6 +109,9 @@ @interface RCT_EXTERN_MODULE(MobilePaymentsSdkReactNative, NSObject) RCT_EXTERN_METHOD(stopPairing:(RCTPromiseResolveBlock)resolve withRejecter:(RCTPromiseRejectBlock)reject) +RCT_EXTERN_METHOD(readerSettings:(RCTPromiseResolveBlock)resolve + withRejecter:(RCTPromiseRejectBlock)reject) + + (BOOL)requiresMainQueueSetup { return YES; diff --git a/ios/MobilePaymentsSdkReactNative.swift b/ios/MobilePaymentsSdkReactNative.swift index 440d16e..6a714b8 100644 --- a/ios/MobilePaymentsSdkReactNative.swift +++ b/ios/MobilePaymentsSdkReactNative.swift @@ -114,6 +114,20 @@ class MobilePaymentsSdkReactNative: RCTEventEmitter { } } + @objc(isShowingSettings:withRejecter:) + func isShowingSettings(resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + let settingsManager = mobilePaymentsSDK.settingsManager + resolve(settingsManager.isSettingsPresented) + } + + @objc(closeSettings:withRejecter:) + func closeSettings(resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + DispatchQueue.main.async { + let settingsManager = self.mobilePaymentsSDK.settingsManager + resolve(settingsManager.dismissSettings()) + } + } + @objc(getEnvironment:withRejecter:) func getEnvironment(resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) { switch(mobilePaymentsSDK.settingsManager.sdkSettings.environment) { @@ -496,6 +510,12 @@ class MobilePaymentsSdkReactNative: RCTEventEmitter { resolve(NSNull()) } // --- + + @objc(readerSettings:withRejecter:) + func readerSettings(resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + let settings = mobilePaymentsSDK.readerManager.readerSettings + resolve(settings.toMap()) + } } class MobilePaymentsReaderObserver: ReaderObserver { diff --git a/src/managers/reader.ts b/src/managers/reader.ts index d8a79b3..7dc2ab5 100644 --- a/src/managers/reader.ts +++ b/src/managers/reader.ts @@ -4,7 +4,11 @@ import { type EmitterSubscription, } from 'react-native'; import MobilePaymentsSdkReactNative from '../base_sdk'; -import type { ReaderChangedEvent, ReaderInfo } from '../models/objects'; +import type { + ReaderChangedEvent, + ReaderInfo, + ReaderSettings, +} from '../models/objects'; export const readerEventEmitter = new NativeEventEmitter( MobilePaymentsSdkReactNative @@ -31,6 +35,10 @@ export const isPairingInProgress = (): Promise => { return MobilePaymentsSdkReactNative.isPairingInProgress(); }; +export const readerSettings = (): Promise => { + return MobilePaymentsSdkReactNative.readerSettings(); +}; + const addReaderChangedCallback = (refId: String): Promise => { return MobilePaymentsSdkReactNative.addReaderChangedCallback(refId); }; diff --git a/src/managers/settings.ts b/src/managers/settings.ts index cd039e3..0f1c9d9 100644 --- a/src/managers/settings.ts +++ b/src/managers/settings.ts @@ -13,6 +13,14 @@ export const getSdkVersion = (): Promise => { return MobilePaymentsSdkReactNative.getSdkVersion(); }; +export const isShowingSettings = (): Promise => { + return MobilePaymentsSdkReactNative.isShowingSettings(); +}; + +export const closeSettings = (): Promise => { + return MobilePaymentsSdkReactNative.closeSettings(); +}; + export namespace PaymentSettings { export const isOfflineProcessingAllowed = (): Promise => { return MobilePaymentsSdkReactNative.isOfflineProcessingAllowed(); diff --git a/src/models/objects.ts b/src/models/objects.ts index 9c5939c..c78b4ae 100644 --- a/src/models/objects.ts +++ b/src/models/objects.ts @@ -195,3 +195,13 @@ export type ReaderChangedEvent = { reader: ReaderInfo; readerSerialNumber?: String; }; + +export type TimeOfDay = { + hour: Number; + minute: Number; +}; + +export type ReaderSettings = { + isReducedChargingModeEnabled: boolean; + preferredFirmwareUpdateTime?: TimeOfDay | null; +}; From 1a1f74af56c6f77cabfc3b075377670041171c51 Mon Sep 17 00:00:00 2001 From: Cesar Sosa <101717495+cesar-sosa-hol@users.noreply.github.com> Date: Tue, 21 Apr 2026 22:06:38 +0200 Subject: [PATCH 3/4] updated --- CHANGELOG.md | 4 ++++ .../src/main/java/com/mobilepaymentssdkreactnative/Utils.kt | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 26ccb36..221f5ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## Changelog +### v2026.4.1 Apr 1, 2026 + +* Upgrade Android and iOS SDK to 2.5.0 + ### v2026.3.4 Mar 25, 2026 * Fix `AdditionalPaymentMethods` mapping to support combining multiple methods (e.g. `TAP_TO_PAY` + `KEYED`) on Android. diff --git a/android/src/main/java/com/mobilepaymentssdkreactnative/Utils.kt b/android/src/main/java/com/mobilepaymentssdkreactnative/Utils.kt index 5dc5cb2..ece56f8 100644 --- a/android/src/main/java/com/mobilepaymentssdkreactnative/Utils.kt +++ b/android/src/main/java/com/mobilepaymentssdkreactnative/Utils.kt @@ -374,7 +374,7 @@ fun ReaderInfo.ReaderFirmwareInfo.toFirmwareInfoMap(): WritableMap { } } -fun ReaderInfo.FirmwareUpdateStatus.toPercent() : Int? { +fun ReaderInfo.FirmwareUpdateStatus.toPercent() : Int? { return when(this) { is ReaderInfo.FirmwareUpdateStatus.None -> null is ReaderInfo.FirmwareUpdateStatus.InProgress -> this.updatePercentage From 1fd144f1f48f3e45ad9c569d0d16662172d0004e Mon Sep 17 00:00:00 2001 From: Cesar Sosa <101717495+cesar-sosa-hol@users.noreply.github.com> Date: Thu, 23 Apr 2026 15:41:34 +0200 Subject: [PATCH 4/4] Artem's comments --- CHANGELOG.md | 11 ++++++++--- .../MobilePaymentsSdkReactNativeModule.kt | 6 +++--- .../java/com/mobilepaymentssdkreactnative/Utils.kt | 1 + example/Gemfile.lock | 5 ++++- example/ios/Podfile.lock | 4 ++-- 5 files changed, 18 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 221f5ec..4191833 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,13 @@ ## Changelog -### v2026.4.1 Apr 1, 2026 - -* Upgrade Android and iOS SDK to 2.5.0 +### v2026.4.1 Apr 22, 2026 + +* Upgrade Android and iOS native SDK to `2.5.0` +* Add `SettingsManager.isShowingSettings()` to check whether the Settings screen is currently presented +* Add `SettingsManager.closeSettings()` to programmatically dismiss the Settings screen +* Add `ReaderManager.readerSettings()` which returns a new `ReaderSettings` object (`isReducedChargingModeEnabled`, `preferredFirmwareUpdateTime`). Adds a new `TimeOfDay` type (`hour`, `minute`) used by `preferredFirmwareUpdateTime` +* **Breaking:** `ReaderInfo.firmwareVersion` and `ReaderInfo.firmwarePercent` have been replaced by a single `ReaderInfo.firmwareInfo` object of shape `{ version, updatePercentage }`, mirroring the 2.5.0 native API +* **Breaking (Android):** Removed `ALIPAY`, `CASH_APP`, `SUICA`, `ID`, and `QUICPAY` from the mapped `Card.Brand` values — these were removed in native SDK `2.5.0` ### v2026.3.4 Mar 25, 2026 diff --git a/android/src/main/java/com/mobilepaymentssdkreactnative/MobilePaymentsSdkReactNativeModule.kt b/android/src/main/java/com/mobilepaymentssdkreactnative/MobilePaymentsSdkReactNativeModule.kt index 4a164cb..9bf0420 100644 --- a/android/src/main/java/com/mobilepaymentssdkreactnative/MobilePaymentsSdkReactNativeModule.kt +++ b/android/src/main/java/com/mobilepaymentssdkreactnative/MobilePaymentsSdkReactNativeModule.kt @@ -346,7 +346,7 @@ class MobilePaymentsSdkReactNativeModule(private val reactContext: ReactApplicat // pairReader @ReactMethod - private fun pairReader(promise: Promise) { + fun pairReader(promise: Promise) { if(pairingHandler != null) { promise.reject("PAIRING_IN_PROGRESS", "A pairing is already in progress") } @@ -367,7 +367,7 @@ class MobilePaymentsSdkReactNativeModule(private val reactContext: ReactApplicat } @ReactMethod - private fun stopPairing(promise: Promise) { + fun stopPairing(promise: Promise) { if(pairingHandler != null) { pairingHandler?.stop() pairingHandler = null; @@ -377,7 +377,7 @@ class MobilePaymentsSdkReactNativeModule(private val reactContext: ReactApplicat // --- @ReactMethod - private fun readerSettings(promise: Promise) { + fun readerSettings(promise: Promise) { val readerManager = MobilePaymentsSdk.readerManager() promise.resolve(readerManager.readerSettings.toReaderSettingsMap()) } diff --git a/android/src/main/java/com/mobilepaymentssdkreactnative/Utils.kt b/android/src/main/java/com/mobilepaymentssdkreactnative/Utils.kt index ece56f8..add657f 100644 --- a/android/src/main/java/com/mobilepaymentssdkreactnative/Utils.kt +++ b/android/src/main/java/com/mobilepaymentssdkreactnative/Utils.kt @@ -371,6 +371,7 @@ fun ReaderInfo.ReaderFirmwareInfo.toFirmwareInfoMap(): WritableMap { return WritableNativeMap().apply { putString("version", version) putInt("updatePercentage", updateStatus.toPercent() ?: 0) + putString("failureReason", null) } } diff --git a/example/Gemfile.lock b/example/Gemfile.lock index 0ee184f..626e252 100644 --- a/example/Gemfile.lock +++ b/example/Gemfile.lock @@ -80,12 +80,15 @@ GEM concurrent-ruby (~> 1.0) json (2.8.2) logger (1.6.1) - minitest (5.25.1) + minitest (6.0.5) + drb (~> 2.0) + prism (~> 1.5) molinillo (0.8.0) nanaimo (0.4.0) nap (1.1.0) netrc (0.11.0) nkf (0.2.0) + prism (1.9.0) public_suffix (4.0.7) rexml (3.3.9) ruby-macho (2.5.1) diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index b0abc12..51393ab 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -7,7 +7,7 @@ PODS: - hermes-engine (0.75.3): - hermes-engine/Pre-built (= 0.75.3) - hermes-engine/Pre-built (0.75.3) - - mobile-payments-sdk-react-native (2026.3.4): + - mobile-payments-sdk-react-native (2026.4.1): - DoubleConversion - glog - hermes-engine @@ -1823,7 +1823,7 @@ SPEC CHECKSUMS: fmt: 4c2741a687cc09f0634a2e2c72a838b99f1ff120 glog: 69ef571f3de08433d766d614c73a9838a06bf7eb hermes-engine: 8d2103d6c0176779aea4e25df6bb1410f9946680 - mobile-payments-sdk-react-native: b32d25a22d460063b2c705d86740998613d10e3e + mobile-payments-sdk-react-native: 648e9e228798472f028ed9fd02ae172581ac1692 MockReaderUI: 651252bf60bffc2699866448a6fb7250c06be785 Permission-BluetoothPeripheral: 34ab829f159c6cf400c57bac05f5ba1b0af7a86e Permission-LocationAccuracy: 30c5421911024b28d8916db5cbd728097da54434