@capacitor-community/stripe-terminal 6.0.2 → 6.2.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 (36) hide show
  1. package/CapacitorCommunityStripeTerminal.podspec +1 -1
  2. package/README.md +767 -28
  3. package/android/build.gradle +1 -1
  4. package/android/src/main/java/com/getcapacitor/community/stripe/terminal/StripeTerminal.java +372 -51
  5. package/android/src/main/java/com/getcapacitor/community/stripe/terminal/StripeTerminalPlugin.java +61 -5
  6. package/android/src/main/java/com/getcapacitor/community/stripe/terminal/TerminalEvent.kt +14 -0
  7. package/android/src/main/java/com/getcapacitor/community/stripe/terminal/helper/TerminalMappers.java +96 -0
  8. package/dist/docs.json +1389 -111
  9. package/dist/esm/definitions.d.ts +263 -11
  10. package/dist/esm/definitions.js +1 -8
  11. package/dist/esm/definitions.js.map +1 -1
  12. package/dist/esm/events.enum.d.ts +15 -1
  13. package/dist/esm/events.enum.js +14 -0
  14. package/dist/esm/events.enum.js.map +1 -1
  15. package/dist/esm/stripe-types/proto.d.ts +501 -0
  16. package/dist/esm/stripe-types/proto.js +2 -0
  17. package/dist/esm/stripe-types/proto.js.map +1 -0
  18. package/dist/esm/stripe.enum.d.ts +154 -0
  19. package/dist/esm/stripe.enum.js +170 -0
  20. package/dist/esm/stripe.enum.js.map +1 -0
  21. package/dist/esm/terminalMappers.d.ts +23 -0
  22. package/dist/esm/terminalMappers.js +119 -0
  23. package/dist/esm/terminalMappers.js.map +1 -0
  24. package/dist/esm/web.d.ts +25 -2
  25. package/dist/esm/web.js +137 -13
  26. package/dist/esm/web.js.map +1 -1
  27. package/dist/plugin.cjs.js +428 -13
  28. package/dist/plugin.cjs.js.map +1 -1
  29. package/dist/plugin.js +429 -15
  30. package/dist/plugin.js.map +1 -1
  31. package/ios/Plugin/StripeTerminal.swift +345 -61
  32. package/ios/Plugin/StripeTerminalPlugin.m +7 -0
  33. package/ios/Plugin/StripeTerminalPlugin.swift +29 -4
  34. package/ios/Plugin/TerminalEvents.swift +14 -0
  35. package/ios/Plugin/TerminalMappers.swift +269 -0
  36. package/package.json +4 -1
@@ -7,7 +7,7 @@ ext {
7
7
  playServicesWalletVersion = project.hasProperty('playServicesWalletVersion') ? rootProject.ext.playServicesWalletVersion : '19.2.+'
8
8
  volleyVersion = project.hasProperty('volleyVersion') ? rootProject.ext.volleyVersion : '1.2.1'
9
9
  stripeterminalLocalmobileVersion = project.hasProperty('stripeterminalLocalmobileVersion') ? rootProject.ext.stripeterminalLocalmobileVersion : '3.5.+'
10
- stripeterminalCoreVersion = project.hasProperty('stripeterminalCoreVersion') ? rootProject.ext.stripeterminalCoreVersion : '3.7.+'
10
+ stripeterminalCoreVersion = project.hasProperty('stripeterminalCoreVersion') ? rootProject.ext.stripeterminalCoreVersion : '3.8.+'
11
11
  }
12
12
 
