@connexup/react-native-square-mobile-payment-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/LICENSE +20 -0
  2. package/NativeSquareMobilePaymentSDK.podspec +23 -0
  3. package/README.md +66 -0
  4. package/android/build.gradle +81 -0
  5. package/android/gradle.properties +5 -0
  6. package/android/src/main/AndroidManifest.xml +2 -0
  7. package/android/src/main/java/com/connexup/square/mobilepayment/DateFormatUtils.java +29 -0
  8. package/android/src/main/java/com/connexup/square/mobilepayment/ErrorUtilities.kt +56 -0
  9. package/android/src/main/java/com/connexup/square/mobilepayment/MobilePaymentAuthorization.kt +185 -0
  10. package/android/src/main/java/com/connexup/square/mobilepayment/MobilePaymentException.kt +8 -0
  11. package/android/src/main/java/com/connexup/square/mobilepayment/MobilePaymentPayment.kt +542 -0
  12. package/android/src/main/java/com/connexup/square/mobilepayment/MobilePaymentReader.kt +344 -0
  13. package/android/src/main/java/com/connexup/square/mobilepayment/MobilePaymentSDK.kt +47 -0
  14. package/android/src/main/java/com/connexup/square/mobilepayment/MobilePaymentSDKPackage.kt +77 -0
  15. package/android/src/main/java/com/connexup/square/mobilepayment/MobilePaymentSetting.kt +144 -0
  16. package/android/src/main/java/com/connexup/square/mobilepayment/convert/AdditionalPaymentMethodConvert.kt +46 -0
  17. package/android/src/main/java/com/connexup/square/mobilepayment/convert/AuthorizationStateConvert.kt +26 -0
  18. package/android/src/main/java/com/connexup/square/mobilepayment/convert/CardConvert.kt +53 -0
  19. package/android/src/main/java/com/connexup/square/mobilepayment/convert/CardDetailsConvert.kt +74 -0
  20. package/android/src/main/java/com/connexup/square/mobilepayment/convert/CardEntryMethodConvert.kt +31 -0
  21. package/android/src/main/java/com/connexup/square/mobilepayment/convert/CashPaymentDetailsConvert.kt +18 -0
  22. package/android/src/main/java/com/connexup/square/mobilepayment/convert/CurrencyCodeConvert.kt +204 -0
  23. package/android/src/main/java/com/connexup/square/mobilepayment/convert/DelayActionConvert.kt +33 -0
  24. package/android/src/main/java/com/connexup/square/mobilepayment/convert/DeniedReasonConvert.kt +28 -0
  25. package/android/src/main/java/com/connexup/square/mobilepayment/convert/DigitalWalletDetailsConvert.kt +18 -0
  26. package/android/src/main/java/com/connexup/square/mobilepayment/convert/ErrorDetailsConvert.kt +32 -0
  27. package/android/src/main/java/com/connexup/square/mobilepayment/convert/ExternalPaymentDetailsConvert.kt +25 -0
  28. package/android/src/main/java/com/connexup/square/mobilepayment/convert/LocationConvert.kt +31 -0
  29. package/android/src/main/java/com/connexup/square/mobilepayment/convert/MoneyConvert.kt +31 -0
  30. package/android/src/main/java/com/connexup/square/mobilepayment/convert/OfflineStatusConvert.kt +21 -0
  31. package/android/src/main/java/com/connexup/square/mobilepayment/convert/PaymentConvert.kt +93 -0
  32. package/android/src/main/java/com/connexup/square/mobilepayment/convert/PaymentProcessingFeeConvert.kt +39 -0
  33. package/android/src/main/java/com/connexup/square/mobilepayment/convert/PaymentSettingsConvert.kt +26 -0
  34. package/android/src/main/java/com/connexup/square/mobilepayment/convert/ProcessingModeConvert.kt +28 -0
  35. package/android/src/main/java/com/connexup/square/mobilepayment/convert/ReaderBatteryStatusConvert.kt +19 -0
  36. package/android/src/main/java/com/connexup/square/mobilepayment/convert/ReaderChangeEventConvert.kt +75 -0
  37. package/android/src/main/java/com/connexup/square/mobilepayment/convert/ReaderConnectionTypeConvert.kt +17 -0
  38. package/android/src/main/java/com/connexup/square/mobilepayment/convert/ReaderInfoConvert.kt +51 -0
  39. package/android/src/main/java/com/connexup/square/mobilepayment/convert/ReaderModalConvert.kt +18 -0
  40. package/android/src/main/java/com/connexup/square/mobilepayment/convert/ReaderStateConvert.kt +51 -0
  41. package/android/src/main/java/com/connexup/square/mobilepayment/convert/ReaderStatusConvert.kt +51 -0
  42. package/android/src/main/java/com/connexup/square/mobilepayment/convert/SdkSettingsConvert.kt +30 -0
  43. package/android/src/main/java/com/connexup/square/mobilepayment/convert/SquareAccountDetailsConvert.kt +20 -0
  44. package/android/src/main/java/com/connexup/square/mobilepayment/convert/TrackingConsentStateConvert.kt +17 -0
  45. package/android/src/main/java/com/connexup/square/mobilepayment/convert/WalletBrandConvert.kt +41 -0
  46. package/ios/Converters/AdditionalPaymentMethod+Extension.swift +17 -0
  47. package/ios/Converters/AdditionalPaymentMethodType+Extension.swift +44 -0
  48. package/ios/Converters/AuthorizationState+Extension.swift +22 -0
  49. package/ios/Converters/BatteryLevel+Extension.swift +27 -0
  50. package/ios/Converters/Card+Extension.swift +33 -0
  51. package/ios/Converters/CardBrand+Extension.swift +47 -0
  52. package/ios/Converters/CardCoBrand+Extension.swift +24 -0
  53. package/ios/Converters/CardEntryMethod+Extension.swift +30 -0
  54. package/ios/Converters/CardInputMethods+Extension.swift +35 -0
  55. package/ios/Converters/CardInsertionStatus+Extension.swift +24 -0
  56. package/ios/Converters/CardPaymentDetails+Extensions.swift +31 -0
  57. package/ios/Converters/CardPaymentStatus+Extension.swift +28 -0
  58. package/ios/Converters/Currency+Extension.swift +50 -0
  59. package/ios/Converters/Location+Extension.swift +19 -0
  60. package/ios/Converters/MoneyAmount+Extension.swift +30 -0
  61. package/ios/Converters/Payment+Extension.swift +44 -0
  62. package/ios/Converters/PaymentSettings+Extension.swift +19 -0
  63. package/ios/Converters/PaymentStatus+Extension.swift +53 -0
  64. package/ios/Converters/ProcessingMode+Extension.swift +37 -0
  65. package/ios/Converters/ReaderBatteryStatus+Extension.swift +19 -0
  66. package/ios/Converters/ReaderChange+Extension.swift +41 -0
  67. package/ios/Converters/ReaderConnectionFailureInfo+Extension.swift +20 -0
  68. package/ios/Converters/ReaderConnectionFailureReason+Extension.swift +40 -0
  69. package/ios/Converters/ReaderConnectionFailureRecoverySuggestion+Extension.swift +30 -0
  70. package/ios/Converters/ReaderConnectionInfo+Extension.swift +18 -0
  71. package/ios/Converters/ReaderConnectionStatus+Extension.swift +26 -0
  72. package/ios/Converters/ReaderFirmwareInfo+Extension.swift +19 -0
  73. package/ios/Converters/ReaderInfo+Extension.swift +30 -0
  74. package/ios/Converters/ReaderModel+Extension.swift +28 -0
  75. package/ios/Converters/ReaderState+Extension.swift +30 -0
  76. package/ios/Converters/ReaderStatus+Extension.swift +60 -0
  77. package/ios/Converters/ReaderStatusInfo+Extension.swift +22 -0
  78. package/ios/Converters/SDKSettings+Extension.swift +25 -0
  79. package/ios/Converters/SourceType+Extension.swift +32 -0
  80. package/ios/Converters/TrackingConsentState+Extension.swift +25 -0
  81. package/ios/ErrorUtilities.swift +41 -0
  82. package/ios/MobilePaymentAuthorization.swift +154 -0
  83. package/ios/MobilePaymentDateFormatter.swift +15 -0
  84. package/ios/MobilePaymentPayment.swift +478 -0
  85. package/ios/MobilePaymentReader.swift +248 -0
  86. package/ios/MobilePaymentSDK.swift +36 -0
  87. package/ios/MobilePaymentSetting.swift +86 -0
  88. package/ios/MockReaderUIManage.swift +52 -0
  89. package/ios/Models/NativeErrorInfo.swift +22 -0
  90. package/ios/Models/RCTPaymentMoneyParameter.swift +20 -0
  91. package/ios/Models/RCTPaymentParameters.swift +50 -0
  92. package/ios/Models/RCTPromptParameters.swift +20 -0
  93. package/ios/NotificationKeys.swift +9 -0
  94. package/ios/NotificationUtils.swift +21 -0
  95. package/ios/RCTMobilePaymentAuthorization.h +12 -0
  96. package/ios/RCTMobilePaymentAuthorization.mm +78 -0
  97. package/ios/RCTMobilePaymentPayment.h +12 -0
  98. package/ios/RCTMobilePaymentPayment.mm +116 -0
  99. package/ios/RCTMobilePaymentReader.h +12 -0
  100. package/ios/RCTMobilePaymentReader.mm +114 -0
  101. package/ios/RCTMobilePaymentSetting.h +10 -0
  102. package/ios/RCTMobilePaymentSetting.mm +94 -0
  103. package/ios/UIColor+Extension.swift +81 -0
  104. package/lib/module/authorization/NativeMobilePaymentAuthorization.js +60 -0
  105. package/lib/module/authorization/NativeMobilePaymentAuthorization.js.map +1 -0
  106. package/lib/module/authorization/index.js +44 -0
  107. package/lib/module/authorization/index.js.map +1 -0
  108. package/lib/module/index.js +7 -0
  109. package/lib/module/index.js.map +1 -0
  110. package/lib/module/package.json +1 -0
  111. package/lib/module/payment/NativeMobilePaymentPayment.js +138 -0
  112. package/lib/module/payment/NativeMobilePaymentPayment.js.map +1 -0
  113. package/lib/module/payment/index.js +113 -0
  114. package/lib/module/payment/index.js.map +1 -0
  115. package/lib/module/reader/NativeMobilePaymentReader.js +151 -0
  116. package/lib/module/reader/NativeMobilePaymentReader.js.map +1 -0
  117. package/lib/module/reader/index.js +109 -0
  118. package/lib/module/reader/index.js.map +1 -0
  119. package/lib/module/setting/NativeMobilePaymentSetting.js +5 -0
  120. package/lib/module/setting/NativeMobilePaymentSetting.js.map +1 -0
  121. package/lib/module/setting/index.js +74 -0
  122. package/lib/module/setting/index.js.map +1 -0
  123. package/lib/module/type.js +27 -0
  124. package/lib/module/type.js.map +1 -0
  125. package/lib/module/util.js +32 -0
  126. package/lib/module/util.js.map +1 -0
  127. package/lib/typescript/package.json +1 -0
  128. package/lib/typescript/src/authorization/NativeMobilePaymentAuthorization.d.ts +82 -0
  129. package/lib/typescript/src/authorization/NativeMobilePaymentAuthorization.d.ts.map +1 -0
  130. package/lib/typescript/src/authorization/index.d.ts +14 -0
  131. package/lib/typescript/src/authorization/index.d.ts.map +1 -0
  132. package/lib/typescript/src/index.d.ts +5 -0
  133. package/lib/typescript/src/index.d.ts.map +1 -0
  134. package/lib/typescript/src/payment/NativeMobilePaymentPayment.d.ts +725 -0
  135. package/lib/typescript/src/payment/NativeMobilePaymentPayment.d.ts.map +1 -0
  136. package/lib/typescript/src/payment/index.d.ts +13 -0
  137. package/lib/typescript/src/payment/index.d.ts.map +1 -0
  138. package/lib/typescript/src/reader/NativeMobilePaymentReader.d.ts +318 -0
  139. package/lib/typescript/src/reader/NativeMobilePaymentReader.d.ts.map +1 -0
  140. package/lib/typescript/src/reader/index.d.ts +19 -0
  141. package/lib/typescript/src/reader/index.d.ts.map +1 -0
  142. package/lib/typescript/src/setting/NativeMobilePaymentSetting.d.ts +49 -0
  143. package/lib/typescript/src/setting/NativeMobilePaymentSetting.d.ts.map +1 -0
  144. package/lib/typescript/src/setting/index.d.ts +17 -0
  145. package/lib/typescript/src/setting/index.d.ts.map +1 -0
  146. package/lib/typescript/src/type.d.ts +23 -0
  147. package/lib/typescript/src/type.d.ts.map +1 -0
  148. package/lib/typescript/src/util.d.ts +3 -0
  149. package/lib/typescript/src/util.d.ts.map +1 -0
  150. package/package.json +178 -0
  151. package/src/authorization/NativeMobilePaymentAuthorization.ts +297 -0
  152. package/src/authorization/index.ts +60 -0
  153. package/src/index.ts +4 -0
  154. package/src/payment/NativeMobilePaymentPayment.ts +1220 -0
  155. package/src/payment/index.ts +161 -0
  156. package/src/reader/NativeMobilePaymentReader.ts +463 -0
  157. package/src/reader/index.ts +140 -0
  158. package/src/setting/NativeMobilePaymentSetting.ts +254 -0
  159. package/src/setting/index.ts +91 -0
  160. package/src/type.ts +35 -0
  161. package/src/util.ts +31 -0
@@ -0,0 +1,344 @@
1
+ package com.connexup.square.mobilepayment
2
+
3
+ import com.connexup.square.mobilepayment.convert.getReaderChangeJsonValue
4
+ import com.connexup.square.mobilepayment.convert.readableMap
5
+ import com.facebook.react.bridge.Promise
6
+ import com.facebook.react.bridge.ReactApplicationContext
7
+ import com.facebook.react.bridge.WritableArray
8
+ import com.facebook.react.bridge.WritableNativeArray
9
+ import com.facebook.react.bridge.WritableNativeMap
10
+ import com.squareup.sdk.mobilepayments.MobilePaymentsSdk
11
+ import com.squareup.sdk.mobilepayments.cardreader.PairingErrorCode
12
+ import com.squareup.sdk.mobilepayments.cardreader.PairingHandle
13
+ import com.squareup.sdk.mobilepayments.cardreader.ReaderChangedEvent
14
+ import com.squareup.sdk.mobilepayments.cardreader.ReaderInfo
15
+ import com.squareup.sdk.mobilepayments.core.CallbackReference
16
+ import com.squareup.sdk.mobilepayments.core.Result
17
+ import kotlinx.coroutines.CoroutineScope
18
+ import kotlinx.coroutines.Dispatchers
19
+ import kotlinx.coroutines.SupervisorJob
20
+ import kotlinx.coroutines.launch
21
+ import java.util.concurrent.ConcurrentHashMap
22
+
23
+ private const val PRESENT_SETTINGS_ERROR_UNEXPECTED = "PRESENT_SETTINGS_ERROR_UNEXPECTED"
24
+
25
+ /**
26
+ * Description:
27
+ * @author lukechen@chancetop.com
28
+ * @date 2026/2/2
29
+ */
30
+
31
+ private const val PAIRING_ERROR_ALREADY_IN_PROGRESS = "PAIRING_ERROR_ALREADY_IN_PROGRESS"
32
+ private const val PAIRING_ERROR_NOT_AUTHORIZED = "PAIRING_ERROR_NOT_AUTHORIZED"
33
+ private const val PAIRING_ERROR_NOT_SUPPORTED = "PAIRING_ERROR_NOT_SUPPORTED"
34
+ private const val PAIRING_ERROR_TIMED_OUT = "PAIRING_ERROR_TIMED_OUT"
35
+ private const val PAIRING_ERROR_READER_ALREADY_PAIRING = "PAIRING_ERROR_READER_ALREADY_PAIRING"
36
+ private const val PAIRING_ERROR_FAILED_TO_CONNECT = "PAIRING_ERROR_FAILED_TO_CONNECT"
37
+ private const val PAIRING_ERROR_BLUETOOTH_DISABLED = "PAIRING_ERROR_BLUETOOTH_DISABLED"
38
+ private const val PAIRING_ERROR_UPDATE_REQUIRED = "PAIRING_ERROR_UPDATE_REQUIRED"
39
+ private const val PAIRING_ERROR_BLUETOOTH_PERMISSION_NOT_DETERMINED =
40
+ "PAIRING_ERROR_BLUETOOTH_PERMISSION_NOT_DETERMINED"
41
+ private const val PAIRING_ERROR_BLUETOOTH_PERMISSION_RESTRICTED =
42
+ "PAIRING_ERROR_BLUETOOTH_PERMISSION_RESTRICTED"
43
+ private const val PAIRING_ERROR_BLUETOOTH_PERMISSION_DENIED =
44
+ "PAIRING_ERROR_BLUETOOTH_PERMISSION_DENIED"
45
+ private const val PAIRING_ERROR_BLUETOOTH_PERMISSION_UNKNOWN_CASE =
46
+ "PAIRING_ERROR_BLUETOOTH_PERMISSION_UNKNOWN_CASE"
47
+ private const val PAIRING_ERROR_BLUETOOTH_NOT_SUPPORTED = "PAIRING_ERROR_BLUETOOTH_NOT_SUPPORTED"
48
+ private const val PAIRING_ERROR_BLUETOOTH_NOT_READY = "PAIRING_ERROR_BLUETOOTH_NOT_READY"
49
+ private const val PAIRING_ERROR_BLUETOOTH_RESETTING = "PAIRING_ERROR_BLUETOOTH_RESETTING"
50
+ private const val PAIRING_ERROR_BONDING_REMOVED = "PAIRING_ERROR_BONDING_REMOVED"
51
+ private const val PAIRING_ERROR_BLUETOOTH_UNKNOWN_ERROR = "PAIRING_ERROR_BLUETOOTH_UNKNOWN_ERROR"
52
+ private const val PAIRING_ERROR_PAIRING_ERROR_APP_UPDATE_REQUIRED =
53
+ "PAIRING_ERROR_APP_UPDATE_REQUIRED"
54
+ private const val PAIRING_ERROR_BOND_FAILED = "PAIRING_ERROR_BOND_FAILED"
55
+ private const val PAIRING_ERROR_INTERNAL_FIRMWARE_ERROR = "PAIRING_ERROR_INTERNAL_FIRMWARE_ERROR"
56
+ private const val PAIRING_ERROR_UNKNOWN_ERROR = "PAIRING_ERROR_UNKNOWN_ERROR"
57
+
58
+
59
+ class MobilePaymentReader(reactContext: ReactApplicationContext) :
60
+ NativeMobilePaymentReaderSpec(reactContext) {
61
+
62
+ private val scope: CoroutineScope by lazy {
63
+ CoroutineScope(
64
+ SupervisorJob() + Dispatchers.Main
65
+ )
66
+ }
67
+
68
+ private var readerChangedCallbackRef: CallbackReference? = null
69
+
70
+ private var pairingHandle: PairingHandle? = null
71
+
72
+ private val readerStateRecord = ConcurrentHashMap<String, ReaderInfo.State>()
73
+
74
+ private var initializeListener: InitializeListener? = null
75
+
76
+ override fun initialize() {
77
+ super.initialize()
78
+ this.initializeListener = MobilePaymentSDK.addInitializeListener {
79
+ onSDKInitialize()
80
+ }
81
+ if (MobilePaymentSDK.isInitialize) {
82
+ initializeListener?.onInitialize()
83
+ }
84
+ }
85
+
86
+ override fun invalidate() {
87
+ initializeListener?.let {
88
+ MobilePaymentSDK.removeInitializeListener(it)
89
+ }
90
+ initializeListener = null
91
+ readerChangedCallbackRef?.clear()
92
+ readerChangedCallbackRef = null
93
+ readerStateRecord.clear()
94
+ super.invalidate()
95
+ }
96
+
97
+ private fun onSDKInitialize() {
98
+ readerChangedCallbackRef?.clear()
99
+ readerChangedCallbackRef = MobilePaymentsSdk.readerManager().setReaderChangedCallback {
100
+ onReaderChanged(it)
101
+ }
102
+ }
103
+
104
+ override fun isPairingInProgress(): Boolean {
105
+ return MobilePaymentsSdk.readerManager().isPairingInProgress
106
+ }
107
+
108
+ override fun readers(): WritableArray {
109
+ val result = WritableNativeArray()
110
+ MobilePaymentsSdk.readerManager().getReaders().forEach {
111
+ result.pushMap(it.readableMap)
112
+ }
113
+ return result
114
+ }
115
+
116
+ override fun bink(readerId: String, promise: Promise) {
117
+ scope.launch {
118
+ val reader = MobilePaymentsSdk.readerManager().getReader(readerId)
119
+ if (reader == null) {
120
+ promise.reject(
121
+ UNKNOWN_ERROR,
122
+ RNMobilePaymentErrorUtilities.createNativeModuleError(
123
+ UNKNOWN_ERROR,
124
+ "Reader Not Found",
125
+ ),
126
+ null,
127
+ )
128
+ return@launch
129
+ }
130
+ if (!reader.isBlinkable) {
131
+ promise.reject(
132
+ UNKNOWN_ERROR,
133
+ RNMobilePaymentErrorUtilities.createNativeModuleError(
134
+ UNKNOWN_ERROR,
135
+ "Reader Cannot Bink",
136
+ ),
137
+ null,
138
+ )
139
+ return@launch
140
+ }
141
+ try {
142
+ MobilePaymentsSdk.readerManager().blink(reader)
143
+ promise.resolve(null)
144
+ } catch (e: Exception) {
145
+ promise.reject(
146
+ UNKNOWN_ERROR,
147
+ RNMobilePaymentErrorUtilities.serializeErrorToJson(
148
+ UNKNOWN_ERROR,
149
+ e.message ?: "",
150
+ ),
151
+ e,
152
+ )
153
+ }
154
+ }
155
+ }
156
+
157
+ override fun forget(readerId: String, promise: Promise) {
158
+ scope.launch {
159
+ val reader = MobilePaymentsSdk.readerManager().getReader(readerId)
160
+ if (reader == null) {
161
+ promise.reject(
162
+ UNKNOWN_ERROR,
163
+ RNMobilePaymentErrorUtilities.createNativeModuleError(
164
+ UNKNOWN_ERROR,
165
+ "Reader Not Found",
166
+ ),
167
+ null,
168
+ )
169
+ return@launch
170
+ }
171
+ if (!reader.isForgettable) {
172
+ promise.reject(
173
+ UNKNOWN_ERROR,
174
+ RNMobilePaymentErrorUtilities.createNativeModuleError(
175
+ UNKNOWN_ERROR,
176
+ "Reader Cannot Forget",
177
+ ),
178
+ null,
179
+ )
180
+ return@launch
181
+ }
182
+ try {
183
+ MobilePaymentsSdk.readerManager().forget(reader)
184
+ promise.resolve(null)
185
+ } catch (e: Exception) {
186
+ promise.reject(
187
+ UNKNOWN_ERROR,
188
+ RNMobilePaymentErrorUtilities.serializeErrorToJson(
189
+ UNKNOWN_ERROR,
190
+ e.message ?: "",
191
+ ),
192
+ e,
193
+ )
194
+ }
195
+ }
196
+ }
197
+
198
+ override fun retryConnection(
199
+ readerId: String,
200
+ promise: Promise
201
+ ) {
202
+ scope.launch {
203
+ val reader = MobilePaymentsSdk.readerManager().getReader(readerId)
204
+ if (reader == null) {
205
+ promise.reject(
206
+ UNKNOWN_ERROR,
207
+ RNMobilePaymentErrorUtilities.createNativeModuleError(
208
+ UNKNOWN_ERROR,
209
+ "Reader Not Found",
210
+ ),
211
+ null,
212
+ )
213
+ return@launch
214
+ }
215
+ try {
216
+ MobilePaymentsSdk.readerManager().retryConnection(reader)
217
+ promise.resolve(null)
218
+ } catch (e: Exception) {
219
+ promise.reject(
220
+ UNKNOWN_ERROR,
221
+ RNMobilePaymentErrorUtilities.createNativeModuleError(
222
+ UNKNOWN_ERROR,
223
+ "Reader Cannot Retry Connection",
224
+ ),
225
+ null,
226
+ )
227
+ }
228
+ }
229
+ }
230
+
231
+ override fun startPairing(promise: Promise) {
232
+ scope.launch {
233
+ if (MobilePaymentsSdk.readerManager().isPairingInProgress) {
234
+ promise.reject(
235
+ PAIRING_ERROR_ALREADY_IN_PROGRESS,
236
+ RNMobilePaymentErrorUtilities.createNativeModuleError(
237
+ PAIRING_ERROR_ALREADY_IN_PROGRESS,
238
+ ),
239
+ null
240
+ )
241
+ return@launch
242
+ }
243
+ pairingHandle = MobilePaymentsSdk.readerManager().pairReader {
244
+ when (it) {
245
+ is Result.Failure -> {
246
+ sendPairingStatusChangeEvent("didFail", it)
247
+ }
248
+
249
+ is Result.Success -> {
250
+ if (it.value) {
251
+ sendPairingStatusChangeEvent("didSucceed", null)
252
+ }
253
+ }
254
+ }
255
+ }
256
+ promise.resolve(null)
257
+ sendPairingStatusChangeEvent("didBegin", null)
258
+ }
259
+ }
260
+
261
+ override fun stopPairing(promise: Promise) {
262
+ scope.launch {
263
+ val pairingHandle = pairingHandle
264
+ if (pairingHandle == null) {
265
+ promise.resolve(true)
266
+ return@launch
267
+ }
268
+
269
+ promise.resolve(
270
+ when (pairingHandle.stop()) {
271
+ PairingHandle.StopResult.ALREADY_COMPLETE -> false
272
+ PairingHandle.StopResult.STOPPED -> true
273
+ }
274
+ )
275
+ }
276
+ }
277
+
278
+ private fun onReaderChanged(event: ReaderChangedEvent) {
279
+ val eventName = when (event.change) {
280
+ ReaderChangedEvent.Change.ADDED -> {
281
+ "readerWasAdded"
282
+ }
283
+
284
+ ReaderChangedEvent.Change.REMOVED -> {
285
+ "readerWasRemoved"
286
+ }
287
+
288
+ else -> {
289
+ "readerDidChange"
290
+ }
291
+ }
292
+
293
+ val lastReaderState = readerStateRecord[event.reader.id]
294
+
295
+ val result = WritableNativeMap()
296
+ result.putString("name", eventName)
297
+ result.putMap("readerInfo", event.reader.readableMap)
298
+ result.putString("readerChange", event.getReaderChangeJsonValue(lastReaderState))
299
+ emitOnReaderChange(result)
300
+
301
+ if (event.change === ReaderChangedEvent.Change.REMOVED) {
302
+ readerStateRecord.remove(event.reader.id)
303
+ } else {
304
+ readerStateRecord[event.reader.id] = event.reader.state
305
+ }
306
+ }
307
+
308
+ private fun sendPairingStatusChangeEvent(
309
+ name: String,
310
+ error: Result.Failure<Boolean, PairingErrorCode>?
311
+ ) {
312
+ val result = WritableNativeMap()
313
+ result.putString("name", name)
314
+ if (error != null) {
315
+ val errorCode = when (error.errorCode) {
316
+ PairingErrorCode.BLUETOOTH_ALREADY_SCANNING -> PAIRING_ERROR_ALREADY_IN_PROGRESS
317
+ PairingErrorCode.BLUETOOTH_DISABLED -> PAIRING_ERROR_BLUETOOTH_DISABLED
318
+ PairingErrorCode.BLUETOOTH_PERMISSION_DENIED -> PAIRING_ERROR_BLUETOOTH_PERMISSION_DENIED
319
+ PairingErrorCode.BLUETOOTH_UNSUPPORTED -> PAIRING_ERROR_BLUETOOTH_NOT_SUPPORTED
320
+ PairingErrorCode.NOT_AUTHORIZED -> PAIRING_ERROR_NOT_AUTHORIZED
321
+ PairingErrorCode.TIMEOUT -> PAIRING_ERROR_TIMED_OUT
322
+ PairingErrorCode.USAGE_ERROR -> PAIRING_ERROR_BLUETOOTH_UNKNOWN_ERROR
323
+ PairingErrorCode.APP_UPDATE_REQUIRED -> PAIRING_ERROR_PAIRING_ERROR_APP_UPDATE_REQUIRED
324
+ PairingErrorCode.BOND_FAILED -> PAIRING_ERROR_BOND_FAILED
325
+ PairingErrorCode.INTERNAL_FIRMWARE_ERROR -> PAIRING_ERROR_INTERNAL_FIRMWARE_ERROR
326
+ PairingErrorCode.UNKNOWN_ERROR -> PAIRING_ERROR_UNKNOWN_ERROR
327
+ }
328
+ result.putString(
329
+ "error", RNMobilePaymentErrorUtilities.serializeErrorToJson(
330
+ errorCode,
331
+ error.errorMessage,
332
+ error.debugCode,
333
+ error.debugMessage
334
+ )
335
+ )
336
+ emitOnReaderPairingStatus(result)
337
+ }
338
+ }
339
+
340
+
341
+ companion object {
342
+ const val NAME = NativeMobilePaymentReaderSpec.NAME
343
+ }
344
+ }
@@ -0,0 +1,47 @@
1
+ package com.connexup.square.mobilepayment
2
+
3
+ import android.app.Application
4
+ import com.squareup.sdk.mobilepayments.MobilePaymentsSdk
5
+ import kotlin.collections.mutableListOf
6
+ import kotlin.getValue
7
+
8
+ /**
9
+ * Description:
10
+ * @author lukechen@chancetop.com
11
+ * @date 2026/1/30
12
+ */
13
+
14
+ fun interface InitializeListener {
15
+ fun onInitialize()
16
+ }
17
+
18
+ object MobilePaymentSDK {
19
+
20
+ var applicationId: String? = null
21
+ private set
22
+
23
+ val isInitialize get() = applicationId != null
24
+
25
+ private val initializeListeners by lazy {
26
+ mutableListOf<InitializeListener>()
27
+ }
28
+
29
+ fun addInitializeListener(listener: InitializeListener): InitializeListener {
30
+ this.initializeListeners.add(listener)
31
+ return listener
32
+ }
33
+
34
+ fun removeInitializeListener(listener: InitializeListener) {
35
+ this.initializeListeners.remove(listener)
36
+ }
37
+
38
+ fun initialize(applicationId: String, application: Application): Boolean {
39
+ if (this.isInitialize) {
40
+ return this.applicationId == applicationId
41
+ }
42
+ MobilePaymentsSdk.initialize(applicationId, application)
43
+ this.applicationId = applicationId
44
+ initializeListeners.forEach { it.onInitialize() }
45
+ return true
46
+ }
47
+ }
@@ -0,0 +1,77 @@
1
+ package com.connexup.square.mobilepayment
2
+
3
+ import com.facebook.react.BaseReactPackage
4
+ import com.facebook.react.bridge.NativeModule
5
+ import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.module.model.ReactModuleInfo
7
+ import com.facebook.react.module.model.ReactModuleInfoProvider
8
+ import java.util.HashMap
9
+
10
+ class MobilePaymentSDKPackage : BaseReactPackage() {
11
+ override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
12
+ return when (name) {
13
+ MobilePaymentAuthorization.NAME -> {
14
+ MobilePaymentAuthorization(reactContext)
15
+ }
16
+
17
+ MobilePaymentPayment.NAME -> {
18
+ MobilePaymentPayment(reactContext)
19
+ }
20
+
21
+ MobilePaymentReader.NAME -> {
22
+ MobilePaymentReader(reactContext)
23
+ }
24
+
25
+ MobilePaymentSetting.NAME -> {
26
+ MobilePaymentSetting(reactContext)
27
+ }
28
+
29
+ else -> {
30
+ null
31
+ }
32
+ }
33
+ }
34
+
35
+ override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
36
+ return ReactModuleInfoProvider {
37
+ val moduleInfos: MutableMap<String, ReactModuleInfo> = HashMap()
38
+ moduleInfos[MobilePaymentAuthorization.NAME] = ReactModuleInfo(
39
+ name = MobilePaymentAuthorization.NAME,
40
+ className = MobilePaymentAuthorization.NAME,
41
+ canOverrideExistingModule = false,
42
+ needsEagerInit = false,
43
+ isCxxModule = false,
44
+ isTurboModule = true
45
+ )
46
+
47
+ moduleInfos[MobilePaymentPayment.NAME] = ReactModuleInfo(
48
+ name = MobilePaymentPayment.NAME,
49
+ className = MobilePaymentPayment.NAME,
50
+ canOverrideExistingModule = false,
51
+ needsEagerInit = false,
52
+ isCxxModule = false,
53
+ isTurboModule = true
54
+ )
55
+
56
+ moduleInfos[MobilePaymentReader.NAME] = ReactModuleInfo(
57
+ name = MobilePaymentReader.NAME,
58
+ className = MobilePaymentReader.NAME,
59
+ canOverrideExistingModule = false,
60
+ needsEagerInit = false,
61
+ isCxxModule = false,
62
+ isTurboModule = true
63
+ )
64
+
65
+ moduleInfos[MobilePaymentSetting.NAME] = ReactModuleInfo(
66
+ name = MobilePaymentSetting.NAME,
67
+ className = MobilePaymentSetting.NAME,
68
+ canOverrideExistingModule = false,
69
+ needsEagerInit = false,
70
+ isCxxModule = false,
71
+ isTurboModule = true
72
+ )
73
+
74
+ moduleInfos
75
+ }
76
+ }
77
+ }
@@ -0,0 +1,144 @@
1
+ package com.connexup.square.mobilepayment
2
+
3
+ import com.connexup.square.mobilepayment.convert.jsonValue
4
+ import com.connexup.square.mobilepayment.convert.writableMap
5
+ import com.facebook.react.bridge.Promise
6
+ import com.facebook.react.bridge.ReactApplicationContext
7
+ import com.facebook.react.bridge.WritableMap
8
+ import com.squareup.sdk.mobilepayments.MobilePaymentsSdk
9
+ import com.squareup.sdk.mobilepayments.core.Result
10
+ import com.squareup.sdk.mobilepayments.mockreader.ui.MockReaderUI
11
+ import com.squareup.sdk.mobilepayments.settings.SettingsErrorCode
12
+ import kotlinx.coroutines.CoroutineScope
13
+ import kotlinx.coroutines.Dispatchers
14
+ import kotlinx.coroutines.SupervisorJob
15
+ import kotlinx.coroutines.launch
16
+
17
+ private const val INIT_SDK_ERROR = "INIT_SDK_ERROR"
18
+ private const val PRESENT_SETTINGS_ERROR_UNEXPECTED = "PRESENT_SETTINGS_ERROR_UNEXPECTED"
19
+ private const val PRESENT_MOCK_UI_ERROR_UNEXPECTED = "PRESENT_MOCK_UI_ERROR_UNEXPECTED"
20
+
21
+ /**
22
+ * Description:
23
+ * @author lukechen@chancetop.com
24
+ * @date 2026/2/2
25
+ */
26
+ class MobilePaymentSetting(reactContext: ReactApplicationContext) :
27
+ NativeMobilePaymentSettingSpec(reactContext) {
28
+
29
+ private val scope: CoroutineScope by lazy {
30
+ CoroutineScope(
31
+ SupervisorJob() + Dispatchers.Main
32
+ )
33
+ }
34
+
35
+ override fun applicationId(): String? {
36
+ return MobilePaymentSDK.applicationId
37
+ }
38
+
39
+ override fun initialize(applicationId: String, promise: Promise) {
40
+ scope.launch {
41
+ try {
42
+ val application = reactApplicationContextIfActiveOrWarn?.currentActivity?.application
43
+ ?: throw Exception("application is null")
44
+ val result = MobilePaymentSDK.initialize(
45
+ applicationId,
46
+ application
47
+ )
48
+ promise.resolve(result)
49
+ } catch (e: Exception) {
50
+ promise.reject(
51
+ INIT_SDK_ERROR,
52
+ RNMobilePaymentErrorUtilities.serializeErrorToJson(
53
+ code = INIT_SDK_ERROR,
54
+ message = e.message ?: "",
55
+ ),
56
+ e,
57
+ )
58
+ }
59
+ }
60
+ }
61
+
62
+ override fun sdkSettings(): WritableMap {
63
+ return MobilePaymentsSdk.settingsManager().getSdkSettings().writableMap
64
+ }
65
+
66
+ override fun paymentSettings(): WritableMap {
67
+ return MobilePaymentsSdk.settingsManager().getPaymentSettings().writableMap
68
+ }
69
+
70
+ override fun trackingConsentState(): String {
71
+ return MobilePaymentsSdk.settingsManager().trackingConsentState.jsonValue
72
+ }
73
+
74
+ override fun updateTrackingConsent(
75
+ granted: Boolean,
76
+ promise: Promise
77
+ ) {
78
+ scope.launch {
79
+ try {
80
+ MobilePaymentsSdk.settingsManager().updateTrackingConsent(granted)
81
+ promise.resolve(null)
82
+ } catch (e: MobilePaymentException) {
83
+ promise.reject(
84
+ UNKNOWN_ERROR,
85
+ RNMobilePaymentErrorUtilities.serializeErrorToJson(
86
+ UNKNOWN_ERROR,
87
+ e.message ?: "",
88
+ ),
89
+ e,
90
+ )
91
+ }
92
+ }
93
+ }
94
+
95
+ override fun presentSettings(promise: Promise) {
96
+ scope.launch {
97
+ MobilePaymentsSdk.settingsManager().showSettings {
98
+ when (it) {
99
+ is Result.Failure -> {
100
+ val errorCode = when (it.errorCode) {
101
+ SettingsErrorCode.USAGE_ERROR -> PRESENT_SETTINGS_ERROR_UNEXPECTED
102
+ }
103
+ promise.reject(
104
+ errorCode,
105
+ RNMobilePaymentErrorUtilities.serializeErrorToJson(
106
+ code = errorCode,
107
+ message = it.errorMessage,
108
+ debugCode = it.debugCode,
109
+ debugMessage = it.debugMessage
110
+ ),
111
+ MobilePaymentException(it.errorMessage),
112
+ )
113
+ }
114
+
115
+ is Result.Success -> {
116
+ promise.resolve(null)
117
+ }
118
+ }
119
+ }
120
+ }
121
+ }
122
+
123
+ override fun presentMockReaderUI(promise: Promise) {
124
+ scope.launch {
125
+ if (MobilePaymentsSdk.isSandboxEnvironment()) {
126
+ MockReaderUI.show()
127
+ }
128
+ promise.resolve(null)
129
+ }
130
+ }
131
+
132
+ override fun dismissMockReaderUI(promise: Promise) {
133
+ scope.launch {
134
+ if (MobilePaymentsSdk.isSandboxEnvironment()) {
135
+ MockReaderUI.hide()
136
+ }
137
+ promise.resolve(null)
138
+ }
139
+ }
140
+
141
+ companion object {
142
+ const val NAME = NativeMobilePaymentSettingSpec.NAME
143
+ }
144
+ }
@@ -0,0 +1,46 @@
1
+ package com.connexup.square.mobilepayment.convert
2
+
3
+ import com.facebook.react.bridge.ReadableArray
4
+ import com.facebook.react.bridge.ReadableMap
5
+ import com.facebook.react.bridge.WritableArray
6
+ import com.facebook.react.bridge.WritableNativeArray
7
+ import com.facebook.react.bridge.WritableNativeMap
8
+ import com.squareup.sdk.mobilepayments.payment.AdditionalPaymentMethod
9
+
10
+ /**
11
+ * Description:
12
+ * @author lukechen@chancetop.com
13
+ * @date 2023/11/17
14
+ */
15
+
16
+ val List<AdditionalPaymentMethod>.readableArray: ReadableArray
17
+ get() {
18
+ return this.writableArray
19
+ }
20
+
21
+ val List<AdditionalPaymentMethod>.writableArray: WritableArray
22
+ get() {
23
+ val result = WritableNativeArray()
24
+ this.forEach {
25
+ result.pushMap(it.readableMap)
26
+ }
27
+ return result
28
+ }
29
+
30
+ val AdditionalPaymentMethod.readableMap: ReadableMap
31
+ get() {
32
+ val result = WritableNativeMap()
33
+ val type = when (this.type) {
34
+ AdditionalPaymentMethod.Type.KEYED -> "KEYED"
35
+ }
36
+ result.putString("type", type)
37
+ // result.putString("name", MainApplication.context.getString(this.label))
38
+ return result
39
+ }
40
+
41
+ fun String.toAdditionalPaymentMethodType(): AdditionalPaymentMethod.Type? {
42
+ return when (this) {
43
+ "KEYED" -> AdditionalPaymentMethod.Type.KEYED
44
+ else -> null
45
+ }
46
+ }
@@ -0,0 +1,26 @@
1
+ package com.connexup.square.mobilepayment.convert
2
+
3
+ import com.squareup.sdk.mobilepayments.authorization.AuthorizationState
4
+
5
+
6
+ /**
7
+ * Description:
8
+ * @author lukechen@chancetop.com
9
+ * @date 2023/11/16
10
+ */
11
+
12
+ val AuthorizationState.jsonValue: String
13
+ get() {
14
+ if (this == AuthorizationState.newAuthorizedState()) {
15
+ return "AUTHORIZED"
16
+ }
17
+
18
+ if (this == AuthorizationState.newUnauthorizedState()) {
19
+ return "NOT_AUTHORIZED"
20
+ }
21
+
22
+ if (this == AuthorizationState.newUnauthorizedState()) {
23
+ return "NOT_AUTHORIZED"
24
+ }
25
+ return "UNKNOWN"
26
+ }