Skip to content

Commit

Permalink
fix(stripe_terminal.ios): Fixes incorrect checking null values from…
Browse files Browse the repository at this point in the history
… flutter

- feat(stripe_terminal): added more parameters to `PaymentIntentParams` class
  • Loading branch information
BreX900 committed Oct 2, 2023
1 parent 69562eb commit 46f5d83
Show file tree
Hide file tree
Showing 23 changed files with 613 additions and 79 deletions.
34 changes: 34 additions & 0 deletions .github/workflows/one_for_all_generator_integration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Integration OneForAllGenerator

on:
pull_request:
paths: [ 'one_for_all/**', 'one_for_all_generator/**' ]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

defaults:
run:
working-directory: one_for_all_generator

jobs:
integration:
runs-on: ubuntu-latest
timeout-minutes: 5

steps:
- uses: actions/checkout@v3
- uses: dart-lang/setup-dart@v1

- name: Resolve dependencies
run: dart pub get
timeout-minutes: 2

- name: Check code formatting
run: >-
dart format --line-length 100 --set-exit-if-changed --output none
$(find . ! -path "./.dart_tool/**" ! -path "./build/**" -name "*.dart" ! -name "*.g.dart")
- name: Analyze code
run: dart analyze
34 changes: 34 additions & 0 deletions .github/workflows/one_for_all_integration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Integration OneForAll

on:
pull_request:
paths: [ 'one_for_all/**' ]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

defaults:
run:
working-directory: one_for_all

jobs:
integration:
runs-on: ubuntu-latest
timeout-minutes: 5

steps:
- uses: actions/checkout@v3
- uses: dart-lang/setup-dart@v1

- name: Resolve dependencies
run: dart pub get
timeout-minutes: 2

- name: Check code formatting
run: >-
dart format --line-length 100 --set-exit-if-changed --output none
$(find . ! -path "./.dart_tool/**" ! -path "./build/**" -name "*.dart" ! -name "*.g.dart")
- name: Analyze code
run: dart analyze
36 changes: 36 additions & 0 deletions .github/workflows/stripe_terminal_integration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Integration StripeTerminal

on:
pull_request:
paths: [ 'stripe_terminal/**', 'one_for_all/**' ]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

defaults:
run:
working-directory: stripe_terminal

jobs:
integration:
runs-on: ubuntu-latest
timeout-minutes: 5

steps:
- uses: actions/checkout@v3
- uses: subosito/flutter-action@v2
with:
flutter-version: '3.13.x'

- name: Resolve dependencies
run: flutter pub get
timeout-minutes: 2

- name: Check code formatting
run: >-
dart format --line-length 100 --set-exit-if-changed --output none
$(find . ! -path "./.dart_tool/**" ! -path "./build/**" -name "*.dart" ! -name "*.g.dart")
- name: Analyze code
run: flutter analyze --no-fatal-infos
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,19 @@ class SwiftApiCodes extends HostApiCodecs {
final typesArgs = type.doubleTypeArgs;
final deserializer = 'Dictionary(uniqueKeysWithValues: ($varAccess as! [AnyHashable?: Any?])'
'.map { k, v in (${encodeDeserialization(typesArgs.$1, 'k')}, ${encodeDeserialization(typesArgs.$2, 'v')}) })';
return type.isNullable ? '$varAccess != nil ? $deserializer : nil' : deserializer;
return type.isNullable ? '!($varAccess is NSNull) ? $deserializer : nil' : deserializer;
}
if (type.isDartCoreEnum || type.element is EnumElement) {
final deserializer = '${encodeName(type.displayName)}(rawValue: $varAccess as! Int)!';
return type.isNullable ? '$varAccess != nil ? $deserializer : nil' : deserializer;
return type.isNullable ? '!($varAccess is NSNull) ? $deserializer : nil' : deserializer;
}

final codec = findCodec(type);
if (codec != null) {
if (!type.isNullable || codec.hasNullSafeDeserialization) {
return codec.encodeDeserialization(this, type, varAccess);
} else {
return '$varAccess != nil ? ${codec.encodeDeserialization(this, type, varAccess)} : nil';
return '!($varAccess is NSNull) ? ${codec.encodeDeserialization(this, type, varAccess)} : nil';
}
}

Expand All @@ -70,7 +70,7 @@ class SwiftApiCodes extends HostApiCodecs {
? 'deserialize${encodeName(type.displayName)}'
: '${encodeName(type.displayName)}.deserialize';
final deserializer = '$deserializerMethod($varAccess as! [Any?])';
return type.isNullable ? '$varAccess != nil ? $deserializer : nil' : deserializer;
return type.isNullable ? '!($varAccess is NSNull) ? $deserializer : nil' : deserializer;
}

@override
Expand Down
4 changes: 3 additions & 1 deletion stripe_terminal/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
## Next release
## 3.0.0-dev
- fix(ios): Fixes incorrect checking `null` values from flutter
- feat: added more parameters to `PaymentIntentParams` class
- build(android): The `minSdkVersion` has been updated to 26. This means that the SDK will no longer support devices running Android 7.1.2 (Nougat) or earlier. Older devices can continue to use the 2.x versions of the SDK while on the maintenance schedule.
- feat: Added to `Reader` class the `location` field.
- fix(android): `Terminal.onUnexpectedReaderDisconnect` will be emit if a command cannot be sent to an internet reader. Previously, this callback was only invoked when a periodic status check failed.
Expand Down
3 changes: 3 additions & 0 deletions stripe_terminal/ROADMAP.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
#### Ready
- Update [README.md](./README.md)

#### Done
- https://github.com/BreX900/mek-packages/issues/11

# Android
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,26 +291,14 @@ class StripeTerminalPlugin : FlutterPlugin, ActivityAware, StripeTerminalPlatfor
parameters: PaymentIntentParametersApi
) {
_terminal.createPaymentIntent(
PaymentIntentParameters.Builder(
amount = parameters.amount,
currency = parameters.currency,
captureMethod = when (parameters.captureMethod) {
CaptureMethodApi.MANUAL -> CaptureMethod.Manual
CaptureMethodApi.AUTOMATIC -> CaptureMethod.Automatic
},
allowedPaymentMethodTypes = parameters.paymentMethodTypes.map {
when (it) {
PaymentMethodTypeApi.CARD_PRESENT -> PaymentMethodType.CARD_PRESENT
PaymentMethodTypeApi.CARD -> PaymentMethodType.CARD
PaymentMethodTypeApi.INTERACT_PRESENT -> PaymentMethodType.INTERAC_PRESENT
}
},
).build(), object : TerminalErrorHandler(result::error), PaymentIntentCallback {
params = parameters.toHost(),
callback = object : TerminalErrorHandler(result::error), PaymentIntentCallback {
override fun onSuccess(paymentIntent: PaymentIntent) {
_paymentIntents[paymentIntent.id!!] = paymentIntent
result.success(paymentIntent.toApi())
}
})
}
)
}

override fun onRetrievePaymentIntent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,10 @@ data class CardNetworksApi(
}
}

enum class CardPresentCaptureMethodApi {
MANUAL_PREFERRED;
}

data class CardPresentDetailsApi(
val brand: CardBrandApi?,
val country: String?,
Expand Down Expand Up @@ -614,6 +618,30 @@ data class CardPresentDetailsApi(
}
}

data class CardPresentParametersApi(
val captureMethod: CardPresentCaptureMethodApi?,
val requestExtendedAuthorization: Boolean?,
val requestIncrementalAuthorizationSupport: Boolean?,
val requestedPriority: CardPresentRoutingApi?,
) {
companion object {
fun deserialize(
serialized: List<Any?>,
): CardPresentParametersApi {
return CardPresentParametersApi(
captureMethod = (serialized[0] as Int?)?.let { CardPresentCaptureMethodApi.values()[it] },
requestExtendedAuthorization = serialized[1] as Boolean?,
requestIncrementalAuthorizationSupport = serialized[2] as Boolean?,
requestedPriority = (serialized[3] as Int?)?.let { CardPresentRoutingApi.values()[it] },
)
}
}
}

enum class CardPresentRoutingApi {
DOMESTIC, INTERNATIONAL;
}

data class CartApi(
val currency: String,
val tax: Long,
Expand Down Expand Up @@ -858,6 +886,18 @@ data class PaymentIntentParametersApi(
val currency: String,
val captureMethod: CaptureMethodApi,
val paymentMethodTypes: List<PaymentMethodTypeApi>,
val metadata: HashMap<String, String>,
val description: String?,
val statementDescriptor: String?,
val statementDescriptorSuffix: String?,
val receiptEmail: String?,
val customerId: String?,
val applicationFeeAmount: Long?,
val transferDataDestination: String?,
val transferGroup: String?,
val onBehalfOf: String?,
val setupFutureUsage: String?,
val paymentMethodOptionsParameters: PaymentMethodOptionsParametersApi?,
) {
companion object {
fun deserialize(
Expand All @@ -868,6 +908,18 @@ data class PaymentIntentParametersApi(
currency = serialized[1] as String,
captureMethod = (serialized[2] as Int).let { CaptureMethodApi.values()[it] },
paymentMethodTypes = (serialized[3] as List<*>).map { (it as Int).let { PaymentMethodTypeApi.values()[it] } },
metadata = hashMapOf(*(serialized[4] as HashMap<*, *>).map { (k, v) -> k as String to v as String }.toTypedArray()),
description = serialized[5] as String?,
statementDescriptor = serialized[6] as String?,
statementDescriptorSuffix = serialized[7] as String?,
receiptEmail = serialized[8] as String?,
customerId = serialized[9] as String?,
applicationFeeAmount = (serialized[10] as? Number)?.toLong(),
transferDataDestination = serialized[11] as String?,
transferGroup = serialized[12] as String?,
onBehalfOf = serialized[13] as String?,
setupFutureUsage = serialized[14] as String?,
paymentMethodOptionsParameters = (serialized[15] as List<Any?>?)?.let { PaymentMethodOptionsParametersApi.deserialize(it) },
)
}
}
Expand All @@ -889,6 +941,20 @@ data class PaymentMethodDetailsApi(
}
}

data class PaymentMethodOptionsParametersApi(
val cardPresentParameters: CardPresentParametersApi,
) {
companion object {
fun deserialize(
serialized: List<Any?>,
): PaymentMethodOptionsParametersApi {
return PaymentMethodOptionsParametersApi(
cardPresentParameters = (serialized[0] as List<Any?>).let { CardPresentParametersApi.deserialize(it) },
)
}
}
}

enum class PaymentMethodTypeApi {
CARD_PRESENT, CARD, INTERACT_PRESENT;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,18 @@ fun DiscoveryConfigurationApi.toHost(): DiscoveryConfiguration? {
isSimulated = isSimulated,
timeout = timeout?.let { microsecondsToSeconds(it) } ?: 0,
)

is BluetoothProximityDiscoveryConfigurationApi -> null
is HandoffDiscoveryConfigurationApi -> DiscoveryConfiguration.HandoffDiscoveryConfiguration()
is InternetDiscoveryConfigurationApi -> DiscoveryConfiguration.InternetDiscoveryConfiguration(
isSimulated = isSimulated,
location = locationId,
)

is LocalMobileDiscoveryConfigurationApi -> DiscoveryConfiguration.LocalMobileDiscoveryConfiguration(
isSimulated = isSimulated,
)

is UsbDiscoveryConfigurationApi -> DiscoveryConfiguration.UsbDiscoveryConfiguration(
isSimulated = isSimulated,
timeout = timeout?.let { microsecondsToSeconds(it) } ?: 0,
Expand Down Expand Up @@ -61,6 +64,65 @@ fun CartLineItemApi.toHost(): CartLineItem {
).build()
}

fun PaymentIntentParametersApi.toHost(): PaymentIntentParameters {
val b = PaymentIntentParameters.Builder(
amount = amount,
currency = currency,
captureMethod = when (captureMethod) {
CaptureMethodApi.MANUAL -> CaptureMethod.Manual
CaptureMethodApi.AUTOMATIC -> CaptureMethod.Automatic
},
allowedPaymentMethodTypes = paymentMethodTypes.map {
when (it) {
PaymentMethodTypeApi.CARD_PRESENT -> PaymentMethodType.CARD_PRESENT
PaymentMethodTypeApi.CARD -> PaymentMethodType.CARD
PaymentMethodTypeApi.INTERACT_PRESENT -> PaymentMethodType.INTERAC_PRESENT
}
},
)
b.setMetadata(metadata)
description?.let(b::setDescription)
statementDescriptor?.let(b::setStatementDescriptor)
statementDescriptorSuffix?.let(b::setStatementDescriptorSuffix)
receiptEmail?.let(b::setReceiptEmail)
customerId?.let(b::setCustomer)
applicationFeeAmount?.let(b::setApplicationFeeAmount)
transferDataDestination?.let(b::setTransferDataDestination)
transferGroup?.let(b::setTransferGroup)
onBehalfOf?.let(b::setOnBehalfOf)
setupFutureUsage?.let(b::setSetupFutureUsage)
paymentMethodOptionsParameters?.let { b.setPaymentMethodOptionsParameters(it.toHost()) }
return b.build()
}

fun PaymentMethodOptionsParametersApi.toHost(): PaymentMethodOptionsParameters {
return PaymentMethodOptionsParameters.Builder()
.setCardPresentParameters(cardPresentParameters.toHost())
.build()
}

fun CardPresentParametersApi.toHost(): CardPresentParameters {
val b = CardPresentParameters.Builder()
captureMethod?.let { b.setCaptureMethod(it.toHost()) }
requestExtendedAuthorization?.let { b.setRequestExtendedAuthorization(it) }
requestIncrementalAuthorizationSupport?.let { b.setRequestIncrementalAuthorizationSupport(it) }
requestedPriority?.let { b.setRouting(CardPresentRoutingOptionParameters(it.toHost())) }
return b.build()
}

fun CardPresentCaptureMethodApi.toHost(): CardPresentCaptureMethod {
return when (this) {
CardPresentCaptureMethodApi.MANUAL_PREFERRED -> CardPresentCaptureMethod.ManualPreferred
}
}

fun CardPresentRoutingApi.toHost(): RoutingPriority {
return when (this) {
CardPresentRoutingApi.DOMESTIC -> RoutingPriority.DOMESTIC
CardPresentRoutingApi.INTERNATIONAL -> RoutingPriority.INTERNATIONAL
}
}

fun SetupIntentUsageApi.toHost(): String {
return when (this) {
SetupIntentUsageApi.ON_SESSION -> "on_session"
Expand Down
Loading

0 comments on commit 46f5d83

Please sign in to comment.