13
13
  buildscript {
@@ -14,6 +14,7 @@ import androidx.core.util.Supplier;
14
14
  import com.getcapacitor.JSArray;
15
15
  import com.getcapacitor.JSObject;
16
16
  import com.getcapacitor.PluginCall;
17
+ import com.getcapacitor.community.stripe.terminal.helper.TerminalMappers;
17
18
  import com.getcapacitor.community.stripe.terminal.models.Executor;
18
19
  import com.google.android.gms.common.util.BiConsumer;
19
20
  import com.stripe.stripeterminal.Terminal;
@@ -26,32 +27,50 @@ import com.stripe.stripeterminal.external.callable.ReaderCallback;
26
27
  import com.stripe.stripeterminal.external.callable.ReaderListener;
27
28
  import com.stripe.stripeterminal.external.callable.ReaderReconnectionListener;
28
29
  import com.stripe.stripeterminal.external.callable.TerminalListener;
30
+ import com.stripe.stripeterminal.external.models.BatteryStatus;
29
31
  import com.stripe.stripeterminal.external.models.CardPresentDetails;
32
+ import com.stripe.stripeterminal.external.models.Cart;
33
+ import com.stripe.stripeterminal.external.models.CartLineItem;
30
34
  import com.stripe.stripeterminal.external.models.CollectConfiguration;
31
35
  import com.stripe.stripeterminal.external.models.ConnectionConfiguration.BluetoothConnectionConfiguration;
32
36
  import com.stripe.stripeterminal.external.models.ConnectionConfiguration.InternetConnectionConfiguration;
33
37
  import com.stripe.stripeterminal.external.models.ConnectionConfiguration.LocalMobileConnectionConfiguration;
34
38
  import com.stripe.stripeterminal.external.models.ConnectionConfiguration.UsbConnectionConfiguration;
35
39
  import com.stripe.stripeterminal.external.models.ConnectionStatus;
40
+ import com.stripe.stripeterminal.external.models.DeviceType;
41
+ import com.stripe.stripeterminal.external.models.DisconnectReason;
36
42
  import com.stripe.stripeterminal.external.models.DiscoveryConfiguration;
43
+ import com.stripe.stripeterminal.external.models.Location;
44
+ import com.stripe.stripeterminal.external.models.LocationStatus;
37
45
  import com.stripe.stripeterminal.external.models.PaymentIntent;
38
46
  import com.stripe.stripeterminal.external.models.PaymentMethod;
39
47
  import com.stripe.stripeterminal.external.models.PaymentStatus;
40
48
  import com.stripe.stripeterminal.external.models.Reader;
49
+ import com.stripe.stripeterminal.external.models.ReaderDisplayMessage;
50
+ import com.stripe.stripeterminal.external.models.ReaderEvent;
51
+ import com.stripe.stripeterminal.external.models.ReaderInputOptions;
41
52
  import com.stripe.stripeterminal.external.models.ReaderSoftwareUpdate;
53
+ import com.stripe.stripeterminal.external.models.SimulateReaderUpdate;
54
+ import com.stripe.stripeterminal.external.models.SimulatedCard;
55
+ import com.stripe.stripeterminal.external.models.SimulatedCardType;
56
+ import com.stripe.stripeterminal.external.models.SimulatorConfiguration;
42
57
  import com.stripe.stripeterminal.external.models.TerminalException;
43
58
  import com.stripe.stripeterminal.log.LogLevel;
44
59
  import java.util.ArrayList;
45
60
  import java.util.List;
46
61
  import java.util.Objects;
47
62
  import org.jetbrains.annotations.NotNull;
63
+ import org.json.JSONException;
64
+ import org.json.JSONObject;
48
65
 
49
66
  public class StripeTerminal extends Executor {
50
67
 
51
68
  private TokenProvider tokenProvider;
52
69
  private Cancelable discoveryCancelable;
53
70
  private Cancelable collectCancelable;
54
- private List<Reader> readers;
71
+ private Cancelable installUpdateCancelable;
72
+ private Cancelable cancelReaderConnectionCancellable;
73
+ private List<Reader> discoveredReadersList;
55
74
  private String locationId;
56
75
  private PluginCall collectCall;
57
76
  private PluginCall confirmPaymentIntentCall;
@@ -60,6 +79,8 @@ public class StripeTerminal extends Executor {
60
79
  private TerminalConnectTypes terminalConnectType;
61
80
  private PaymentIntent paymentIntentInstance;
62
81
 
82
+ private final TerminalMappers terminalMappers = new TerminalMappers();
83
+
63
84
  public StripeTerminal(
64
85
  Supplier<Context> contextSupplier,
65
86
  Supplier<Activity> activitySupplier,
@@ -68,7 +89,7 @@ public class StripeTerminal extends Executor {
68
89
  ) {
69
90
  super(contextSupplier, activitySupplier, notifyListenersFunction, pluginLogTag, "StripeTerminalExecutor");
70
91
  this.contextSupplier = contextSupplier;
71
- this.readers = new ArrayList<>();
92
+ this.discoveredReadersList = new ArrayList<>();
72
93
  }
73
94
 
74
95
  public void initialize(final PluginCall call) throws TerminalException {
@@ -95,17 +116,23 @@ public class StripeTerminal extends Executor {
95
116
  TerminalListener listener = new TerminalListener() {
96
117
  @Override
97
118
  public void onUnexpectedReaderDisconnect(@NonNull Reader reader) {
98
- // TODO: Listenerを追加
119
+ notifyListeners(
120
+ TerminalEnumEvent.UnexpectedReaderDisconnect.getWebEventName(),
121
+ new JSObject().put("reader", convertReaderInterface(reader))
122
+ );
99
123
  }
100
124
 
101
125
  @Override
102
126
  public void onConnectionStatusChange(@NonNull ConnectionStatus status) {
103
- // TODO: Listenerを追加
127
+ notifyListeners(
128
+ TerminalEnumEvent.ConnectionStatusChange.getWebEventName(),
129
+ new JSObject().put("status", status.toString())
130
+ );
104
131
  }
105
132
 
106
133
  @Override
107
134
  public void onPaymentStatusChange(@NonNull PaymentStatus status) {
108
- // TODO: Listenerを追加
135
+ notifyListeners(TerminalEnumEvent.PaymentStatusChange.getWebEventName(), new JSObject().put("status", status.toString()));
109
136
  }
110
137
  };
111
138
  LogLevel logLevel = LogLevel.VERBOSE;
@@ -121,6 +148,24 @@ public class StripeTerminal extends Executor {
121
148
  this.tokenProvider.setConnectionToken(call);
122
149
  }
123
150
 
151
+ public void setSimulatorConfiguration(PluginCall call) {
152
+ try {
153
+ Terminal
154
+ .getInstance()
155
+ .setSimulatorConfiguration(
156
+ new SimulatorConfiguration(
157
+ SimulateReaderUpdate.valueOf(call.getString("update", "UPDATE_AVAILABLE")),
158
+ new SimulatedCard(SimulatedCardType.valueOf(call.getString("simulatedCard", "VISA"))),
159
+ call.getLong("simulatedTipAmount", null)
160
+ )
161
+ );
162
+
163
+ call.resolve();
164
+ } catch (Exception ex) {
165
+ call.reject(ex.getMessage());
166
+ }
167
+ }
168
+
124
169
  public void onDiscoverReaders(final PluginCall call) {
125
170
  if (
126
171
  ActivityCompat.checkSelfPermission(this.contextSupplier.get(), Manifest.permission.ACCESS_FINE_LOCATION) !=
@@ -156,12 +201,12 @@ public class StripeTerminal extends Executor {
156
201
  final DiscoveryListener discoveryListener = readers -> {
157
202
  // 検索したReaderの一覧をListenerで渡す
158
203
  Log.d(logTag, String.valueOf(readers.get(0).getSerialNumber()));
159
- this.readers = readers;
204
+ this.discoveredReadersList = readers;
160
205
  JSArray readersJSObject = new JSArray();
161
206
 
162
207
  int i = 0;
163
- for (Reader reader : this.readers) {
164
- readersJSObject.put(new JSObject().put("index", String.valueOf(i)).put("serialNumber", reader.getSerialNumber()));
208
+ for (Reader reader : this.discoveredReadersList) {
209
+ readersJSObject.put(convertReaderInterface(reader).put("index", String.valueOf(i)));
165
210
  }
166
211
  this.notifyListeners(TerminalEnumEvent.DiscoveredReaders.getWebEventName(), new JSObject().put("readers", readersJSObject));
167
212
  call.resolve(new JSObject().put("readers", readersJSObject));
@@ -205,7 +250,7 @@ public class StripeTerminal extends Executor {
205
250
  if (reader == null) {
206
251
  call.resolve(new JSObject().put("reader", JSObject.NULL));
207
252
  } else {
208
- call.resolve(new JSObject().put("reader", new JSObject().put("serialNumber", reader.getSerialNumber())));
253
+ call.resolve(new JSObject().put("reader", convertReaderInterface(reader)));
209
254
  }
210
255
  }
211
256
 
@@ -235,81 +280,125 @@ public class StripeTerminal extends Executor {
235
280
 
236
281
  private void connectLocalMobileReader(final PluginCall call) {
237
282
  JSObject reader = call.getObject("reader");
283
+ String serialNumber = reader.getString("serialNumber");
284
+
285
+ Reader foundReader =
286
+ this.discoveredReadersList.stream().filter(device -> serialNumber.equals(device.getSerialNumber())).findFirst().orElse(null);
238
287
 
239
- if (reader.getInteger("index") == null) {
288
+ if (serialNumber == null || foundReader == null) {
240
289
  call.reject("The reader value is not set correctly.");
241
290
  return;
242
291
  }
243
292
 
293
+ Boolean autoReconnectOnUnexpectedDisconnect = call.getBoolean("autoReconnectOnUnexpectedDisconnect", false);
294
+
244
295
  LocalMobileConnectionConfiguration config = new LocalMobileConnectionConfiguration(
245
296
  this.locationId,
246
- true,
247
- this.localMobileReaderReconnectionListener
297
+ autoReconnectOnUnexpectedDisconnect,
298
+ this.readerReconnectionListener
248
299
  );
249
- Terminal.getInstance().connectLocalMobileReader(this.readers.get(reader.getInteger("index")), config, this.readerCallback(call));
300
+ Terminal.getInstance().connectLocalMobileReader(foundReader, config, this.readerCallback(call));
250
301
  }
251
302
 
252
- ReaderReconnectionListener localMobileReaderReconnectionListener = new ReaderReconnectionListener() {
303
+ ReaderReconnectionListener readerReconnectionListener = new ReaderReconnectionListener() {
253
304
  @Override
254
- public void onReaderReconnectStarted(@NonNull Reader reader, @NonNull Cancelable cancelReconnect) {
255
- // 1. Notified at the start of a reconnection attempt
256
- // Use cancelable to stop reconnection at any time
305
+ public void onReaderReconnectStarted(@NonNull Reader reader, @NonNull Cancelable cancelable, @NonNull DisconnectReason reason) {
306
+ cancelReaderConnectionCancellable = cancelable;
307
+ notifyListeners(
308
+ TerminalEnumEvent.ReaderReconnectStarted.getWebEventName(),
309
+ new JSObject().put("reason", reason.toString()).put("reader", convertReaderInterface(reader))
310
+ );
257
311
  }
258
312
 
259
313
  @Override
260
314
  public void onReaderReconnectSucceeded(@NonNull Reader reader) {
261
- // 2. Notified when reader reconnection succeeds
262
- // App is now connected
315
+ notifyListeners(
316
+ TerminalEnumEvent.ReaderReconnectSucceeded.getWebEventName(),
317
+ new JSObject().put("reader", convertReaderInterface(reader))
318
+ );
263
319
  }
264
320
 
265
321
  @Override
266
322
  public void onReaderReconnectFailed(@NonNull Reader reader) {
267
- // 3. Notified when reader reconnection fails
268
- // App is now disconnected
323
+ notifyListeners(
324
+ TerminalEnumEvent.ReaderReconnectFailed.getWebEventName(),
325
+ new JSObject().put("reader", convertReaderInterface(reader))
326
+ );
269
327
  }
270
328
  };
271
329
 
272
330
  private void connectInternetReader(final PluginCall call) {
273
331
  JSObject reader = call.getObject("reader");
332
+ String serialNumber = reader.getString("serialNumber");
333
+
334
+ Reader foundReader =
335
+ this.discoveredReadersList.stream().filter(device -> serialNumber.equals(device.getSerialNumber())).findFirst().orElse(null);
336
+
337
+ if (serialNumber == null || foundReader == null) {
338
+ call.reject("The reader value is not set correctly.");
339
+ return;
340
+ }
341
+
274
342
  InternetConnectionConfiguration config = new InternetConnectionConfiguration();
275
- Terminal.getInstance().connectInternetReader(this.readers.get(reader.getInteger("index")), config, this.readerCallback(call));
343
+ Terminal.getInstance().connectInternetReader(foundReader, config, this.readerCallback(call));
276
344
  }
277
345
 
278
346
  private void connectUsbReader(final PluginCall call) {
279
347
  JSObject reader = call.getObject("reader");
348
+ String serialNumber = reader.getString("serialNumber");
349
+
350
+ Reader foundReader =
351
+ this.discoveredReadersList.stream().filter(device -> serialNumber.equals(device.getSerialNumber())).findFirst().orElse(null);
352
+
353
+ if (serialNumber == null || foundReader == null) {
354
+ call.reject("The reader value is not set correctly.");
355
+ return;
356
+ }
357
+
280
358
  UsbConnectionConfiguration config = new UsbConnectionConfiguration(this.locationId);
281
- Terminal
282
- .getInstance()
283
- .connectUsbReader(this.readers.get(reader.getInteger("index")), config, this.readerListener(), this.readerCallback(call));
359
+ Terminal.getInstance().connectUsbReader(foundReader, config, this.readerListener(), this.readerCallback(call));
284
360
  }
285
361
 
286
362
  private void connectBluetoothReader(final PluginCall call) {
287
363
  JSObject reader = call.getObject("reader");
288
- BluetoothConnectionConfiguration config = new BluetoothConnectionConfiguration(this.locationId);
289
- Terminal
290
- .getInstance()
291
- .connectBluetoothReader(this.readers.get(reader.getInteger("index")), config, this.readerListener(), this.readerCallback(call));
364
+ String serialNumber = reader.getString("serialNumber");
365
+
366
+ Reader foundReader =
367
+ this.discoveredReadersList.stream().filter(device -> serialNumber.equals(device.getSerialNumber())).findFirst().orElse(null);
368
+
369
+ if (serialNumber == null || foundReader == null) {
370
+ call.reject("The reader value is not set correctly.");
371
+ return;
372
+ }
373
+ Boolean autoReconnectOnUnexpectedDisconnect = call.getBoolean("autoReconnectOnUnexpectedDisconnect", false);
374
+
375
+ BluetoothConnectionConfiguration config = new BluetoothConnectionConfiguration(
376
+ this.locationId,
377
+ autoReconnectOnUnexpectedDisconnect,
378
+ this.readerReconnectionListener
379
+ );
380
+ Terminal.getInstance().connectBluetoothReader(foundReader, config, this.readerListener(), this.readerCallback(call));
292
381
  }
293
382
 
294
383
  public void cancelDiscoverReaders(final PluginCall call) {
295
- if (discoveryCancelable != null) {
296
- discoveryCancelable.cancel(
297
- new Callback() {
298
- @Override
299
- public void onSuccess() {
300
- notifyListeners(TerminalEnumEvent.CancelDiscoveredReaders.getWebEventName(), emptyObject);
301
- call.resolve();
302
- }
303
-
304
- @Override
305
- public void onFailure(@NonNull TerminalException ex) {
306
- call.reject(ex.getLocalizedMessage(), ex);
307
- }
308
- }
309
- );
310
- } else {
384
+ if (discoveryCancelable == null || discoveryCancelable.isCompleted()) {
311
385
  call.resolve();
386
+ return;
312
387
  }
388
+ discoveryCancelable.cancel(
389
+ new Callback() {
390
+ @Override
391
+ public void onSuccess() {
392
+ notifyListeners(TerminalEnumEvent.CancelDiscoveredReaders.getWebEventName(), emptyObject);
393
+ call.resolve();
394
+ }
395
+
396
+ @Override
397
+ public void onFailure(@NonNull TerminalException ex) {
398
+ call.reject(ex.getLocalizedMessage(), ex);
399
+ }
400
+ }
401
+ );
313
402
  }
314
403
 
315
404
  public void collectPaymentMethod(final PluginCall call) {
@@ -331,14 +420,13 @@ public class StripeTerminal extends Executor {
331
420
  new Callback() {
332
421
  @Override
333
422
  public void onSuccess() {
334
- collectCancelable = null;
335
423
  notifyListeners(TerminalEnumEvent.Canceled.getWebEventName(), emptyObject);
336
424
  call.resolve();
337
425
  }
338
426
 
339
427
  @Override
340
428
  public void onFailure(@NonNull TerminalException e) {
341
- call.reject(e.getErrorMessage());
429
+ call.reject(e.getLocalizedMessage());
342
430
  }
343
431
  }
344
432
  );
@@ -361,7 +449,6 @@ public class StripeTerminal extends Executor {
361
449
  private final PaymentIntentCallback collectPaymentMethodCallback = new PaymentIntentCallback() {
362
450
  @Override
363
451
  public void onSuccess(PaymentIntent paymentIntent) {
364
- collectCancelable = null;
365
452
  paymentIntentInstance = paymentIntent;
366
453
  notifyListeners(TerminalEnumEvent.CollectedPaymentIntent.getWebEventName(), emptyObject);
367
454
 
@@ -391,7 +478,6 @@ public class StripeTerminal extends Executor {
391
478
 
392
479
  @Override
393
480
  public void onFailure(@NonNull TerminalException ex) {
394
- collectCancelable = null;
395
481
  notifyListeners(TerminalEnumEvent.Failed.getWebEventName(), emptyObject);
396
482
  collectCall.reject(ex.getLocalizedMessage(), ex);
397
483
  }
@@ -407,6 +493,149 @@ public class StripeTerminal extends Executor {
407
493
  Terminal.getInstance().confirmPaymentIntent(this.paymentIntentInstance, confirmPaymentMethodCallback);
408
494
  }
409
495
 
496
+ public void installAvailableUpdate(final PluginCall call) {
497
+ Terminal.getInstance().installAvailableUpdate();
498
+ call.resolve(emptyObject);
499
+ }
500
+
501
+ public void cancelInstallUpdate(final PluginCall call) {
502
+ if (this.installUpdateCancelable == null || this.installUpdateCancelable.isCompleted()) {
503
+ call.resolve();
504
+ return;
505
+ }
506
+
507
+ this.installUpdateCancelable.cancel(
508
+ new Callback() {
509
+ @Override
510
+ public void onSuccess() {
511
+ call.resolve();
512
+ }
513
+
514
+ @Override
515
+ public void onFailure(@NonNull TerminalException e) {
516
+ call.reject(e.getLocalizedMessage());
517
+ }
518
+ }
519
+ );
520
+ }
521
+
522
+ public void setReaderDisplay(final PluginCall call) {
523
+ String currency = call.getString("currency", null);
524
+ if (currency == null) {
525
+ call.reject("You must provide a currency value");
526
+ return;
527
+ }
528
+
529
+ int tax = call.getInt("tax", 0);
530
+ int total = call.getInt("total", 0);
531
+ if (total == 0) {
532
+ call.reject("You must provide a total value");
533
+ return;
534
+ }
535
+
536
+ JSArray lineItems = call.getArray("lineItems");
537
+ List<JSONObject> lineItemsList;
538
+ try {
539
+ lineItemsList = lineItems.toList();
540
+ } catch (JSONException e) {
541
+ call.reject(e.getLocalizedMessage());
542
+ return;
543
+ }
544
+
545
+ List<CartLineItem> cartLineItems = new ArrayList<>();
546
+ for (JSONObject item : lineItemsList) {
547
+ try {
548
+ JSObject itemObj = JSObject.fromJSONObject(item);
549
+ cartLineItems.add(
550
+ new CartLineItem(
551
+ Objects.requireNonNull(itemObj.getString("displayName")),
552
+ Objects.requireNonNull(itemObj.getInteger("quantity")),
553
+ Objects.requireNonNull(itemObj.getInteger("amount"))
554
+ )
555
+ );
556
+ } catch (JSONException e) {
557
+ call.reject(e.getLocalizedMessage());
558
+ return;
559
+ }
560
+ }
561
+
562
+ Cart cart = new Cart.Builder(currency, tax, total, cartLineItems).build();
563
+
564
+ Terminal
565
+ .getInstance()
566
+ .setReaderDisplay(
567
+ cart,
568
+ new Callback() {
569
+ @Override
570
+ public void onSuccess() {
571
+ call.resolve();
572
+ }
573
+
574
+ @Override
575
+ public void onFailure(@NonNull TerminalException e) {
576
+ call.reject(e.getErrorMessage());
577
+ }
578
+ }
579
+ );
580
+ }
581
+
582
+ public void clearReaderDisplay(final PluginCall call) {
583
+ Terminal
584
+ .getInstance()
585
+ .clearReaderDisplay(
586
+ new Callback() {
587
+ @Override
588
+ public void onSuccess() {
589
+ call.resolve();
590
+ }
591
+
592
+ @Override
593
+ public void onFailure(@NonNull TerminalException e) {
594
+ call.reject(e.getErrorMessage());
595
+ }
596
+ }
597
+ );
598
+ }
599
+
600
+ public void rebootReader(final PluginCall call) {
601
+ Terminal
602
+ .getInstance()
603
+ .rebootReader(
604
+ new Callback() {
605
+ @Override
606
+ public void onSuccess() {
607
+ paymentIntentInstance = null;
608
+ call.resolve(emptyObject);
609
+ }
610
+
611
+ @Override
612
+ public void onFailure(@NonNull TerminalException e) {
613
+ call.reject(e.getLocalizedMessage());
614
+ }
615
+ }
616
+ );
617
+ }
618
+
619
+ public void cancelReaderReconnection(final PluginCall call) {
620
+ if (cancelReaderConnectionCancellable == null || cancelReaderConnectionCancellable.isCompleted()) {
621
+ call.resolve();
622
+ return;
623
+ }
624
+ cancelReaderConnectionCancellable.cancel(
625
+ new Callback() {
626
+ @Override
627
+ public void onSuccess() {
628
+ call.resolve();
629
+ }
630
+
631
+ @Override
632
+ public void onFailure(@NonNull TerminalException ex) {
633
+ call.reject(ex.getLocalizedMessage(), ex);
634
+ }
635
+ }
636
+ );
637
+ }
638
+
410
639
  private final PaymentIntentCallback confirmPaymentMethodCallback = new PaymentIntentCallback() {
411
640
  @Override
412
641
  public void onSuccess(PaymentIntent paymentIntent) {
@@ -443,16 +672,40 @@ public class StripeTerminal extends Executor {
443
672
  @Override
444
673
  public void onStartInstallingUpdate(@NotNull ReaderSoftwareUpdate update, @NotNull Cancelable cancelable) {
445
674
  // Show UI communicating that a required update has started installing
675
+ installUpdateCancelable = cancelable;
676
+ notifyListeners(
677
+ TerminalEnumEvent.StartInstallingUpdate.getWebEventName(),
678
+ new JSObject().put("update", convertReaderSoftwareUpdate(update))
679
+ );
446
680
  }
447
681
 
448
682
  @Override
449
683
  public void onReportReaderSoftwareUpdateProgress(float progress) {
450
684
  // Update the progress of the install
685
+ notifyListeners(TerminalEnumEvent.ReaderSoftwareUpdateProgress.getWebEventName(), new JSObject().put("progress", progress));
686
+ }
687
+
688
+ @Override
689
+ public void onFinishInstallingUpdate(@Nullable ReaderSoftwareUpdate update, @Nullable TerminalException error) {
690
+ JSObject eventObject = new JSObject();
691
+
692
+ if (error != null) {
693
+ // note: Since errorCode cannot be obtained in iOS, use errorMessage for unification.
694
+ eventObject.put("error", error.getLocalizedMessage());
695
+ notifyListeners(TerminalEnumEvent.FinishInstallingUpdate.getWebEventName(), eventObject);
696
+ return;
697
+ }
698
+
699
+ eventObject.put("update", update == null ? null : convertReaderSoftwareUpdate(update));
700
+ notifyListeners(TerminalEnumEvent.FinishInstallingUpdate.getWebEventName(), eventObject);
451
701
  }
452
702
 
453
703
  @Override
454
- public void onFinishInstallingUpdate(@Nullable ReaderSoftwareUpdate update, @Nullable TerminalException e) {
455
- // Report success or failure of the update
704
+ public void onBatteryLevelUpdate(float batteryLevel, @NonNull BatteryStatus batteryStatus, boolean isCharging) {
705
+ notifyListeners(
706
+ TerminalEnumEvent.BatteryLevel.getWebEventName(),
707
+ new JSObject().put("level", batteryLevel).put("charging", isCharging).put("status", batteryStatus.toString())
708
+ );
456
709
  }
457
710
 
458
711
  @Override
@@ -462,7 +715,75 @@ public class StripeTerminal extends Executor {
462
715
  public void onReportAvailableUpdate(@NotNull ReaderSoftwareUpdate update) {
463
716
  // An update is available for the connected reader. Show this update in your application.
464
717
  // This update can be installed using `Terminal.getInstance().installAvailableUpdate`.
718
+ notifyListeners(
719
+ TerminalEnumEvent.ReportAvailableUpdate.getWebEventName(),
720
+ new JSObject().put("update", convertReaderSoftwareUpdate(update))
721
+ );
722
+ }
723
+
724
+ @Override
725
+ public void onReportReaderEvent(@NotNull ReaderEvent event) {
726
+ notifyListeners(TerminalEnumEvent.ReaderEvent.getWebEventName(), new JSObject().put("event", event.toString()));
727
+ }
728
+
729
+ @Override
730
+ public void onRequestReaderDisplayMessage(@NotNull ReaderDisplayMessage message) {
731
+ notifyListeners(
732
+ TerminalEnumEvent.RequestDisplayMessage.getWebEventName(),
733
+ new JSObject().put("messageType", message.name()).put("message", message.toString())
734
+ );
735
+ }
736
+
737
+ @Override
738
+ public void onRequestReaderInput(@NotNull ReaderInputOptions options) {
739
+ List<ReaderInputOptions.ReaderInputOption> optionsList = options.getOptions();
740
+ JSArray jsOptions = new JSArray();
741
+ for (ReaderInputOptions.ReaderInputOption optionType : optionsList) {
742
+ jsOptions.put(optionType.name());
743
+ }
744
+
745
+ notifyListeners(
746
+ TerminalEnumEvent.RequestReaderInput.getWebEventName(),
747
+ new JSObject().put("options", jsOptions).put("message", options.toString())
748
+ );
749
+ }
750
+
751
+ public void onDisconnect(@NotNull DisconnectReason reason) {
752
+ notifyListeners(TerminalEnumEvent.DisconnectedReader.getWebEventName(), new JSObject().put("reason", reason.toString()));
465
753
  }
466
754
  };
467
755
  }
756
+
757
+ private JSObject convertReaderInterface(Reader reader) {
758
+ return new JSObject()
759
+ .put("label", reader.getLabel())
760
+ .put("serialNumber", reader.getSerialNumber())
761
+ .put("id", reader.getId())
762
+ .put("locationId", reader.getLocation() != null ? reader.getLocation().getId() : null)
763
+ .put("deviceSoftwareVersion", reader.getDeviceSwVersion$external_publish())
764
+ .put("simulated", reader.isSimulated())
765
+ .put("serialNumber", reader.getSerialNumber())
766
+ .put("ipAddress", reader.getIpAddress())
767
+ .put("baseUrl", reader.getBaseUrl())
768
+ .put("bootloaderVersion", reader.getBootloaderVersion())
769
+ .put("configVersion", reader.getConfigVersion())
770
+ .put("emvKeyProfileId", reader.getEmvKeyProfileId())
771
+ .put("firmwareVersion", reader.getFirmwareVersion())
772
+ .put("hardwareVersion", reader.getHardwareVersion())
773
+ .put("macKeyProfileId", reader.getMacKeyProfileId())
774
+ .put("pinKeyProfileId", reader.getPinKeyProfileId())
775
+ .put("trackKeyProfileId", reader.getTrackKeyProfileId())
776
+ .put("settingsVersion", reader.getSettingsVersion())
777
+ .put("pinKeysetId", reader.getPinKeysetId())
778
+ .put("deviceType", terminalMappers.mapFromDeviceType(reader.getDeviceType()))
779
+ .put("status", terminalMappers.mapFromNetworkStatus(reader.getNetworkStatus()))
780
+ .put("locationStatus", terminalMappers.mapFromLocationStatus(reader.getLocationStatus()))
781
+ .put("batteryLevel", reader.getBatteryLevel() != null ? reader.getBatteryLevel().doubleValue() : null)
782
+ .put("availableUpdate", terminalMappers.mapFromReaderSoftwareUpdate(reader.getAvailableUpdate()))
783
+ .put("location", terminalMappers.mapFromLocation(reader.getLocation()));
784
+ }
785
+
786
+ private JSObject convertReaderSoftwareUpdate(ReaderSoftwareUpdate update) {
787
+ return terminalMappers.mapFromReaderSoftwareUpdate(update);
788
+ }
468
789
  }