Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
## Changelog

### v2026.1.1 Jan 31, 2026

* Upgrade Android SDK to 2.4.0
* Upgrade iOS SDK to 2.4.0

### v2025.2.1 Feb 19, 2025

* Address NPM dependency issue
Expand Down
10 changes: 10 additions & 0 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,16 @@ repositories {

def kotlin_version = getExtOrDefault("kotlinVersion")

// Align Kotlin stdlib with compiler to avoid "metadata version 2.2.0, expected 2.0.0" when
// other dependencies pull in a newer stdlib
configurations.all {
resolutionStrategy {
force "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
force "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
force "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
}
}

dependencies {
// For < 0.71, this will be from the local maven repo
// For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
Expand Down
2 changes: 1 addition & 1 deletion android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ MobilePaymentsSdkReactNative_kotlinVersion=2.0.21
MobilePaymentsSdkReactNative_minSdkVersion=28
MobilePaymentsSdkReactNative_targetSdkVersion=35
MobilePaymentsSdkReactNative_compileSdkVersion=35
MobilePaymentsSdkReactNative_ndkversion=26.1.10909125
MobilePaymentsSdkReactNative_ndkversion=28.0.12433566
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ fun ReadableMap.readPaymentParameters(): PaymentParameters {
val statementDescription = getString("statementDescription")
val teamMemberId = getString("teamMemberId")
val tipMoney = convertToMoney(getMap("tipMoney"))
val idempotencyKey = getString("idempotencyKey")
val paymentAttemptId = getString("paymentAttemptId")
?: java.util.UUID.randomUUID().toString()

val builder = PaymentParameters.Builder(amountMoney, processingMode, allowCardSurcharge)
val builder = PaymentParameters.Builder(amountMoney, processingMode, allowCardSurcharge, paymentAttemptId)
acceptPartialAuthorization?.let { builder.acceptPartialAuthorization(it) }
appFeeMoney?.let { builder.appFeeMoney(it) }
autocomplete?.let { builder.autocomplete(it) }
Expand All @@ -78,8 +78,6 @@ fun ReadableMap.readPaymentParameters(): PaymentParameters {
statementDescription?.let { builder.statementDescription(it) }
teamMemberId?.let { builder.teamMemberId(it) }
tipMoney?.let { builder.tipMoney(it) }
idempotencyKey?.let { builder.idempotencyKey(it) }
paymentAttemptId?.let { builder.paymentAttemptId(it) }

return builder.build()
}
Expand Down Expand Up @@ -330,7 +328,7 @@ fun ReaderInfo.toReaderInfoMap(): WritableMap {
return WritableNativeMap().apply {
putString("id", id)
putString("model", model.toModelString())
putString("state", state.toStateString())
putString("state", status.toStatusString())
putString("status", status.toStatusString())
putString("serialNumber", serialNumber)
putString("name", name)
Expand Down
3 changes: 2 additions & 1 deletion example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ The example app makes the following assumptions:
* Clone this repo (if you have not already):
`https://github.com/square/mobile-payments-sdk-react-native`
* Make sure you've set up your environment for developing in React Native, by visiting the [React Native - Environment Setup](https://reactnative.dev/docs/environment-setup) guide.
* **Android 16KB:** The example is configured for 16KB page size support (NDK r28, Build Tools 35). Install **NDK 28.0.12433566** (or newer r28) and **Build Tools 35.0.0** via Android Studio SDK Manager if needed.

## 2. Get application credentials
In your [Developer Dashboard](https://developer.squareup.com/apps), create an application or open an existing one you would like to use. If this is your first time creating an application with Square, you can review this [Get Started](https://developer.squareup.com/docs/square-get-started) guide for more information.
Expand All @@ -53,7 +54,7 @@ Click "Locations" in the left navigation and make note of the Default Test Accou
## 4. Run the app
1. Make sure you're in the root folder of the repository.
2. Run `yarn`, then `yarn example start`. This will start `Metro`, the JavaScript _bundler_ that ships _with_ React Native.
3. Once Metro has loaded, select the plaform of your choice: `a` for Android, `i` for iOS.
3. Once Metro has loaded, select the platform of your choice: `a` for Android, `i` for iOS.

You can also run the app for each individual platform by opening `ios/MobilePaymentsSdkReactNativeExample.xcworkspace` in Xcode for iOS; or `android/build.gradle` in Android Studio, for Android.

Expand Down
18 changes: 18 additions & 0 deletions example/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@ apply plugin: "com.android.application"
apply plugin: "org.jetbrains.kotlin.android"
apply plugin: "com.facebook.react"

// Align Kotlin stdlib with compiler (2.0.21) to avoid "metadata 2.2.0, expected 2.0.0" when
// dependencies pull in a newer stdlib
def kotlinVersion = rootProject.ext.has("kotlinVersion") ? rootProject.ext.get("kotlinVersion") : "2.0.21"
configurations.all {
resolutionStrategy {
force "org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}"
force "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${kotlinVersion}"
force "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlinVersion}"
}
}

/* Load custom properties for the app, if any */
Properties localProperties = new Properties()
if (project.file("app.properties").exists()) {
Expand Down Expand Up @@ -117,12 +128,19 @@ android {
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
}

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
implementation("com.squareup.sdk:mobile-payments-sdk:$squareSdkVersion")
implementation("com.squareup.sdk:mockreader-ui:$squareSdkVersion")
if (hermesEnabled.toBoolean()) {
implementation("com.facebook.react:hermes-android")
} else {
Expand Down
6 changes: 3 additions & 3 deletions example/android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
buildscript {
ext {
buildToolsVersion = "34.0.0"
buildToolsVersion = "35.0.0"
minSdkVersion = 28
compileSdkVersion = 35
targetSdkVersion = 35
ndkVersion = "26.1.10909125"
ndkVersion = "28.0.12433566"
kotlinVersion = "2.0.21"
squareSdkVersion = "2.3.4"
squareSdkVersion = "2.4.0"
}
repositories {
google()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#import <RCTAppDelegate.h>
#import <SquareMobilePaymentsSDK/SquareMobilePaymentsSDK-Swift.h>
#import <UIKit/UIKit.h>
#import <React/RCTBridgeModule.h>
#import "SquareSDKInitializer.h"

@interface AppDelegate : RCTAppDelegate

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ @implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSString *APP_ID = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"APP_ID"];
[SQMPMobilePaymentsSDK initializeWithApplicationLaunchOptions:launchOptions squareApplicationID: APP_ID];
MPRNInitializeSquareSDK(launchOptions, APP_ID);


self.moduleName = @"MobilePaymentsSdkReactNativeExample";
Expand Down
14 changes: 7 additions & 7 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ PODS:
- DoubleConversion
- glog
- hermes-engine
- MockReaderUI (~> 2.3.1)
- MockReaderUI (~> 2.4.0)
- RCT-Folly (= 2024.01.01.00)
- RCTRequired
- RCTTypeSafety
Expand All @@ -28,9 +28,9 @@ PODS:
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- SquareMobilePaymentsSDK (~> 2.3.1)
- SquareMobilePaymentsSDK (~> 2.4.0)
- Yoga
- MockReaderUI (2.3.1)
- MockReaderUI (2.4.0)
- Permission-BluetoothPeripheral (3.10.1):
- RNPermissions
- Permission-LocationAccuracy (3.10.1):
Expand Down Expand Up @@ -1581,7 +1581,7 @@ PODS:
- ReactCommon/turbomodule/core
- Yoga
- SocketRocket (0.7.0)
- SquareMobilePaymentsSDK (2.3.1)
- SquareMobilePaymentsSDK (2.4.0)
- Yoga (0.0.0)

DEPENDENCIES:
Expand Down Expand Up @@ -1823,8 +1823,8 @@ SPEC CHECKSUMS:
fmt: 4c2741a687cc09f0634a2e2c72a838b99f1ff120
glog: 69ef571f3de08433d766d614c73a9838a06bf7eb
hermes-engine: 8d2103d6c0176779aea4e25df6bb1410f9946680
mobile-payments-sdk-react-native: 14d13486a0252d5a56cd6b1bfbd2e2f10c26b11a
MockReaderUI: 9307e00522d5ff4aa6fb5c012205af1bbab7dc70
mobile-payments-sdk-react-native: 383bbd2a98346a3a66ed5b72581a97bba781ae75
MockReaderUI: e527a5bc446b95e8cd5ddb4c565fc7d614d38a0f
Permission-BluetoothPeripheral: 34ab829f159c6cf400c57bac05f5ba1b0af7a86e
Permission-LocationAccuracy: 30c5421911024b28d8916db5cbd728097da54434
Permission-LocationAlways: af165dee8a5a5888df6764f9f6ba98b112893709
Expand Down Expand Up @@ -1891,7 +1891,7 @@ SPEC CHECKSUMS:
RNScreens: 35bb8e81aeccf111baa0ea01a54231390dbbcfd9
RNVectorIcons: 182892e7d1a2f27b52d3c627eca5d2665a22ee28
SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d
SquareMobilePaymentsSDK: f53082b4972428724c629f41882e11e6152c7ec3
SquareMobilePaymentsSDK: 53cd315a537037377cd364edc874bf75782239eb
Yoga: 4ef80d96a5534f0e01b3055f17d1e19a9fc61b63

PODFILE CHECKSUM: 81d2f9e3393262e2bc7a99478a8e3a6741f0482e
Expand Down
129 changes: 12 additions & 117 deletions ios/Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,27 +66,6 @@ extension CardInputMethods {
}
}

extension ReaderState {
func toName() -> String {
return switch self {
case .connecting:
"CONNECTING"
case .disabled:
"DISABLED"
case .disconnected:
"DISCONNECTED"
case .failedToConnect:
"FAILED_TO_CONNECT"
case .ready:
"READY"
case .updatingFirmware:
"UPDATING_FIRMWARE"
default:
"UNKNOWN"
}
}
}

extension ReaderModel {
func toName() -> String {
return switch self {
Expand Down Expand Up @@ -116,96 +95,6 @@ extension ReaderFirmwareInfo {
}
}

extension ReaderConnectionFailureReason {
func toName() -> String {
return switch self {
case .deniedByServer:
"DENIED_BY_SERVER"
case .genericError:
"GENERIC_ERROR"
case .maxReadersConnected:
"MAX_READERS_CONNECTED"
case .networkTimeout:
"NETWORK_TIMEOUT"
case .networkTransportError:
"NETWORK_TRANSPORT_ERROR"
case .notConnectedToInternet:
"NOT_CONNECTED_TO_INTERNET"
case .readerTimeout:
"READER_TIMEOUT"
case .revokedByDevice:
"REVOKED_BY_DEVICE"
case .serverError:
"SERVER_ERROR"
case .tapToPayError:
"TAP_TO_PAY_ERROR"
case .unknown:
"UNKNOWN"
default : "UNKNOWN"
}
}
}


extension ReaderConnectionFailureRecoverySuggestion {
func toName() -> String {
return switch self {
case .activateAccount:
"ACTIVATE_ACCOUNT"
case .contactSupport:
"CONTACT_SUPPORT"
case .enablePasscodeToUseTapToPay:
"ENABLE_PASSCODE_TO_USE_TAP_TO_PAY"
case .noSuggestion:
"NO_SUGGESTION"
case .retry:
"RETRY"
case .reviewTapToPayGuidelines:
"REVIEW_TAP_TO_PAY_GUIDELINES"
default:
"UNKNOWN"
}
}
}


extension ReaderConnectionFailureInfo {
func toMap() -> NSDictionary {
return [
"failureReason" : failureReason.toName(),
"localizedDescription" : localizedDescription,
"localizedTitle" : localizedTitle,
"recoverySuggestion": recoverySuggestion.toName()
]
}
}

extension ReaderConnectionState {
func toName() -> String {
return switch self {
case .connected:
"CONNECTED"
case .connecting:
"CONNECTING"
case .failedToConnect:
"FAILED_TO_CONNECT"
case .notConnected:
"NOT_CONNECTED"
default:
"UNKNOWN"
}
}
}

extension ReaderConnectionInfo {
func toMap() -> NSDictionary {
return [
"failureInfo" : failureInfo?.toMap() ?? NSNull(),
"state" : state.toName()
]
}
}


extension CardInsertionStatus {
func toName() -> String {
Expand Down Expand Up @@ -245,6 +134,18 @@ extension ReaderBatteryStatus {
}
}

extension ReaderStatusInfo {
func toMap() -> NSDictionary {
return [
"status" : status.rawValue,
"statusDescription" : status.description,
"unavailableReasonInfo" : unavailableReasonInfo?.reason.rawValue ?? NSNull(),
"unavailableReasonInfoTitle" : unavailableReasonInfo?.title ?? NSNull(),
"unavailableReasonInfoDescription" : unavailableReasonInfo?.description ?? NSNull(),
]
}
}

extension ReaderChange {
func toName() -> String {
switch self {
Expand All @@ -258,16 +159,10 @@ extension ReaderChange {
return "CARD_INSERTED"
case .cardRemoved:
return "CARD_REMOVED"
case .connectionDidFail:
return "CONNECTION_DID_FAILED"
case .connectionStateDidChange:
return "CONNECTION_STATE_DID_CHANGED"
case .firmwareUpdateDidFail:
return "FIRMWARE_UPDATE_DID_FAILED"
case .firmwareUpdatePercentDidChange:
return "FIRMWARE_UPDATE_PERCENT_DID_CHANGED"
case .stateDidChange:
return "STATE_DID_CHANGED"
default: return "UNKNOWN"
}
}
Expand Down
11 changes: 1 addition & 10 deletions ios/Mappers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,6 @@ class Mappers {
processingMode: processingMode
)
}
else if let idempotencyKey = paymentParameters["idempotencyKey"] as? String {
paymentParams = PaymentParameters(
idempotencyKey: idempotencyKey,
amountMoney: amountMoney,
processingMode: processingMode
)
}

guard let paymentParams
else {
return .failure(.missingPaymentAttemptIdOrIdempotencyKey)
Expand Down Expand Up @@ -143,7 +135,6 @@ class Mappers {
return [
"batteryStatus" : reader.batteryStatus?.toMap() ?? NSNull(),
"cardInsertionStatus": reader.cardInsertionStatus.toName(),
"connectionInfo": reader.connectionInfo.toMap(),
"firmwareInfo" : reader.firmwareInfo?.toMap() ?? NSNull(),
"id": String(reader.id),
"isBlinkable" : reader.isBlinkable,
Expand All @@ -152,7 +143,7 @@ class Mappers {
"model": reader.model.toName(),
"name" : reader.name,
"serialNumber" : reader.serialNumber ?? NSNull(),
"state" : reader.state.toName(),
"statusInfo" : reader.statusInfo.toMap(),
"supportedCardEntryMethods" : reader.supportedInputMethods.toList()
]
}
Expand Down
Loading
Loading