Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(stripe_terminal): updated package to full support sdk v. 3.4.0 #59

Merged
merged 1 commit into from
Mar 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions stripe_terminal/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@
- chore: Bumped [Android](https://github.com/stripe/stripe-terminal-android/blob/master/CHANGELOG.md#340---2024-03-04)
and [IOS](https://github.com/stripe/stripe-terminal-ios/blob/master/CHANGELOG.md#340-2024-03-04) sdks versions to `3.4.0`
- refactor: Renamed `TerminalExceptionCode.bluetoothConnectionFailedBatteryCriticallyLow` to `TerminalExceptionCode.readerBatteryCriticallyLow`
- feat: Added new `TerminalExceptionCode.readerMissingEncryptionKeys`. Returned in a rare condition
where the reader is missing the required keys to encrypt payment method data. The reader will
disconnect if this error is hit. Reconnecting to the reader should re-install the keys.
- feat: Added a `DisconnectReason` to the `ReaderReconnectionDelegate.onReaderReconnectStarted2` callback.
- build(android): Increased the minimum API version requirement to 30 (Android 11).
- build(android): SDKs have been updated to depend on [Kotlin 1.9.10](https://github.com/JetBrains/kotlin/releases/tag/v1.9.10).
- build(ios): The SDK now requires that a `NSBluetoothAlwaysUsageDescription` key be present in your
app's Info.plist instead of a `NSBluetoothPeripheralUsageDescription` key.

## 3.2.1
- chore: Bumped [Android](https://github.com/stripe/stripe-terminal-android/blob/master/CHANGELOG.md#321---2023-12-18)
Expand Down
21 changes: 20 additions & 1 deletion stripe_terminal/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,20 @@
- Location permissions will continue to be required for all [`DiscoveryConfigurations`](https://stripe.dev/stripe-terminal-android/external/com.stripe.stripeterminal.external.models/-discovery-configuration/index.html). Location services will also need to be enabled on the device at the time of discovery.
- (Not exist on ios) `Reader.device` has been removed and replaced with [`Reader.bluetoothDevice`](https://stripe.dev/stripe-terminal-android/external/com.stripe.stripeterminal.external.models/-reader/bluetooth-device.html) and [`Reader.usbDevice`](https://stripe.dev/stripe-terminal-android/external/com.stripe.stripeterminal.external.models/-reader/usb-device.html).

#### 3.4.0 - 2024-03-04

- Update: The [`Terminal.collectInputs`](https://stripe.com/docs/terminal/features/collect-inputs) method can now display optional toggles in each form.

#### 3.3.0 - 2024-01-30

- Beta: Added a [`Terminal.collectInputs`](https://stripe.com/docs/terminal/features/collect-inputs) method to display forms and collect information from customers. It requires the use of a new `@OptIn` annotation; `@CollectInputs`. Note that this feature is in beta.
- If you are interested in joining this beta, please email [email protected]
- Beta: Added support for retrieving and updating reader settings on WisePOS E and Stripe S700 by calling [`Terminal.getReaderSettings`](https://stripe.dev/stripe-terminal-android/core/com.stripe.stripeterminal/-terminal/get-reader-settings.html) and [`Terminal.setReaderSettings`](https://stripe.dev/stripe-terminal-android/core/com.stripe.stripeterminal/-terminal/set-reader-settings.html). Accessibility settings are provided at this time, allowing text-to-speech via speakers to be turned on and off as needed.
- If you are interested in joining this beta, please email [email protected]
- _Note: this feature requires [reader software version](https://stripe.com/docs/terminal/readers/bbpos-wisepos-e#reader-software-version) `2.20` or later to be installed on your reader._


### Ready
- Feat: Added support to `Terminal.updateSimulatorConfiguration`

### In progress

Expand All @@ -28,6 +40,13 @@
* New: Private beta support for offline payments.
* See [Collect payments while offline](https://stripe.com/docs/terminal/features/operate-offline/collect-payments) for details.

#### 3.3.0 2024-02-02
* New: Added support for retrieving and updating reader settings on WisePOS E and Stripe S700 by calling `retrieveReaderSettings` and `setReaderSettings` on `SCPTerminal`.
* Beta: Accessibility settings are provided at this time, allowing text-to-speech via speakers to be turned on and off as needed.
* Please [contact us](mailto:[email protected]) if you are interested in joining this beta.
* Beta: Added a [`collectInputs`](https://stripe.com/docs/terminal/features/collect-inputs) method to display forms and collect information from customers.
* If you are interested in joining this beta, please email [email protected].

### Ready

### In progress
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,13 +201,16 @@ class TerminalPlugin : FlutterPlugin, ActivityAware, TerminalPlatformApi {
override fun onConnectMobileReader(
result: Result<ReaderApi>,
serialNumber: String,
locationId: String
locationId: String,
autoReconnectOnUnexpectedDisconnect: Boolean
) {
val reader = findActiveReader(serialNumber)

val config =
ConnectionConfiguration.LocalMobileConnectionConfiguration(
locationId = locationId
locationId = locationId,
autoReconnectOnUnexpectedDisconnect = autoReconnectOnUnexpectedDisconnect,
localMobileReaderReconnectionListener = readerReconnectionDelegate
)
terminal.connectLocalMobileReader(
reader,
Expand Down Expand Up @@ -285,6 +288,14 @@ class TerminalPlugin : FlutterPlugin, ActivityAware, TerminalPlatformApi {
)
}

override fun onRebootReader(result: Result<Unit>) {
terminal.rebootReader(
object : TerminalErrorHandler(result::error), Callback {
override fun onSuccess() = result.success(Unit)
}
)
}

override fun onDisconnectReader(result: Result<Unit>) {
terminal.disconnectReader(
object : TerminalErrorHandler(result::error), Callback {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ interface TerminalPlatformApi {
result: Result<ReaderApi>,
serialNumber: String,
locationId: String,
autoReconnectOnUnexpectedDisconnect: Boolean,
)

fun onConnectUsbReader(
Expand Down Expand Up @@ -117,6 +118,10 @@ interface TerminalPlatformApi {
result: Result<Unit>,
)

fun onRebootReader(
result: Result<Unit>,
)

fun onDisconnectReader(
result: Result<Unit>,
)
Expand Down Expand Up @@ -272,7 +277,7 @@ interface TerminalPlatformApi {
}
"connectMobileReader" -> {
val res = Result<ReaderApi>(result) { it.serialize() }
onConnectMobileReader(res, args[0] as String, args[1] as String)
onConnectMobileReader(res, args[0] as String, args[1] as String, args[2] as Boolean)
}
"connectUsbReader" -> {
val res = Result<ReaderApi>(result) { it.serialize() }
Expand All @@ -298,6 +303,10 @@ interface TerminalPlatformApi {
val res = Result<Unit>(result) { null }
onCancelReaderUpdate(res)
}
"rebootReader" -> {
val res = Result<Unit>(result) { null }
onRebootReader(res)
}
"disconnectReader" -> {
val res = Result<Unit>(result) { null }
onDisconnectReader(res)
Expand Down Expand Up @@ -522,6 +531,12 @@ class TerminalHandlersApi(
channel.invokeMethod("_onReaderFinishInstallingUpdate", listOf<Any?>(update?.serialize(), exception?.serialize()))
}

fun disconnect(
reason: DisconnectReasonApi,
) {
channel.invokeMethod("_onDisconnect", listOf<Any?>(reason.ordinal))
}

fun readerReconnectFailed(
reader: ReaderApi,
) {
Expand All @@ -530,8 +545,9 @@ class TerminalHandlersApi(

fun readerReconnectStarted(
reader: ReaderApi,
reason: DisconnectReasonApi,
) {
channel.invokeMethod("_onReaderReconnectStarted", listOf<Any?>(reader.serialize()))
channel.invokeMethod("_onReaderReconnectStarted", listOf<Any?>(reader.serialize(), reason.ordinal))
}

fun readerReconnectSucceeded(
Expand Down Expand Up @@ -761,6 +777,10 @@ enum class DeviceTypeApi {
CHIPPER1_X, CHIPPER2_X, STRIPE_M2, COTS_DEVICE, VERIFONE_P400, WISE_CUBE, WISE_PAD3, WISE_PAD3S, WISE_POS_E, WISE_POS_E_DEVKIT, ETNA, STRIPE_S700, STRIPE_S700_DEVKIT, APPLE_BUILT_IN;
}

enum class DisconnectReasonApi {
UNKNOWN, DISCONNECT_REQUESTED, REBOOT_REQUESTED, SECURITY_REBOOT, CRITICALLY_LOW_BATTERY, POWERED_OFF, BLUETOOTH_DISABLED;
}

sealed class DiscoveryConfigurationApi {
companion object {
fun deserialize(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package mek.stripeterminal.mappings

import com.stripe.stripeterminal.external.models.DisconnectReason
import mek.stripeterminal.api.DisconnectReasonApi

fun DisconnectReason.toApi(): DisconnectReasonApi {
return when (this) {
DisconnectReason.UNKNOWN -> DisconnectReasonApi.UNKNOWN
DisconnectReason.DISCONNECT_REQUESTED -> DisconnectReasonApi.DISCONNECT_REQUESTED
DisconnectReason.REBOOT_REQUESTED -> DisconnectReasonApi.REBOOT_REQUESTED
DisconnectReason.SECURITY_REBOOT -> DisconnectReasonApi.SECURITY_REBOOT
DisconnectReason.CRITICALLY_LOW_BATTERY -> DisconnectReasonApi.CRITICALLY_LOW_BATTERY
DisconnectReason.POWERED_OFF -> DisconnectReasonApi.POWERED_OFF
DisconnectReason.BLUETOOTH_DISABLED -> DisconnectReasonApi.BLUETOOTH_DISABLED
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import mek.stripeterminal.toHashMap
fun PaymentIntent.toApi(): PaymentIntentApi {
return PaymentIntentApi(
id = id!!,
created = created,
created = created * 1000,
status = status!!.toApi(),
amount = amount.toDouble(),
captureMethod = when (captureMethod!!) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.stripe.stripeterminal.external.callable.Cancelable
import com.stripe.stripeterminal.external.callable.HandoffReaderListener
import com.stripe.stripeterminal.external.callable.ReaderListener
import com.stripe.stripeterminal.external.models.BatteryStatus
import com.stripe.stripeterminal.external.models.DisconnectReason
import com.stripe.stripeterminal.external.models.ReaderDisplayMessage
import com.stripe.stripeterminal.external.models.ReaderEvent
import com.stripe.stripeterminal.external.models.ReaderInputOptions
Expand Down Expand Up @@ -64,4 +65,8 @@ class ReaderDelegatePlugin(private val _handlers: TerminalHandlersApi) :
cancelUpdate = null
_handlers.readerFinishInstallingUpdate(update?.toApi(), e?.toApi())
}

override fun onDisconnect(reason: DisconnectReason) {
_handlers.disconnect(reason.toApi())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package mek.stripeterminal.plugin

import com.stripe.stripeterminal.external.callable.Cancelable
import com.stripe.stripeterminal.external.callable.ReaderReconnectionListener
import com.stripe.stripeterminal.external.models.DisconnectReason
import com.stripe.stripeterminal.external.models.Reader
import mek.stripeterminal.api.TerminalHandlersApi
import mek.stripeterminal.mappings.toApi
Expand All @@ -11,10 +12,10 @@ class ReaderReconnectionListenerPlugin(private val _handlers: TerminalHandlersAp
ReaderReconnectionListener {
var cancelReconnect: Cancelable? = null

override fun onReaderReconnectStarted(reader: Reader, cancelReconnect: Cancelable) =
override fun onReaderReconnectStarted(reader: Reader, cancelReconnect: Cancelable, reason: DisconnectReason) =
runOnMainThread {
this.cancelReconnect = cancelReconnect
_handlers.readerReconnectStarted(reader.toApi())
_handlers.readerReconnectStarted(reader.toApi(), reason.toApi())
}

override fun onReaderReconnectFailed(reader: Reader) = runOnMainThread {
Expand Down
33 changes: 29 additions & 4 deletions stripe_terminal/ios/Classes/Api/TerminalApi.swift
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ protocol TerminalPlatformApi {

func onConnectMobileReader(
_ serialNumber: String,
_ locationId: String
_ locationId: String,
_ autoReconnectOnUnexpectedDisconnect: Bool
) async throws -> ReaderApi

func onConnectUsbReader(
Expand All @@ -144,6 +145,8 @@ protocol TerminalPlatformApi {

func onCancelReaderUpdate() async throws -> Void

func onRebootReader() async throws -> Void

func onDisconnectReader() async throws -> Void

func onSetSimulatorConfiguration(
Expand Down Expand Up @@ -321,7 +324,7 @@ func setTerminalPlatformApiHandler(
}
case "connectMobileReader":
runAsync {
let res = try await hostApi.onConnectMobileReader(args[0] as! String, args[1] as! String)
let res = try await hostApi.onConnectMobileReader(args[0] as! String, args[1] as! String, args[2] as! Bool)
return res.serialize()
}
case "connectUsbReader":
Expand Down Expand Up @@ -350,6 +353,11 @@ func setTerminalPlatformApiHandler(
try await hostApi.onCancelReaderUpdate()
return nil
}
case "rebootReader":
runAsync {
try await hostApi.onRebootReader()
return nil
}
case "disconnectReader":
runAsync {
try await hostApi.onDisconnectReader()
Expand Down Expand Up @@ -554,16 +562,23 @@ class TerminalHandlersApi {
channel.invokeMethod("_onReaderFinishInstallingUpdate", arguments: [update?.serialize(), exception?.serialize()])
}

func disconnect(
reason: DisconnectReasonApi
) {
channel.invokeMethod("_onDisconnect", arguments: [reason.rawValue])
}

func readerReconnectFailed(
reader: ReaderApi
) {
channel.invokeMethod("_onReaderReconnectFailed", arguments: [reader.serialize()])
}

func readerReconnectStarted(
reader: ReaderApi
reader: ReaderApi,
reason: DisconnectReasonApi
) {
channel.invokeMethod("_onReaderReconnectStarted", arguments: [reader.serialize()])
channel.invokeMethod("_onReaderReconnectStarted", arguments: [reader.serialize(), reason.rawValue])
}

func readerReconnectSucceeded(
Expand Down Expand Up @@ -819,6 +834,16 @@ enum DeviceTypeApi: Int {
case appleBuiltIn
}

enum DisconnectReasonApi: Int {
case unknown
case disconnectRequested
case rebootRequested
case securityReboot
case criticallyLowBattery
case poweredOff
case bluetoothDisabled
}

protocol DiscoveryConfigurationApi {}

func deserializeDiscoveryConfigurationApi(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import Foundation
import StripeTerminal

extension DisconnectReason {
func toApi() -> DisconnectReasonApi {
switch self {
case .unknown:
return .unknown
case .disconnectRequested:
return .disconnectRequested
case .rebootRequested:
return .rebootRequested
case .securityReboot:
return .securityReboot
case .criticallyLowBattery:
return .criticallyLowBattery
case .poweredOff:
return .poweredOff
case .bluetoothDisabled:
return .bluetoothDisabled
@unknown default:
fatalError("WTF")
}
}
}
4 changes: 4 additions & 0 deletions stripe_terminal/ios/Classes/Plugin/ReaderDelegatePlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,8 @@ class ReaderDelegatePlugin: NSObject, BluetoothReaderDelegate, LocalMobileReader
func localMobileReader(_ reader: Reader, didFinishInstallingUpdate update: ReaderSoftwareUpdate?, error: Error?) {
self.reader(reader, didFinishInstallingUpdate: update, error: error)
}

func reader(_ reader: Reader, didDisconnect reason: DisconnectReason) {
self._handlers.disconnect(reason: reason.toApi())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ class ReaderReconnectionDelegatePlugin: NSObject, ReconnectionDelegate {
self._handlers = handlers
}

func reader(_ reader: Reader, didStartReconnect cancelable: Cancelable) {
func reader(_ reader: Reader, didStartReconnect cancelable: Cancelable, reason: DisconnectReason) {
self.cancelable = cancelable
DispatchQueue.main.async {
self._handlers.readerReconnectStarted(reader: reader.toApi())
self._handlers.readerReconnectStarted(reader: reader.toApi(), reason: reason.toApi())
}
}

Expand Down
13 changes: 12 additions & 1 deletion stripe_terminal/ios/Classes/TerminalPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,12 @@ public class TerminalPlugin: NSObject, FlutterPlugin, TerminalPlatformApi {

func onConnectMobileReader(
_ serialNumber: String,
_ locationId: String
_ locationId: String,
_ autoReconnectOnUnexpectedDisconnect: Bool
) async throws -> ReaderApi {
let config = LocalMobileConnectionConfigurationBuilder(locationId: locationId)
.setAutoReconnectOnUnexpectedDisconnect(autoReconnectOnUnexpectedDisconnect)
.setAutoReconnectionDelegate(_readerReconnectionDelegate)
do {
let reader = try await Terminal.shared.connectLocalMobileReader(
_findReader(serialNumber),
Expand Down Expand Up @@ -181,6 +184,14 @@ public class TerminalPlugin: NSObject, FlutterPlugin, TerminalPlatformApi {
try await _readerDelegate.cancellableUpdate?.cancel()
}

func onRebootReader() async throws {
do {
try await Terminal.shared.rebootReader()
} catch let error as NSError {
throw error.toPlatformError()
}
}

func onDisconnectReader() async throws {
do {
try await Terminal.shared.disconnectReader()
Expand Down
1 change: 1 addition & 0 deletions stripe_terminal/lib/mek_stripe_terminal.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading