@capacitor-community/stripe-terminal 6.4.0 → 6.4.1
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.
- package/README.md +16 -0
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/getcapacitor/community/stripe/terminal/StripeTerminal.kt +910 -0
- package/android/src/main/java/com/getcapacitor/community/stripe/terminal/StripeTerminalPlugin.kt +205 -0
- package/android/src/main/java/com/getcapacitor/community/stripe/terminal/TokenProvider.kt +85 -0
- package/android/src/main/java/com/getcapacitor/community/stripe/terminal/helper/MetaData.kt +24 -0
- package/android/src/main/java/com/getcapacitor/community/stripe/terminal/helper/TerminalMappers.kt +90 -0
- package/android/src/main/java/com/getcapacitor/community/stripe/terminal/models/Executor.kt +22 -0
- package/package.json +1 -1
- package/android/src/main/java/com/getcapacitor/community/stripe/terminal/StripeTerminal.java +0 -872
- package/android/src/main/java/com/getcapacitor/community/stripe/terminal/StripeTerminalPlugin.java +0 -193
- package/android/src/main/java/com/getcapacitor/community/stripe/terminal/TokenProvider.java +0 -105
- package/android/src/main/java/com/getcapacitor/community/stripe/terminal/helper/MetaData.java +0 -28
- package/android/src/main/java/com/getcapacitor/community/stripe/terminal/helper/TerminalMappers.java +0 -96
- package/android/src/main/java/com/getcapacitor/community/stripe/terminal/models/Executor.java +0 -33
|
@@ -0,0 +1,910 @@
|
|
|
1
|
+
package com.getcapacitor.community.stripe.terminal
|
|
2
|
+
|
|
3
|
+
import android.Manifest
|
|
4
|
+
import android.app.Activity
|
|
5
|
+
import android.app.Application
|
|
6
|
+
import android.bluetooth.BluetoothAdapter
|
|
7
|
+
import android.content.Context
|
|
8
|
+
import android.content.pm.PackageManager
|
|
9
|
+
import android.os.Build
|
|
10
|
+
import android.util.Log
|
|
11
|
+
import androidx.core.app.ActivityCompat
|
|
12
|
+
import androidx.core.util.Supplier
|
|
13
|
+
import com.getcapacitor.JSArray
|
|
14
|
+
import com.getcapacitor.JSObject
|
|
15
|
+
import com.getcapacitor.PluginCall
|
|
16
|
+
import com.getcapacitor.community.stripe.terminal.helper.TerminalMappers
|
|
17
|
+
import com.getcapacitor.community.stripe.terminal.models.Executor
|
|
18
|
+
import com.google.android.gms.common.util.BiConsumer
|
|
19
|
+
import com.stripe.stripeterminal.Terminal
|
|
20
|
+
import com.stripe.stripeterminal.Terminal.Companion.initTerminal
|
|
21
|
+
import com.stripe.stripeterminal.Terminal.Companion.isInitialized
|
|
22
|
+
import com.stripe.stripeterminal.TerminalApplicationDelegate.onCreate
|
|
23
|
+
import com.stripe.stripeterminal.external.callable.Callback
|
|
24
|
+
import com.stripe.stripeterminal.external.callable.Cancelable
|
|
25
|
+
import com.stripe.stripeterminal.external.callable.DiscoveryListener
|
|
26
|
+
import com.stripe.stripeterminal.external.callable.InternetReaderListener
|
|
27
|
+
import com.stripe.stripeterminal.external.callable.MobileReaderListener
|
|
28
|
+
import com.stripe.stripeterminal.external.callable.PaymentIntentCallback
|
|
29
|
+
import com.stripe.stripeterminal.external.callable.ReaderCallback
|
|
30
|
+
import com.stripe.stripeterminal.external.callable.TapToPayReaderListener
|
|
31
|
+
import com.stripe.stripeterminal.external.callable.TerminalListener
|
|
32
|
+
import com.stripe.stripeterminal.external.models.BatteryStatus
|
|
33
|
+
import com.stripe.stripeterminal.external.models.CardPresentDetails
|
|
34
|
+
import com.stripe.stripeterminal.external.models.Cart
|
|
35
|
+
import com.stripe.stripeterminal.external.models.CartLineItem
|
|
36
|
+
import com.stripe.stripeterminal.external.models.CollectConfiguration
|
|
37
|
+
import com.stripe.stripeterminal.external.models.ConnectionConfiguration
|
|
38
|
+
import com.stripe.stripeterminal.external.models.ConnectionStatus
|
|
39
|
+
import com.stripe.stripeterminal.external.models.DisconnectReason
|
|
40
|
+
import com.stripe.stripeterminal.external.models.DiscoveryConfiguration
|
|
41
|
+
import com.stripe.stripeterminal.external.models.PaymentIntent
|
|
42
|
+
import com.stripe.stripeterminal.external.models.PaymentStatus
|
|
43
|
+
import com.stripe.stripeterminal.external.models.Reader
|
|
44
|
+
import com.stripe.stripeterminal.external.models.ReaderDisplayMessage
|
|
45
|
+
import com.stripe.stripeterminal.external.models.ReaderEvent
|
|
46
|
+
import com.stripe.stripeterminal.external.models.ReaderInputOptions
|
|
47
|
+
import com.stripe.stripeterminal.external.models.ReaderSoftwareUpdate
|
|
48
|
+
import com.stripe.stripeterminal.external.models.SimulateReaderUpdate
|
|
49
|
+
import com.stripe.stripeterminal.external.models.SimulatedCard
|
|
50
|
+
import com.stripe.stripeterminal.external.models.SimulatorConfiguration
|
|
51
|
+
import com.stripe.stripeterminal.external.models.TerminalException
|
|
52
|
+
import com.stripe.stripeterminal.log.LogLevel
|
|
53
|
+
import org.json.JSONException
|
|
54
|
+
import org.json.JSONObject
|
|
55
|
+
import java.util.Objects
|
|
56
|
+
|
|
57
|
+
//import com.stripe.stripeterminal.external.callable.ReaderReconnectionListener;
|
|
58
|
+
class StripeTerminal(
|
|
59
|
+
contextSupplier: Supplier<Context>,
|
|
60
|
+
activitySupplier: Supplier<Activity>,
|
|
61
|
+
notifyListenersFunction: BiConsumer<String, JSObject>,
|
|
62
|
+
pluginLogTag: String
|
|
63
|
+
) : Executor(
|
|
64
|
+
contextSupplier,
|
|
65
|
+
activitySupplier,
|
|
66
|
+
notifyListenersFunction,
|
|
67
|
+
pluginLogTag,
|
|
68
|
+
"StripeTerminalExecutor"
|
|
69
|
+
) {
|
|
70
|
+
private var tokenProvider: TokenProvider? = null
|
|
71
|
+
private var discoveryCancelable: Cancelable? = null
|
|
72
|
+
private var collectCancelable: Cancelable? = null
|
|
73
|
+
private var installUpdateCancelable: Cancelable? = null
|
|
74
|
+
private var cancelReaderConnectionCancellable: Cancelable? = null
|
|
75
|
+
private var discoveredReadersList: List<Reader?>
|
|
76
|
+
private var locationId: String? = null
|
|
77
|
+
private var collectCall: PluginCall? = null
|
|
78
|
+
private var confirmPaymentIntentCall: PluginCall? = null
|
|
79
|
+
private val emptyObject = JSObject()
|
|
80
|
+
private var isTest: Boolean? = null
|
|
81
|
+
private var terminalConnectType: TerminalConnectTypes? = null
|
|
82
|
+
private var paymentIntentInstance: PaymentIntent? = null
|
|
83
|
+
|
|
84
|
+
private val terminalMappers = TerminalMappers()
|
|
85
|
+
|
|
86
|
+
@Throws(TerminalException::class)
|
|
87
|
+
fun initialize(call: PluginCall) {
|
|
88
|
+
this.isTest = call.getBoolean("isTest", true)
|
|
89
|
+
|
|
90
|
+
val bluetooth = BluetoothAdapter.getDefaultAdapter()
|
|
91
|
+
if (!bluetooth.isEnabled) {
|
|
92
|
+
if (ActivityCompat.checkSelfPermission(
|
|
93
|
+
contextSupplier.get(),
|
|
94
|
+
Manifest.permission.BLUETOOTH_CONNECT
|
|
95
|
+
) ==
|
|
96
|
+
PackageManager.PERMISSION_GRANTED
|
|
97
|
+
) {
|
|
98
|
+
bluetooth.enable()
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
activitySupplier.get()
|
|
103
|
+
.runOnUiThread {
|
|
104
|
+
onCreate((contextSupplier.get().applicationContext as Application))
|
|
105
|
+
notifyListeners(TerminalEnumEvent.Loaded.webEventName, emptyObject)
|
|
106
|
+
call.resolve()
|
|
107
|
+
}
|
|
108
|
+
val listener: TerminalListener = object : TerminalListener {
|
|
109
|
+
override fun onConnectionStatusChange(status: ConnectionStatus) {
|
|
110
|
+
notifyListeners(
|
|
111
|
+
TerminalEnumEvent.ConnectionStatusChange.webEventName,
|
|
112
|
+
JSObject().put("status", status.toString())
|
|
113
|
+
)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
override fun onPaymentStatusChange(status: PaymentStatus) {
|
|
117
|
+
notifyListeners(
|
|
118
|
+
TerminalEnumEvent.PaymentStatusChange.webEventName,
|
|
119
|
+
JSObject().put("status", status.toString())
|
|
120
|
+
)
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
val logLevel = LogLevel.VERBOSE
|
|
124
|
+
this.tokenProvider = TokenProvider(
|
|
125
|
+
this.contextSupplier,
|
|
126
|
+
call.getString("tokenProviderEndpoint", "")!!,
|
|
127
|
+
this.notifyListenersFunction
|
|
128
|
+
)
|
|
129
|
+
if (!isInitialized()) {
|
|
130
|
+
initTerminal(
|
|
131
|
+
contextSupplier.get().applicationContext,
|
|
132
|
+
logLevel,
|
|
133
|
+
this.tokenProvider!!,
|
|
134
|
+
listener
|
|
135
|
+
)
|
|
136
|
+
}
|
|
137
|
+
Terminal.getInstance()
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
fun setConnectionToken(call: PluginCall) {
|
|
141
|
+
tokenProvider!!.setConnectionToken(call)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
fun setSimulatorConfiguration(call: PluginCall) {
|
|
145
|
+
try {
|
|
146
|
+
val updateString = call.getString("update", "UPDATE_AVAILABLE")
|
|
147
|
+
val simulateReaderUpdate = SimulateReaderUpdate.entries.find { it.name == updateString }
|
|
148
|
+
|
|
149
|
+
Terminal.getInstance()
|
|
150
|
+
.simulatorConfiguration = SimulatorConfiguration(
|
|
151
|
+
simulateReaderUpdate!!,
|
|
152
|
+
SimulatedCard(call.getString("simulatedCard", "VISA")!!),
|
|
153
|
+
call.getLong("simulatedTipAmount", null),
|
|
154
|
+
false
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
call.resolve()
|
|
159
|
+
} catch (ex: Exception) {
|
|
160
|
+
call.reject(ex.message)
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
fun onDiscoverReaders(call: PluginCall) {
|
|
165
|
+
if (ActivityCompat.checkSelfPermission(
|
|
166
|
+
contextSupplier.get(),
|
|
167
|
+
Manifest.permission.ACCESS_FINE_LOCATION
|
|
168
|
+
) !=
|
|
169
|
+
PackageManager.PERMISSION_GRANTED
|
|
170
|
+
) {
|
|
171
|
+
Log.d(this.logTag, "android.permission.ACCESS_FINE_LOCATION permission is not granted.")
|
|
172
|
+
call.reject("android.permission.ACCESS_FINE_LOCATION permission is not granted.")
|
|
173
|
+
return
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
this.locationId = call.getString("locationId")
|
|
177
|
+
val config: DiscoveryConfiguration
|
|
178
|
+
if (call.getString("type") == TerminalConnectTypes.TapToPay.webEventName) {
|
|
179
|
+
config = DiscoveryConfiguration.TapToPayDiscoveryConfiguration(this.isTest!!)
|
|
180
|
+
this.terminalConnectType = TerminalConnectTypes.TapToPay
|
|
181
|
+
} else if (call.getString("type") == TerminalConnectTypes.Internet.webEventName) {
|
|
182
|
+
config = DiscoveryConfiguration.InternetDiscoveryConfiguration(
|
|
183
|
+
0,
|
|
184
|
+
this.locationId,
|
|
185
|
+
this.isTest!!
|
|
186
|
+
)
|
|
187
|
+
this.terminalConnectType = TerminalConnectTypes.Internet
|
|
188
|
+
} else if (call.getString("type") == TerminalConnectTypes.Usb.webEventName) {
|
|
189
|
+
config = DiscoveryConfiguration.UsbDiscoveryConfiguration(0, this.isTest!!)
|
|
190
|
+
this.terminalConnectType = TerminalConnectTypes.Usb
|
|
191
|
+
} else if (call.getString("type") == TerminalConnectTypes.Bluetooth.webEventName || call.getString(
|
|
192
|
+
"type"
|
|
193
|
+
) == TerminalConnectTypes.Simulated.webEventName
|
|
194
|
+
) {
|
|
195
|
+
config = DiscoveryConfiguration.BluetoothDiscoveryConfiguration(0, this.isTest!!)
|
|
196
|
+
this.terminalConnectType = TerminalConnectTypes.Bluetooth
|
|
197
|
+
} else {
|
|
198
|
+
call.unimplemented(call.getString("type") + " is not support now")
|
|
199
|
+
return
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
discoveryCancelable = Terminal.getInstance()
|
|
203
|
+
.discoverReaders(
|
|
204
|
+
config,
|
|
205
|
+
object : DiscoveryListener {
|
|
206
|
+
override fun onUpdateDiscoveredReaders(readers: List<Reader>) {
|
|
207
|
+
Log.d(logTag, readers[0].serialNumber.toString())
|
|
208
|
+
discoveredReadersList = readers
|
|
209
|
+
val readersJSObject = JSArray()
|
|
210
|
+
|
|
211
|
+
val i = 0
|
|
212
|
+
for (reader in discoveredReadersList) {
|
|
213
|
+
readersJSObject.put(convertReaderInterface(reader).put("index", i.toString()))
|
|
214
|
+
}
|
|
215
|
+
notifyListeners(
|
|
216
|
+
TerminalEnumEvent.DiscoveredReaders.webEventName,
|
|
217
|
+
JSObject().put("readers", readersJSObject)
|
|
218
|
+
)
|
|
219
|
+
call.resolve(JSObject().put("readers", readersJSObject))
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
object : Callback {
|
|
223
|
+
override fun onSuccess() {
|
|
224
|
+
Log.d(logTag, "Finished discovering readers")
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
override fun onFailure(e: TerminalException) {
|
|
228
|
+
Log.d(logTag, e.localizedMessage)
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
)
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
fun connectReader(call: PluginCall) {
|
|
235
|
+
if (this.terminalConnectType == TerminalConnectTypes.TapToPay) {
|
|
236
|
+
this.connectTapToPayReader(call)
|
|
237
|
+
} else if (this.terminalConnectType == TerminalConnectTypes.Internet) {
|
|
238
|
+
this.connectInternetReader(call)
|
|
239
|
+
} else if (this.terminalConnectType == TerminalConnectTypes.Usb) {
|
|
240
|
+
this.connectUsbReader(call)
|
|
241
|
+
} else if (this.terminalConnectType == TerminalConnectTypes.Bluetooth) {
|
|
242
|
+
this.connectBluetoothReader(call)
|
|
243
|
+
} else {
|
|
244
|
+
call.reject("type is not defined.")
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
fun getConnectedReader(call: PluginCall) {
|
|
249
|
+
val reader: Reader? = Terminal.getInstance().connectedReader
|
|
250
|
+
if (reader == null) {
|
|
251
|
+
call.resolve(JSObject().put("reader", JSObject.NULL))
|
|
252
|
+
} else {
|
|
253
|
+
call.resolve(JSObject().put("reader", convertReaderInterface(reader)))
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
fun disconnectReader(call: PluginCall) {
|
|
258
|
+
if (Terminal.getInstance().connectedReader == null) {
|
|
259
|
+
call.resolve()
|
|
260
|
+
return
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
Terminal.getInstance()
|
|
264
|
+
.disconnectReader(
|
|
265
|
+
object : Callback {
|
|
266
|
+
override fun onSuccess() {
|
|
267
|
+
notifyListeners(
|
|
268
|
+
TerminalEnumEvent.DisconnectedReader.webEventName,
|
|
269
|
+
emptyObject
|
|
270
|
+
)
|
|
271
|
+
call.resolve()
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
override fun onFailure(e: TerminalException) {
|
|
275
|
+
call.reject(e.localizedMessage, e)
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
)
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
private fun connectTapToPayReader(call: PluginCall) {
|
|
282
|
+
val reader = call.getObject("reader")
|
|
283
|
+
val serialNumber = reader.getString("serialNumber")
|
|
284
|
+
this.locationId = call.getString("locationId", this.locationId)
|
|
285
|
+
|
|
286
|
+
val foundReader = this.findReader(this.discoveredReadersList, serialNumber)
|
|
287
|
+
|
|
288
|
+
if (serialNumber == null || foundReader == null) {
|
|
289
|
+
call.reject("The reader value is not set correctly.")
|
|
290
|
+
return
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
val autoReconnectOnUnexpectedDisconnect: Boolean = Objects.requireNonNullElse(
|
|
294
|
+
call.getBoolean("autoReconnectOnUnexpectedDisconnect", false),
|
|
295
|
+
false
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
val config: ConnectionConfiguration.TapToPayConnectionConfiguration = ConnectionConfiguration.TapToPayConnectionConfiguration(
|
|
299
|
+
this.locationId!!,
|
|
300
|
+
autoReconnectOnUnexpectedDisconnect,
|
|
301
|
+
this.tapToPayReaderListener
|
|
302
|
+
)
|
|
303
|
+
Terminal.getInstance().connectReader(foundReader, config, this.readerCallback(call))
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
var tapToPayReaderListener: TapToPayReaderListener = object : TapToPayReaderListener {
|
|
307
|
+
override fun onReaderReconnectFailed(reader: Reader) {
|
|
308
|
+
notifyListeners(
|
|
309
|
+
TerminalEnumEvent.ReaderReconnectFailed.webEventName,
|
|
310
|
+
JSObject().put("reader", convertReaderInterface(reader))
|
|
311
|
+
)
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
override fun onReaderReconnectStarted(
|
|
315
|
+
reader: Reader,
|
|
316
|
+
cancelReconnect: Cancelable,
|
|
317
|
+
reason: DisconnectReason
|
|
318
|
+
) {
|
|
319
|
+
cancelReaderConnectionCancellable = cancelReconnect
|
|
320
|
+
notifyListeners(
|
|
321
|
+
TerminalEnumEvent.ReaderReconnectStarted.webEventName,
|
|
322
|
+
JSObject().put("reason", reason.toString())
|
|
323
|
+
.put("reader", convertReaderInterface(reader))
|
|
324
|
+
)
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
override fun onReaderReconnectSucceeded(reader: Reader) {
|
|
328
|
+
notifyListeners(
|
|
329
|
+
TerminalEnumEvent.ReaderReconnectSucceeded.webEventName,
|
|
330
|
+
JSObject().put("reader", convertReaderInterface(reader))
|
|
331
|
+
)
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
override fun onDisconnect(reason: DisconnectReason) {
|
|
335
|
+
notifyListeners(
|
|
336
|
+
TerminalEnumEvent.DisconnectedReader.webEventName,
|
|
337
|
+
JSObject().put("reason", reason.toString())
|
|
338
|
+
)
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
var internetReaderListener: InternetReaderListener = object : InternetReaderListener {
|
|
343
|
+
override fun onDisconnect(reason: DisconnectReason) {
|
|
344
|
+
notifyListeners(
|
|
345
|
+
TerminalEnumEvent.DisconnectedReader.webEventName,
|
|
346
|
+
JSObject().put("reason", reason.toString())
|
|
347
|
+
)
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// ReaderReconnectionListener readerReconnectionListener = new ReaderReconnectionListener() {
|
|
352
|
+
// @Override
|
|
353
|
+
// public void onReaderReconnectStarted(@NonNull Reader reader, @NonNull Cancelable cancelable, @NonNull DisconnectReason reason) {
|
|
354
|
+
// cancelReaderConnectionCancellable = cancelable;
|
|
355
|
+
// notifyListeners(
|
|
356
|
+
// TerminalEnumEvent.ReaderReconnectStarted.getWebEventName(),
|
|
357
|
+
// new JSObject().put("reason", reason.toString()).put("reader", convertReaderInterface(reader))
|
|
358
|
+
// );
|
|
359
|
+
// }
|
|
360
|
+
//
|
|
361
|
+
// @Override
|
|
362
|
+
// public void onReaderReconnectSucceeded(@NonNull Reader reader) {
|
|
363
|
+
// notifyListeners(
|
|
364
|
+
// TerminalEnumEvent.ReaderReconnectSucceeded.getWebEventName(),
|
|
365
|
+
// new JSObject().put("reader", convertReaderInterface(reader))
|
|
366
|
+
// );
|
|
367
|
+
// }
|
|
368
|
+
//
|
|
369
|
+
// @Override
|
|
370
|
+
// public void onReaderReconnectFailed(@NonNull Reader reader) {
|
|
371
|
+
// notifyListeners(
|
|
372
|
+
// TerminalEnumEvent.ReaderReconnectFailed.getWebEventName(),
|
|
373
|
+
// new JSObject().put("reader", convertReaderInterface(reader))
|
|
374
|
+
// );
|
|
375
|
+
// }
|
|
376
|
+
// };
|
|
377
|
+
private fun connectInternetReader(call: PluginCall) {
|
|
378
|
+
val reader = call.getObject("reader")
|
|
379
|
+
val serialNumber = reader.getString("serialNumber")
|
|
380
|
+
this.locationId = call.getString("locationId", this.locationId)
|
|
381
|
+
|
|
382
|
+
val foundReader = this.findReader(this.discoveredReadersList, serialNumber)
|
|
383
|
+
|
|
384
|
+
if (serialNumber == null || foundReader == null) {
|
|
385
|
+
call.reject("The reader value is not set correctly.")
|
|
386
|
+
return
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
val config: ConnectionConfiguration.InternetConnectionConfiguration =
|
|
390
|
+
ConnectionConfiguration.InternetConnectionConfiguration(
|
|
391
|
+
true,
|
|
392
|
+
this.internetReaderListener
|
|
393
|
+
)
|
|
394
|
+
Terminal.getInstance().connectReader(foundReader, config, this.readerCallback(call))
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
private fun connectUsbReader(call: PluginCall) {
|
|
398
|
+
val reader = call.getObject("reader")
|
|
399
|
+
val serialNumber = reader.getString("serialNumber")
|
|
400
|
+
this.locationId = call.getString("locationId", this.locationId)
|
|
401
|
+
|
|
402
|
+
val foundReader = this.findReader(this.discoveredReadersList, serialNumber)
|
|
403
|
+
|
|
404
|
+
if (serialNumber == null || foundReader == null) {
|
|
405
|
+
call.reject("The reader value is not set correctly.")
|
|
406
|
+
return
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
val config: ConnectionConfiguration.UsbConnectionConfiguration =
|
|
410
|
+
ConnectionConfiguration.UsbConnectionConfiguration(
|
|
411
|
+
this.locationId!!,
|
|
412
|
+
true,
|
|
413
|
+
this.readerListener()
|
|
414
|
+
)
|
|
415
|
+
Terminal.getInstance().connectReader(foundReader, config, this.readerCallback(call))
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
private fun connectBluetoothReader(call: PluginCall) {
|
|
419
|
+
val reader = call.getObject("reader")
|
|
420
|
+
val serialNumber = reader.getString("serialNumber")
|
|
421
|
+
this.locationId = call.getString("locationId", this.locationId)
|
|
422
|
+
|
|
423
|
+
val foundReader = this.findReader(this.discoveredReadersList, serialNumber)
|
|
424
|
+
|
|
425
|
+
if (serialNumber == null || foundReader == null) {
|
|
426
|
+
call.reject("The reader value is not set correctly.")
|
|
427
|
+
return
|
|
428
|
+
}
|
|
429
|
+
val autoReconnectOnUnexpectedDisconnect: Boolean = Objects.requireNonNullElse(
|
|
430
|
+
call.getBoolean("autoReconnectOnUnexpectedDisconnect", false),
|
|
431
|
+
false
|
|
432
|
+
)
|
|
433
|
+
|
|
434
|
+
val config: ConnectionConfiguration.BluetoothConnectionConfiguration =
|
|
435
|
+
ConnectionConfiguration.BluetoothConnectionConfiguration(
|
|
436
|
+
this.locationId!!,
|
|
437
|
+
autoReconnectOnUnexpectedDisconnect,
|
|
438
|
+
this.readerListener()
|
|
439
|
+
)
|
|
440
|
+
Terminal.getInstance().connectReader(foundReader, config, this.readerCallback(call))
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
fun cancelDiscoverReaders(call: PluginCall) {
|
|
444
|
+
if (discoveryCancelable == null || discoveryCancelable!!.isCompleted) {
|
|
445
|
+
call.resolve()
|
|
446
|
+
return
|
|
447
|
+
}
|
|
448
|
+
discoveryCancelable!!.cancel(
|
|
449
|
+
object : Callback {
|
|
450
|
+
override fun onSuccess() {
|
|
451
|
+
notifyListeners(
|
|
452
|
+
TerminalEnumEvent.CancelDiscoveredReaders.webEventName,
|
|
453
|
+
emptyObject
|
|
454
|
+
)
|
|
455
|
+
call.resolve()
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
override fun onFailure(e: TerminalException) {
|
|
459
|
+
call.reject(e.localizedMessage, e)
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
)
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
fun collectPaymentMethod(call: PluginCall) {
|
|
466
|
+
val paymentIntent = call.getString("paymentIntent")
|
|
467
|
+
if (paymentIntent == null) {
|
|
468
|
+
call.reject("The value of paymentIntent is not set correctly.")
|
|
469
|
+
return
|
|
470
|
+
}
|
|
471
|
+
this.collectCall = call
|
|
472
|
+
Terminal.getInstance().retrievePaymentIntent(paymentIntent, createPaymentIntentCallback)
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
fun cancelCollectPaymentMethod(call: PluginCall) {
|
|
476
|
+
if (this.collectCancelable == null || collectCancelable!!.isCompleted) {
|
|
477
|
+
call.resolve()
|
|
478
|
+
return
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
collectCancelable!!.cancel(
|
|
482
|
+
object : Callback {
|
|
483
|
+
override fun onSuccess() {
|
|
484
|
+
notifyListeners(TerminalEnumEvent.Canceled.webEventName, emptyObject)
|
|
485
|
+
call.resolve()
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
override fun onFailure(e: TerminalException) {
|
|
489
|
+
call.reject(e.localizedMessage)
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
)
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
private val createPaymentIntentCallback: PaymentIntentCallback =
|
|
496
|
+
object : PaymentIntentCallback {
|
|
497
|
+
override fun onSuccess(paymentIntent: PaymentIntent) {
|
|
498
|
+
val collectConfig: CollectConfiguration =
|
|
499
|
+
CollectConfiguration.Builder().updatePaymentIntent(true).build()
|
|
500
|
+
collectCancelable = Terminal.getInstance().collectPaymentMethod(
|
|
501
|
+
paymentIntent,
|
|
502
|
+
collectPaymentMethodCallback,
|
|
503
|
+
collectConfig
|
|
504
|
+
)
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
override fun onFailure(exception: TerminalException) {
|
|
508
|
+
notifyListeners(TerminalEnumEvent.Failed.webEventName, emptyObject)
|
|
509
|
+
val returnObject = JSObject()
|
|
510
|
+
returnObject.put("message", exception.localizedMessage)
|
|
511
|
+
if (exception.apiError != null) {
|
|
512
|
+
returnObject.put("code", exception.apiError!!.code)
|
|
513
|
+
returnObject.put("declineCode", exception.apiError!!.declineCode)
|
|
514
|
+
}
|
|
515
|
+
collectCall!!.reject(exception.localizedMessage, null as String?, returnObject)
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
private val collectPaymentMethodCallback: PaymentIntentCallback =
|
|
520
|
+
object : PaymentIntentCallback {
|
|
521
|
+
override fun onSuccess(paymentIntent: PaymentIntent) {
|
|
522
|
+
paymentIntentInstance = paymentIntent
|
|
523
|
+
notifyListeners(TerminalEnumEvent.CollectedPaymentIntent.webEventName, emptyObject)
|
|
524
|
+
|
|
525
|
+
val pm = paymentIntent.paymentMethod
|
|
526
|
+
var card: CardPresentDetails? = null
|
|
527
|
+
|
|
528
|
+
if (pm != null) {
|
|
529
|
+
card =
|
|
530
|
+
if (pm.cardPresentDetails != null) pm.cardPresentDetails else pm.interacPresentDetails
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
if (card != null) {
|
|
534
|
+
collectCall!!.resolve(
|
|
535
|
+
JSObject()
|
|
536
|
+
.put("brand", card.brand)
|
|
537
|
+
.put("cardholderName", card.cardholderName)
|
|
538
|
+
.put("country", card.country)
|
|
539
|
+
.put("emvAuthData", card.emvAuthData)
|
|
540
|
+
.put("expMonth", card.expMonth)
|
|
541
|
+
.put("expYear", card.expYear)
|
|
542
|
+
.put("funding", card.funding)
|
|
543
|
+
.put("generatedCard", card.generatedCard)
|
|
544
|
+
.put(
|
|
545
|
+
"incrementalAuthorizationStatus",
|
|
546
|
+
card.incrementalAuthorizationStatus
|
|
547
|
+
)
|
|
548
|
+
.put("last4", card.last4)
|
|
549
|
+
.put("networks", card.networks)
|
|
550
|
+
.put("readMethod", card.readMethod)
|
|
551
|
+
)
|
|
552
|
+
} else {
|
|
553
|
+
collectCall!!.resolve()
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
override fun onFailure(e: TerminalException) {
|
|
558
|
+
notifyListeners(TerminalEnumEvent.Failed.webEventName, emptyObject)
|
|
559
|
+
var errorCode: String? = "generic_error"
|
|
560
|
+
if (e.apiError != null && e.apiError!!.code != null) {
|
|
561
|
+
errorCode = e.apiError!!.code
|
|
562
|
+
}
|
|
563
|
+
val returnObject = JSObject()
|
|
564
|
+
returnObject.put("message", e.localizedMessage)
|
|
565
|
+
if (e.apiError != null) {
|
|
566
|
+
returnObject.put("code", e.apiError!!.code)
|
|
567
|
+
returnObject.put("declineCode", e.apiError!!.declineCode)
|
|
568
|
+
}
|
|
569
|
+
collectCall!!.reject(e.localizedMessage, errorCode, returnObject)
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
fun confirmPaymentIntent(call: PluginCall) {
|
|
574
|
+
if (this.paymentIntentInstance == null) {
|
|
575
|
+
call.reject("PaymentIntent not found for confirmPaymentIntent. Use collect method first and try again.")
|
|
576
|
+
return
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
this.confirmPaymentIntentCall = call
|
|
580
|
+
Terminal.getInstance()
|
|
581
|
+
.confirmPaymentIntent(this.paymentIntentInstance!!, confirmPaymentMethodCallback)
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
fun installAvailableUpdate(call: PluginCall) {
|
|
585
|
+
Terminal.getInstance().installAvailableUpdate()
|
|
586
|
+
call.resolve(emptyObject)
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
fun cancelInstallUpdate(call: PluginCall) {
|
|
590
|
+
if (this.installUpdateCancelable == null || installUpdateCancelable!!.isCompleted) {
|
|
591
|
+
call.resolve()
|
|
592
|
+
return
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
installUpdateCancelable!!.cancel(
|
|
596
|
+
object : Callback {
|
|
597
|
+
override fun onSuccess() {
|
|
598
|
+
call.resolve()
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
override fun onFailure(e: TerminalException) {
|
|
602
|
+
call.reject(e.localizedMessage)
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
)
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
fun setReaderDisplay(call: PluginCall) {
|
|
609
|
+
val currency = call.getString("currency", null)
|
|
610
|
+
if (currency == null) {
|
|
611
|
+
call.reject("You must provide a currency value")
|
|
612
|
+
return
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
val tax: Int = call.getInt("tax", 0)!!
|
|
616
|
+
val total: Int = call.getInt("total", 0)!!
|
|
617
|
+
if (total == 0) {
|
|
618
|
+
call.reject("You must provide a total value")
|
|
619
|
+
return
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
val lineItems = call.getArray("lineItems")
|
|
623
|
+
val lineItemsList: List<JSONObject>
|
|
624
|
+
try {
|
|
625
|
+
lineItemsList = lineItems.toList()
|
|
626
|
+
} catch (e: JSONException) {
|
|
627
|
+
call.reject(e.localizedMessage)
|
|
628
|
+
return
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
val cartLineItems: MutableList<CartLineItem> = ArrayList()
|
|
632
|
+
for (item in lineItemsList) {
|
|
633
|
+
try {
|
|
634
|
+
val itemObj = JSObject.fromJSONObject(item)
|
|
635
|
+
cartLineItems.add(
|
|
636
|
+
CartLineItem.Builder(
|
|
637
|
+
Objects.requireNonNull(itemObj.getString("displayName")!!),
|
|
638
|
+
Objects.requireNonNull(itemObj.getInteger("quantity")!!),
|
|
639
|
+
Objects.requireNonNull(itemObj.getInteger("amount")!!).toLong()
|
|
640
|
+
).build()
|
|
641
|
+
)
|
|
642
|
+
} catch (e: JSONException) {
|
|
643
|
+
call.reject(e.localizedMessage)
|
|
644
|
+
return
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
val cart: Cart = Cart.Builder(currency, tax.toLong(), total.toLong(), cartLineItems).build()
|
|
649
|
+
|
|
650
|
+
Terminal.getInstance()
|
|
651
|
+
.setReaderDisplay(
|
|
652
|
+
cart,
|
|
653
|
+
object : Callback {
|
|
654
|
+
override fun onSuccess() {
|
|
655
|
+
call.resolve()
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
override fun onFailure(e: TerminalException) {
|
|
659
|
+
call.reject(e.errorMessage)
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
)
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
fun clearReaderDisplay(call: PluginCall) {
|
|
666
|
+
Terminal.getInstance()
|
|
667
|
+
.clearReaderDisplay(
|
|
668
|
+
object : Callback {
|
|
669
|
+
override fun onSuccess() {
|
|
670
|
+
call.resolve()
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
override fun onFailure(e: TerminalException) {
|
|
674
|
+
call.reject(e.errorMessage)
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
)
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
fun rebootReader(call: PluginCall) {
|
|
681
|
+
Terminal.getInstance()
|
|
682
|
+
.rebootReader(
|
|
683
|
+
object : Callback {
|
|
684
|
+
override fun onSuccess() {
|
|
685
|
+
paymentIntentInstance = null
|
|
686
|
+
call.resolve(emptyObject)
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
override fun onFailure(e: TerminalException) {
|
|
690
|
+
call.reject(e.localizedMessage)
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
)
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
fun cancelReaderReconnection(call: PluginCall) {
|
|
697
|
+
if (cancelReaderConnectionCancellable == null || cancelReaderConnectionCancellable!!.isCompleted) {
|
|
698
|
+
call.resolve()
|
|
699
|
+
return
|
|
700
|
+
}
|
|
701
|
+
cancelReaderConnectionCancellable!!.cancel(
|
|
702
|
+
object : Callback {
|
|
703
|
+
override fun onSuccess() {
|
|
704
|
+
call.resolve()
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
override fun onFailure(e: TerminalException) {
|
|
708
|
+
call.reject(e.localizedMessage, e)
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
)
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
private val confirmPaymentMethodCallback: PaymentIntentCallback =
|
|
715
|
+
object : PaymentIntentCallback {
|
|
716
|
+
override fun onSuccess(paymentIntent: PaymentIntent) {
|
|
717
|
+
notifyListeners(TerminalEnumEvent.ConfirmedPaymentIntent.webEventName, emptyObject)
|
|
718
|
+
paymentIntentInstance = null
|
|
719
|
+
confirmPaymentIntentCall!!.resolve()
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
override fun onFailure(e: TerminalException) {
|
|
723
|
+
notifyListeners(TerminalEnumEvent.Failed.webEventName, emptyObject)
|
|
724
|
+
val returnObject = JSObject()
|
|
725
|
+
returnObject.put("message", e.localizedMessage)
|
|
726
|
+
if (e.apiError != null) {
|
|
727
|
+
returnObject.put("code", e.apiError!!.code)
|
|
728
|
+
returnObject.put("declineCode", e.apiError!!.declineCode)
|
|
729
|
+
}
|
|
730
|
+
confirmPaymentIntentCall!!.reject(
|
|
731
|
+
e.localizedMessage,
|
|
732
|
+
null as String?,
|
|
733
|
+
returnObject
|
|
734
|
+
)
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
init {
|
|
739
|
+
this.contextSupplier = contextSupplier
|
|
740
|
+
this.discoveredReadersList = ArrayList()
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
private fun readerCallback(call: PluginCall): ReaderCallback {
|
|
744
|
+
return object : ReaderCallback {
|
|
745
|
+
override fun onSuccess(reader: Reader) {
|
|
746
|
+
notifyListeners(TerminalEnumEvent.ConnectedReader.webEventName, emptyObject)
|
|
747
|
+
call.resolve()
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
override fun onFailure(e: TerminalException) {
|
|
751
|
+
e.printStackTrace()
|
|
752
|
+
call.reject(e.localizedMessage, e)
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
private fun readerListener(): MobileReaderListener {
|
|
758
|
+
return object : MobileReaderListener {
|
|
759
|
+
override fun onStartInstallingUpdate(
|
|
760
|
+
update: ReaderSoftwareUpdate,
|
|
761
|
+
cancelable: Cancelable?
|
|
762
|
+
) {
|
|
763
|
+
// Show UI communicating that a required update has started installing
|
|
764
|
+
installUpdateCancelable = cancelable
|
|
765
|
+
notifyListeners(
|
|
766
|
+
TerminalEnumEvent.StartInstallingUpdate.webEventName,
|
|
767
|
+
JSObject().put("update", convertReaderSoftwareUpdate(update))
|
|
768
|
+
)
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
override fun onReportReaderSoftwareUpdateProgress(progress: Float) {
|
|
772
|
+
// Update the progress of the install
|
|
773
|
+
notifyListeners(
|
|
774
|
+
TerminalEnumEvent.ReaderSoftwareUpdateProgress.webEventName,
|
|
775
|
+
JSObject().put("progress", progress.toDouble())
|
|
776
|
+
)
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
override fun onFinishInstallingUpdate(
|
|
780
|
+
update: ReaderSoftwareUpdate?,
|
|
781
|
+
e: TerminalException?
|
|
782
|
+
) {
|
|
783
|
+
val eventObject = JSObject()
|
|
784
|
+
|
|
785
|
+
if (e != null) {
|
|
786
|
+
// note: Since errorCode cannot be obtained in iOS, use errorMessage for unification.
|
|
787
|
+
eventObject.put("error", e.localizedMessage)
|
|
788
|
+
notifyListeners(
|
|
789
|
+
TerminalEnumEvent.FinishInstallingUpdate.webEventName,
|
|
790
|
+
eventObject
|
|
791
|
+
)
|
|
792
|
+
return
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
eventObject.put(
|
|
796
|
+
"update",
|
|
797
|
+
if (update == null) null else convertReaderSoftwareUpdate(update)
|
|
798
|
+
)
|
|
799
|
+
notifyListeners(TerminalEnumEvent.FinishInstallingUpdate.webEventName, eventObject)
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
override fun onBatteryLevelUpdate(
|
|
803
|
+
batteryLevel: Float,
|
|
804
|
+
batteryStatus: BatteryStatus,
|
|
805
|
+
isCharging: Boolean
|
|
806
|
+
) {
|
|
807
|
+
notifyListeners(
|
|
808
|
+
TerminalEnumEvent.BatteryLevel.webEventName,
|
|
809
|
+
JSObject().put("level", batteryLevel.toDouble()).put("charging", isCharging)
|
|
810
|
+
.put("status", batteryStatus.toString())
|
|
811
|
+
)
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
override fun onReportLowBatteryWarning() {}
|
|
815
|
+
|
|
816
|
+
override fun onReportAvailableUpdate(update: ReaderSoftwareUpdate) {
|
|
817
|
+
// An update is available for the connected reader. Show this update in your application.
|
|
818
|
+
// This update can be installed using `Terminal.getInstance().installAvailableUpdate`.
|
|
819
|
+
notifyListeners(
|
|
820
|
+
TerminalEnumEvent.ReportAvailableUpdate.webEventName,
|
|
821
|
+
JSObject().put("update", convertReaderSoftwareUpdate(update))
|
|
822
|
+
)
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
override fun onReportReaderEvent(event: ReaderEvent) {
|
|
826
|
+
notifyListeners(
|
|
827
|
+
TerminalEnumEvent.ReaderEvent.webEventName,
|
|
828
|
+
JSObject().put("event", event.toString())
|
|
829
|
+
)
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
override fun onRequestReaderDisplayMessage(message: ReaderDisplayMessage) {
|
|
833
|
+
notifyListeners(
|
|
834
|
+
TerminalEnumEvent.RequestDisplayMessage.webEventName,
|
|
835
|
+
JSObject().put("messageType", message.name).put("message", message.toString())
|
|
836
|
+
)
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
override fun onRequestReaderInput(options: ReaderInputOptions) {
|
|
840
|
+
val optionsList: List<ReaderInputOptions.ReaderInputOption> = options.options
|
|
841
|
+
val jsOptions = JSArray()
|
|
842
|
+
for (optionType in optionsList) {
|
|
843
|
+
jsOptions.put(optionType.name)
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
notifyListeners(
|
|
847
|
+
TerminalEnumEvent.RequestReaderInput.webEventName,
|
|
848
|
+
JSObject().put("options", jsOptions).put("message", options.toString())
|
|
849
|
+
)
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
override fun onDisconnect(reason: DisconnectReason) {
|
|
853
|
+
notifyListeners(
|
|
854
|
+
TerminalEnumEvent.DisconnectedReader.webEventName,
|
|
855
|
+
JSObject().put("reason", reason.toString())
|
|
856
|
+
)
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
private fun convertReaderInterface(reader: Reader?): JSObject {
|
|
862
|
+
return JSObject()
|
|
863
|
+
.put("label", reader!!.label)
|
|
864
|
+
.put("serialNumber", reader.serialNumber)
|
|
865
|
+
.put("id", reader.id)
|
|
866
|
+
.put("locationId", if (reader.location != null) reader.location!!.id else null)
|
|
867
|
+
.put("deviceSoftwareVersion", reader.softwareVersion)
|
|
868
|
+
.put("simulated", reader.isSimulated)
|
|
869
|
+
.put("serialNumber", reader.serialNumber)
|
|
870
|
+
.put("ipAddress", reader.ipAddress)
|
|
871
|
+
.put("baseUrl", reader.baseUrl)
|
|
872
|
+
.put("bootloaderVersion", reader.bootloaderVersion)
|
|
873
|
+
.put("configVersion", reader.configVersion)
|
|
874
|
+
.put("emvKeyProfileId", reader.emvKeyProfileId)
|
|
875
|
+
.put("firmwareVersion", reader.firmwareVersion)
|
|
876
|
+
.put("hardwareVersion", reader.hardwareVersion)
|
|
877
|
+
.put("macKeyProfileId", reader.macKeyProfileId)
|
|
878
|
+
.put("pinKeyProfileId", reader.pinKeyProfileId)
|
|
879
|
+
.put("trackKeyProfileId", reader.trackKeyProfileId)
|
|
880
|
+
.put("settingsVersion", reader.settingsVersion)
|
|
881
|
+
.put("pinKeysetId", reader.pinKeysetId)
|
|
882
|
+
.put("deviceType", terminalMappers.mapFromDeviceType(reader.deviceType))
|
|
883
|
+
.put("status", terminalMappers.mapFromNetworkStatus(reader.networkStatus))
|
|
884
|
+
.put("locationStatus", terminalMappers.mapFromLocationStatus(reader.locationStatus))
|
|
885
|
+
.put(
|
|
886
|
+
"batteryLevel",
|
|
887
|
+
if (reader.batteryLevel != null) reader.batteryLevel!!.toDouble() else null
|
|
888
|
+
)
|
|
889
|
+
.put(
|
|
890
|
+
"availableUpdate",
|
|
891
|
+
terminalMappers.mapFromReaderSoftwareUpdate(reader.availableUpdate)
|
|
892
|
+
)
|
|
893
|
+
.put("location", terminalMappers.mapFromLocation(reader.location))
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
private fun convertReaderSoftwareUpdate(update: ReaderSoftwareUpdate): JSObject? {
|
|
897
|
+
return terminalMappers.mapFromReaderSoftwareUpdate(update)
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
private fun findReader(discoveredReadersList: List<Reader?>, serialNumber: String?): Reader? {
|
|
901
|
+
var foundReader: Reader? = null
|
|
902
|
+
foundReader = discoveredReadersList
|
|
903
|
+
.stream()
|
|
904
|
+
.filter { device: Reader? -> serialNumber != null && serialNumber == device!!.serialNumber }
|
|
905
|
+
.findFirst()
|
|
906
|
+
.orElse(null)
|
|
907
|
+
|
|
908
|
+
return foundReader
|
|
909
|
+
}
|
|
910
|
+
}
|