-
Notifications
You must be signed in to change notification settings - Fork 50
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
[WIP] Bump Terminal SDK to 4.0.0 #847
base: main
Are you sure you want to change the base?
Conversation
@@ -659,7 +602,7 @@ private fun mapFromWechatPayDetails(wechatPayDetails: WechatPayDetails?): Readab | |||
private fun mapFromOfflineDetails(offlineDetails: OfflineDetails?): ReadableMap? = | |||
offlineDetails?.let { | |||
nativeMapOf { | |||
putString("storedAt", offlineDetails.storedAt.toString()) | |||
putString("storedAt", offlineDetails.storedAtMs.toString()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make sense to update the string name?
putString("storedAt", offlineDetails.storedAtMs.toString()) | |
putString("storedAtMs", offlineDetails.storedAtMs.toString()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because it's also used on ios side and name only changed in Android now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like it's still storedAt
for iOS. @bric-stripe this could be something to consider for SDKv5?
Android Jira ticket for context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it makes sense for the RN layer to expose a consistent value though, right? I think RN exposing storedAtMs
and then in the swift layer below it can just convert from the s to the ms value so its consistent regardless of platform...and yeah we should fix it up on the native side. we could add the storedAtMs next to storedAt in a minor update and then drop storedAt in v5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just found RN already had the transform before 4.0, so we can align the name as bric suggested.
https://github.com/stripe/stripe-terminal-react-native/blob/main/ios/Mappers.swift#L530
https://github.com/stripe/stripe-terminal-react-native/blob/main/ios/Mappers.swift#L457-L463
val autoReconnectOnUnexpectedDisconnect = if (discoveryMethod == DiscoveryMethod.BLUETOOTH_SCAN || discoveryMethod == DiscoveryMethod.USB || discoveryMethod == DiscoveryMethod.TAP_TO_PAY) { | ||
getBoolean(params, "autoReconnectOnUnexpectedDisconnect") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If no autoReconnectOnUnexpectedDisconnect
is provided, it should default to true.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just want to make sure are your referring to the scope of BLUETOOTH_SCAN, USB, TAP_TO_PAY only or no matter which discoveryMethod.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's only for BLUETOOTH_SCAN, USB and TAP_TO_PAY. For other connection types, it shouldn't matter if a autoReconnectOnUnexpectedDisconnect
value is provided.
@@ -250,7 +194,7 @@ class StripeTerminalReactNativeModule(reactContext: ReactApplicationContext) : | |||
params: ReadableMap, | |||
promise: Promise, | |||
discoveryMethod: DiscoveryMethod, | |||
listener: ReaderListenable? = null | |||
listener: ReaderDisconnectListener? = null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder why we pass in ReaderDisconnectListener
here. I think the listener should be one of the following:
- RNBluetoothReaderListener
- RNHandoffReaderListener
- RNInternetReaderListener
- RNTapToPayReaderListener
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ya, but RNInternetReaderListener
, RNTapToPayReaderListener
are not ReaderListenable
, if we want to use the same pattern here we have to find a common parent, or we need to expose new parameter (probably two in this case).
Another idea is to declare listener and discoveryMethod relationship in a sealed class and use that binding for more type safe usage but it require more change the scope of bump sdk version.
What do you think on these two or any other suggestions?
Also add a todo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we want to use the same pattern here we have to find a common parent, or we need to expose new parameter (probably two in this case).
I think it's fine to expose new parameters in private methods.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AllowRedisplay.ALWAYS, | ||
// customerConsentCollected,//TODO: seems removed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should give an option for the merchant to set the AllowRedisplay
parameter. If the merchant doesn't provide one, we should default to AllowRedisplay.UNSPECIFIED
The removal of the customerConsentCollected
parameter is expected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we'll have new parameter for user on AllowRedisplay right?
But what is the different meaning to user/rn sdk? is there other required change corresponding to this attribute?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can find more details about this specific change in our Stripe docs here. We also have Android docs here and iOS docs here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup @tim-lin-bbpos
for collectSetupIntentPaymentMethod
the user is required to pass in AllowRedisplay
now, they are no longer expected to pass customerConsentCollected
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please also include an optional AllowRedisplay
field for CollectConfiguration
for CollectPaymentMethod
(line ~500) and pass that into the SDK as well
reader: Reader, | ||
locationId: String, | ||
autoReconnectOnUnexpectedDisconnect: Boolean = false, | ||
listener: ReaderListenable? = null, | ||
reconnectionListener: ReaderReconnectionListener | ||
disconnectListener: ReaderDisconnectListener? = null, | ||
reconnectionListener: ReaderReconnectionListener, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this connectReader(...)
method publicly exposed in the RN SDK? If not, can we remove it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RN user should only use RN sdk via js interface not any native Kotlin/Android code.
reader: Reader, | ||
locationId: String, | ||
autoReconnectOnUnexpectedDisconnect: Boolean = false, | ||
listener: ReaderListenable? = null, | ||
reconnectionListener: ReaderReconnectionListener | ||
disconnectListener: ReaderDisconnectListener? = null, | ||
reconnectionListener: ReaderReconnectionListener, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wondering if we can make ReaderReconnectionListener
optional to pass in, since it's not required by internet and handoff readers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can make the declaration optional but it won't help much in this case since there's only one usage.
Maybe best way is to initiate this listener when need if it's not common for all the cases but it also imply a bigger refactoring which I try to avoid in this stage.
Mark a todo here.
|
||
class RNBluetoothReaderListener( | ||
private val context: ReactApplicationContext, | ||
private val onStartInstallingUpdate: (cancelable: Cancelable?) -> Unit | ||
) : ReaderListener { | ||
) : MobileReaderListener, ReaderDisconnectListener by readerDisconnectDelete(context) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity, why are we adding a readerDisconnectDelete
delegate here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To avoid adding same code again and again, as these interface is not required so people can remove if not carefully, for example the RNHandoffReaderListener is not implement the disconnect part before.
reason: DisconnectReason | ||
) { | ||
onReaderReconnectStarted(cancelReconnect) | ||
context.sendEvent(START_READER_RECONNECT.listenerName) { | ||
putMap("reader", mapFromReader(reader)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we add the disconnect reason to the event?
@@ -47,7 +47,7 @@ export type ConnectUsbReaderParams = { | |||
autoReconnectOnUnexpectedDisconnect?: boolean; | |||
}; | |||
|
|||
export type ConnectLocalMobileParams = { | |||
export type ConnectTapToPayParams = { | |||
reader: Reader.Type; | |||
locationId?: string; | |||
onBehalfOf?: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should update ConnectTapToPayParams
so that autoReconnectOnUnexpectedDisconnect
defaults to true
android/src/main/java/com/stripeterminalreactnative/ktx/TerminalExtensions.kt
Outdated
Show resolved
Hide resolved
): Reader = when (discoveryMethod) { | ||
DiscoveryMethod.BLUETOOTH_SCAN -> { | ||
val connConfig = BluetoothConnectionConfiguration( | ||
locationId, | ||
autoReconnectOnUnexpectedDisconnect, | ||
reconnectionListener | ||
(disconnectListener as? MobileReaderListener).bindReconnectionListener(reconnectionListener) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it looks like we don't give an option to pass in a ReaderListenable
here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same thing as above, right now disconnectListener is acted like the original listener but I'm also struggling if there's other better alternative.
case .tapToPayReaderFailedToPrepare: | ||
return "TapToPayReaderFailedToPrepare" | ||
case .tapToPayReaderDeviceBanned: | ||
return "TapToPayReaderDeviceBanned" | ||
case .tapToPayReaderTOSNotYetAccepted: | ||
return "TapToPayReaderTOSNotYetAccepted" | ||
case .tapToPayReaderTOSAcceptanceFailed: | ||
return "TapToPayReaderTOSAcceptanceFailed" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We've added a new error code to the iOS and Android SDK. (for iOS, it's SCPErrorGenericReaderError
, and for Android it's GENERIC_READER_ERROR
). Can we add a new external-facing RN error code for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In Android we use toString so it doesn't matter if there's new element or not, but on iOS side besides .genericReaderError
we still have all of these:
case .cancelFailedUnavailable:
<#code#>
case .invalidConnectionConfiguration:
<#code#>
case .invalidRequiredParameterOnBehalfOf:
<#code#>
case .requestDynamicCurrencyConversionRequiresUpdatePaymentIntent:
<#code#>
case .dynamicCurrencyConversionNotAvailable:
<#code#>
case .surchargeNoticeRequiresUpdatePaymentIntent:
<#code#>
case .surchargeUnavailableWithDynamicCurrencyConversion:
<#code#>
case .canceledDueToIntegrationError:
<#code#>
case .collectInputsInvalidParameter:
<#code#>
case .collectInputsUnsupported:
<#code#>
case .readerConnectionOfflineNeedsUpdate:
<#code#>
case .readerConnectionOfflinePairingUnseenDisabled:
<#code#>
case .collectInputsTimedOut:
<#code#>
case .usbDiscoveryTimedOut:
<#code#>
case .tapToPayReaderAccountDeactivated:
<#code#>
case .readerMissingEncryptionKeys:
<#code#>
case .usbDisconnected:
<#code#>
case .encryptionKeyFailure:
<#code#>
case .encryptionKeyStillInitializing:
<#code#>
case .collectInputsApplicationError:
<#code#>
case .genericReaderError:
<#code#>
case .commandInvalidAllowRedisplay:
<#code#>
case .onlinePinNotSupportedOffline:
<#code#>
case .offlineTestCardInLivemode:
Do we need to add them all or only the one you mentioned?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we want to add all these iOS errors (cc @bric-stripe @mindy-stripe to confirm)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems we still need some time to merge this, create in separate pr here: #851
Will add new ones here when able to rebase.
Also would like to know if we're consider some ways to automatically convert enum to string without hardcode like Android side?
https://stackoverflow.com/questions/24701075/swift-convert-enum-value-to-string
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also would like to know if we're consider some ways to automatically convert enum to string without hardcode
unfortunately the enum backing ErrorCode.Code
in the native SDK is an ObjC enum and so can't be declared as being backed by a String.
in the native SDK we do have a code to string helper already and we could expose that, but it wouldn't be available until 4.2 at the earliest.
@tim-lin-bbpos To match the new native commands can we consolidate all connect* methods to a single |
@tim-lin-bbpos you might've already made this change - |
97edf62
to
1ad049c
Compare
1ad049c
to
5a2c56f
Compare
Summary
Bump Terminal SDK to 4.0.0
Motivation
REPORT_UNEXPECTED_READER_DISCONNECT
as we can now useDISCONNECT
directly.Testing
Documentation
Select one: