From a679954c0fcd51f3cb3252555fd6502af3011644 Mon Sep 17 00:00:00 2001 From: softdev55 Date: Sun, 4 Jul 2021 14:02:08 +0200 Subject: [PATCH] Sync with latest sources (#162) * sync android code * implement new parsing cardfield and paymentintent * comply to new result propagation for setupintent * sync ios * Update dart layer * Throw errors for easy debug + cancel login when error * workaround for https://github.com/stripe/stripe-react-native/issues/368, also adjusted canceledAt * migrate to flutter_lints because pedantic is deprecated * implement create token method (#165) * implement create token method * add create token to example app * Add createToken for iOS * Make example tiles scrollable Co-authored-by: Jaime Blasco * improve documentation for Android and issues #155 #142 * fix merge issue * add urlscheme to initialise method * BREAKING: rename threedsecure button config and add config theme for other buttons * BREAKING make paymentIntentClientSecret nullable and add setupIntentClientSecret for paymentsheet * add fontfamily and dangerouslyGetFullCardDetails to cardfield Co-authored-by: Remon Co-authored-by: Remon Helmond Co-authored-by: Jaime Blasco --- README.md | 3 +- analysis_options.yaml | 2 +- example/lib/main.dart | 2 +- example/lib/screens/legacy_token_screen.dart | 73 + .../screens/no_webhook_payment_screen.dart | 1 + example/lib/screens/payment_sheet_screen.dart | 2 + example/lib/screens/screens.dart | 5 + .../screens/setup_future_payment_screen.dart | 4 +- example/lib/widgets/loading_button.dart | 24 +- packages/stripe/lib/src/stripe.dart | 38 +- .../stripe/lib/src/widgets/card_field.dart | 19 + packages/stripe/pubspec.yaml | 3 +- packages/stripe_android/android/build.gradle | 3 +- .../react/bridge/BaseActivityEventListener.kt | 6 +- .../react/bridge/ReactApplicationContext.java | 7 +- .../com/flutter/stripe/StripeAndroidPlugin.kt | 11 +- .../stripe/StripeSdkCardPlatformView.kt | 18 +- .../reactnativestripesdk/CardChangedEvent.kt | 21 +- .../kotlin/com/reactnativestripesdk/Errors.kt | 60 +- .../com/reactnativestripesdk/Mappers.kt | 273 +++- .../PaymentMethodCreateParamsFactory.kt | 2 +- .../PaymentSheetFragment.kt | 37 +- .../reactnativestripesdk/StripeSdkCardView.kt | 97 +- .../StripeSdkCardViewManager.kt | 12 +- .../reactnativestripesdk/StripeSdkModule.kt | 385 ++--- packages/stripe_android/pubspec.yaml | 2 +- .../ios/Classes/CardFieldView.swift | 10 +- packages/stripe_ios/ios/Classes/Errors.swift | 63 +- packages/stripe_ios/ios/Classes/Mappers.swift | 331 ++++- .../ios/Classes/PaymentMethodFactory.swift | 2 +- .../stripe_ios/ios/Classes/RCTBridge.swift | 9 + .../stripe_ios/ios/Classes/StripePlugin.swift | 21 +- .../stripe_ios/ios/Classes/StripeSdk.swift | 275 ++-- packages/stripe_ios/pubspec.yaml | 2 +- .../lib/src/method_channel_stripe.dart | 40 +- .../lib/src/models/address.freezed.dart | 4 +- .../lib/src/models/app_info.freezed.dart | 4 +- .../lib/src/models/apple_pay.freezed.dart | 11 +- .../lib/src/models/card_field_input.dart | 12 +- .../src/models/card_field_input.freezed.dart | 85 +- .../lib/src/models/card_field_input.g.dart | 6 +- .../lib/src/models/create_token_data.dart | 158 ++ .../src/models/create_token_data.freezed.dart | 1313 +++++++++++++++++ .../lib/src/models/create_token_data.g.dart | 159 ++ .../lib/src/models/errors.dart | 2 + .../lib/src/models/errors.freezed.dart | 4 +- .../lib/src/models/payment_intents.dart | 12 +- .../src/models/payment_intents.freezed.dart | 108 +- .../lib/src/models/payment_intents.g.dart | 8 +- .../src/models/payment_methods.freezed.dart | 100 +- .../lib/src/models/payment_sheet.dart | 10 +- .../lib/src/models/payment_sheet.freezed.dart | 74 +- .../lib/src/models/payment_sheet.g.dart | 4 +- .../lib/src/models/setup_intent.dart | 3 +- .../lib/src/models/setup_intent.freezed.dart | 26 +- .../lib/src/models/setup_intent.g.dart | 2 +- .../lib/src/models/three_d_secure.dart | 28 +- .../src/models/three_d_secure.freezed.dart | 362 +++-- .../lib/src/models/three_d_secure.g.dart | 32 +- .../lib/src/stripe_platform_interface.dart | 6 + .../lib/stripe_platform_interface.dart | 1 + .../stripe_platform_interface/pubspec.yaml | 8 +- .../test/method_channel_mock.dart | 2 +- .../test/method_channel_stripe_test.dart | 91 +- .../test/test_data.dart | 46 +- 65 files changed, 3791 insertions(+), 753 deletions(-) create mode 100644 example/lib/screens/legacy_token_screen.dart create mode 100644 packages/stripe_platform_interface/lib/src/models/create_token_data.dart create mode 100644 packages/stripe_platform_interface/lib/src/models/create_token_data.freezed.dart create mode 100644 packages/stripe_platform_interface/lib/src/models/create_token_data.g.dart diff --git a/README.md b/README.md index 9eb19e9..cad2942 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,8 @@ dart pub add flutter_stripe - Android 5.0 (API level 21) and above - Kotlin version 1.5.0 and above: [example](https://github.com/flutter-stripe/flutter_stripe/blob/79b201a2e9b827196d6a97bb41e1d0e526632a5a/example/android/build.gradle#L2) -- Using a descendant of `Theme.AppCompact` for your activity: [example](https://github.com/flutter-stripe/flutter_stripe/blob/384d390c8a90d19dc62c73faa5226fa931fd6d44/example/android/app/src/main/res/values/styles.xml#L15) +- Using a descendant of `Theme.AppCompact` for your activity: [example](https://github.com/flutter-stripe/flutter_stripe/main/example/android/app/src/main/res/values/styles.xml#L15), [example night theme](https://github.com/flutter-stripe/flutter_stripe/blob/main/example/android/app/src/main/res/values-night/styles.xml#L16) +- Using an up-to-date Android gradle build tools version: [example](https://github.com/flutter-stripe/flutter_stripe/blob/main/example/android/build.gradle#L9) and an up-to-date gradle version accordingly: [example](https://github.com/flutter-stripe/flutter_stripe/blob/main/example/android/gradle/wrapper/gradle-wrapper.properties#L6) - Using `FlutterFragmentActivity` instead of `FlutterActivity` in `MainActivity.kt`: [example](https://github.com/flutter-stripe/flutter_stripe/blob/79b201a2e9b827196d6a97bb41e1d0e526632a5a/example/android/app/src/main/kotlin/com/flutter/stripe/example/MainActivity.kt#L6) This is caused by the Stripe SDK requires the use of the AppCompact theme for their UI components and the Support Fragment Manager for the Payment Sheets diff --git a/analysis_options.yaml b/analysis_options.yaml index 97aae0b..17df8a6 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -4,7 +4,7 @@ # # include: ../analysis_options.yaml # -include: package:pedantic/analysis_options.1.11.0.yaml +include: package:flutter_lints/flutter.yaml # TODO (albertus-stripe): Add "public_member_api_docs" linter after all public member documentation are finished. diff --git a/example/lib/main.dart b/example/lib/main.dart index 0190afa..fe62b58 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -42,7 +42,7 @@ class _HomePageState extends State { appBar: AppBar( title: const Text('Plugin example app'), ), - body: Column(children: [ + body: ListView(children: [ ...ListTile.divideTiles( context: context, tiles: [ diff --git a/example/lib/screens/legacy_token_screen.dart b/example/lib/screens/legacy_token_screen.dart new file mode 100644 index 0000000..c1cf3ab --- /dev/null +++ b/example/lib/screens/legacy_token_screen.dart @@ -0,0 +1,73 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_stripe/flutter_stripe.dart'; +import 'package:stripe_example/widgets/loading_button.dart'; +import 'package:stripe_platform_interface/stripe_platform_interface.dart'; + +class LegacyTokenScreen extends StatefulWidget { + @override + _LegacyTokenScreenState createState() => _LegacyTokenScreenState(); +} + +class _LegacyTokenScreenState extends State { + CardFieldInputDetails? _card; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(), + body: Column( + children: [ + Padding( + padding: EdgeInsets.all(16), + child: CardField( + onCardChanged: (card) { + setState(() { + _card = card; + }); + }, + ), + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 16), + child: LoadingButton( + onPressed: + _card?.complete == true ? _handleCreateTokenPress : null, + text: 'Create token', + ), + ), + ], + ), + ); + } + + Future _handleCreateTokenPress() async { + if (_card == null) { + return; + } + + try { + // 1. Gather customer billing information (ex. email) + + final address = Address( + city: 'Houston', + country: 'US', + line1: '1459 Circle Drive', + line2: '', + state: 'Texas', + postalCode: '77063', + ); // mocked data for tests + + // 2. Create payment method + await Stripe.instance.createToken( + CreateTokenParams(type: TokenType.Card, address: address)); + + ScaffoldMessenger.of(context).showSnackBar(SnackBar( + content: Text('Success!: The token was created successfully}!'))); + return; + } catch (e) { + ScaffoldMessenger.of(context) + .showSnackBar(SnackBar(content: Text('Error: $e'))); + rethrow; + } + } +} diff --git a/example/lib/screens/no_webhook_payment_screen.dart b/example/lib/screens/no_webhook_payment_screen.dart index 7f429db..256e007 100644 --- a/example/lib/screens/no_webhook_payment_screen.dart +++ b/example/lib/screens/no_webhook_payment_screen.dart @@ -125,6 +125,7 @@ class _NoWebhookPaymentScreenState extends State { } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Error: $e'))); + rethrow; } } diff --git a/example/lib/screens/payment_sheet_screen.dart b/example/lib/screens/payment_sheet_screen.dart index 7a26f49..92a1da5 100644 --- a/example/lib/screens/payment_sheet_screen.dart +++ b/example/lib/screens/payment_sheet_screen.dart @@ -80,6 +80,7 @@ class _PaymentSheetScreenState extends State { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Error: $e')), ); + rethrow; } } @@ -107,6 +108,7 @@ class _PaymentSheetScreenState extends State { content: Text('$e'), ), ); + rethrow; } } } diff --git a/example/lib/screens/screens.dart b/example/lib/screens/screens.dart index a158cbf..f62cc1a 100644 --- a/example/lib/screens/screens.dart +++ b/example/lib/screens/screens.dart @@ -6,6 +6,7 @@ import '../screens/no_webhook_payment_screen.dart'; import '../screens/setup_future_payment_screen.dart'; import '../screens/webhook_payment_screen.dart'; import 'cvc_re_collection_screen.dart'; +import 'legacy_token_screen.dart'; import 'payment_sheet_screen.dart'; import 'themes.dart'; @@ -51,5 +52,9 @@ class Example { title: 'Payment sheet', builder: (context) => PaymentSheetScreen(), ), + Example( + title: 'Create token (legacy)', + builder: (context)=> LegacyTokenScreen(), + ) ]; } diff --git a/example/lib/screens/setup_future_payment_screen.dart b/example/lib/screens/setup_future_payment_screen.dart index fcf795e..7513a30 100644 --- a/example/lib/screens/setup_future_payment_screen.dart +++ b/example/lib/screens/setup_future_payment_screen.dart @@ -2,8 +2,8 @@ import 'dart:convert'; import 'dart:developer'; import 'package:flutter/material.dart' hide Card; -import 'package:http/http.dart' as http; import 'package:flutter_stripe/flutter_stripe.dart'; +import 'package:http/http.dart' as http; import 'package:stripe_example/config.dart'; import 'package:stripe_example/widgets/loading_button.dart'; import 'package:stripe_platform_interface/stripe_platform_interface.dart'; @@ -183,7 +183,7 @@ class _SetupFuturePaymentScreenState extends State { await Stripe.instance.confirmPaymentMethod( _retrievedPaymentIntent!.clientSecret, PaymentMethodParams.cardFromMethodId( - paymentMethodId: _retrievedPaymentIntent!.paymentMethodId), + paymentMethodId: _retrievedPaymentIntent!.paymentMethodId!), ); } } diff --git a/example/lib/widgets/loading_button.dart b/example/lib/widgets/loading_button.dart index 59f8257..cc82993 100644 --- a/example/lib/widgets/loading_button.dart +++ b/example/lib/widgets/loading_button.dart @@ -29,18 +29,22 @@ class _LoadingButtonState extends State { setState(() { _isLoading = true; }); - if (kDebugMode) { + + try { await widget.onPressed!(); - } else { - try { - await widget.onPressed!(); - } catch (e) { - ScaffoldMessenger.of(context) - .showSnackBar(SnackBar(content: Text('Error $e'))); + } catch (e) { + if (kDebugMode) { + rethrow; + } else { + ScaffoldMessenger.of(context) + .showSnackBar(SnackBar(content: Text('Error $e'))); } + } finally { + setState(() { + _isLoading = false; + }); } - setState(() { - _isLoading = false; - }); + + } } diff --git a/packages/stripe/lib/src/stripe.dart b/packages/stripe/lib/src/stripe.dart index cc090f1..9a8d825 100644 --- a/packages/stripe/lib/src/stripe.dart +++ b/packages/stripe/lib/src/stripe.dart @@ -57,6 +57,20 @@ class Stripe { instance.markNeedsSettings(); } + /// Sets the custom url scheme + static set urlScheme(String? value) { + if (value == instance._urlScheme) { + return; + } + instance._urlScheme = value; + instance.markNeedsSettings(); + } + + /// Retrieves the custom url scheme + static String? get urlScheme { + return instance._urlScheme; + } + /// Retrieves the merchant identifier. static String? get merchantIdentifier => instance._merchantIdentifier; @@ -71,12 +85,13 @@ class Stripe { /// Reconfigures the Stripe platform by applying the current values for /// [publishableKey], [merchantIdentifier], [stripeAccountId], - /// [threeDSecureParams] + /// [threeDSecureParams], [urlScheme] Future applySettings() => _initialise( publishableKey: publishableKey, merchantIdentifier: merchantIdentifier, stripeAccountId: stripeAccountId, threeDSecureParams: threeDSecureParams, + urlScheme: urlScheme, ); /// Exposes a [ValueListenable] whether or not Apple pay is supported for this @@ -122,6 +137,22 @@ class Stripe { } } + /// Creates a single-use token that represents a credit card’s details. + /// + /// Tokens are considered legacy, use [PaymentMethod] and [PaymentIntent] + /// instead. + /// /// Throws an [StripeError] in case createToken fails. + + Future createToken(CreateTokenParams params) async { + await _awaitForSettings(); + try { + final tokenData = await _platform.createToken(params); + return tokenData; + } on StripeError catch (error) { + throw StripeError(message: error.message, code: error.message); + } + } + /// Retrieves a [PaymentIntent] using the provided [clientSecret]. /// /// Throws an [StripeError] in case retrieving the intent fails. @@ -290,6 +321,7 @@ class Stripe { String? _stripeAccountId; ThreeDSecureConfigurationParams? _threeDSecureParams; String? _merchantIdentifier; + String? _urlScheme; static StripePlatform? __platform; @@ -311,13 +343,15 @@ class Stripe { String? stripeAccountId, ThreeDSecureConfigurationParams? threeDSecureParams, String? merchantIdentifier, + String? urlScheme, }) async { - _needsSettings = false; + _needsSettings = false; await _platform.initialise( publishableKey: publishableKey, stripeAccountId: stripeAccountId, threeDSecureParams: threeDSecureParams, merchantIdentifier: merchantIdentifier, + urlScheme: urlScheme, ); } diff --git a/packages/stripe/lib/src/widgets/card_field.dart b/packages/stripe/lib/src/widgets/card_field.dart index a3eff1e..0b8756b 100644 --- a/packages/stripe/lib/src/widgets/card_field.dart +++ b/packages/stripe/lib/src/widgets/card_field.dart @@ -5,6 +5,7 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_stripe/flutter_stripe.dart'; import 'package:stripe_platform_interface/stripe_platform_interface.dart'; /// Customizable form that collects card information. @@ -17,6 +18,7 @@ class CardField extends StatefulWidget { this.enablePostalCode = false, this.style, this.autofocus = false, + this.dangerouslyGetFullCardDetails = false, this.cursorColor, this.numberHintText, this.expirationHintText, @@ -59,6 +61,15 @@ class CardField extends StatefulWidget { /// Default is `false`. final bool autofocus; + /// When true the Full card details will be returned. + /// + /// WARNING!!! Only do this if you're certain that you fulfill the necessary + /// PCI compliance requirements. Make sure that you're not mistakenly logging + /// or storing full card details! See the docs for + /// details: https://stripe.com/docs/security/guide#validating-pci-compliance + /// Default is `false`. + final bool dangerouslyGetFullCardDetails; + @override _CardFieldState createState() => _CardFieldState(); } @@ -135,9 +146,15 @@ class _CardFieldState extends State { final fontSize = widget.style?.fontSize ?? Theme.of(context).textTheme.subtitle1?.fontSize ?? kCardFieldDefaultFontSize; + + final fontFamily = widget.style?.fontFamily ?? + Theme.of(context).textTheme.subtitle1?.fontFamily ?? + kCardFieldDefaultFontFamily; + return CardStyle( textColor: widget.style?.color, fontSize: fontSize, + fontFamily: fontFamily, cursorColor: widget.cursorColor, textErrorColor: decoration.errorStyle?.color, placeholderColor: decoration.hintStyle?.color, @@ -235,6 +252,7 @@ class _MethodChannelCardFieldState extends State<_MethodChannelCardField> { baseTextStyle?.color ?? kCardFieldDefaultTextColor, fontSize: baseTextStyle?.fontSize ?? kCardFieldDefaultFontSize, + fontFamily: baseTextStyle?.fontFamily ?? kCardFieldDefaultFontFamily, textErrorColor: theme.inputDecorationTheme.errorStyle?.color ?? theme.errorColor, placeholderColor: @@ -469,6 +487,7 @@ class _UiKitCardField extends StatelessWidget { const kCardFieldDefaultHeight = 48.0; const kCardFieldDefaultFontSize = 17.0; const kCardFieldDefaultTextColor = Colors.black; +const kCardFieldDefaultFontFamily = 'Roboto'; typedef CardChangedCallback = void Function(CardFieldInputDetails? details); typedef CardFocusCallback = void Function(CardFieldName? focusedField); diff --git a/packages/stripe/pubspec.yaml b/packages/stripe/pubspec.yaml index 636a15d..73553cc 100644 --- a/packages/stripe/pubspec.yaml +++ b/packages/stripe/pubspec.yaml @@ -17,8 +17,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.11.0 - + flutter_lints: ^1.0.3 diff --git a/packages/stripe_android/android/build.gradle b/packages/stripe_android/android/build.gradle index f921574..6b0def7 100644 --- a/packages/stripe_android/android/build.gradle +++ b/packages/stripe_android/android/build.gradle @@ -38,8 +38,9 @@ android { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'com.stripe:stripe-android:16.8.2' + implementation 'com.stripe:stripe-android:16.10.0' implementation 'com.google.android.material:material:1.3.0' implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0' + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0' } diff --git a/packages/stripe_android/android/src/main/kotlin/com/facebook/react/bridge/BaseActivityEventListener.kt b/packages/stripe_android/android/src/main/kotlin/com/facebook/react/bridge/BaseActivityEventListener.kt index ddb18db..118eba4 100644 --- a/packages/stripe_android/android/src/main/kotlin/com/facebook/react/bridge/BaseActivityEventListener.kt +++ b/packages/stripe_android/android/src/main/kotlin/com/facebook/react/bridge/BaseActivityEventListener.kt @@ -8,14 +8,10 @@ import java.lang.ref.WeakReference abstract class BaseActivityEventListener : ActivityEventListener, ActivityResultListener { - var pluginInstance: StripeAndroidPlugin? = null - lateinit var activity: WeakReference override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?): Boolean { - if (pluginInstance != null && pluginInstance?.isInitialized == true) { - onActivityResult(activity.get(), requestCode, resultCode, data) - } + onActivityResult(activity.get(), requestCode, resultCode, data) return false } } \ No newline at end of file diff --git a/packages/stripe_android/android/src/main/kotlin/com/facebook/react/bridge/ReactApplicationContext.java b/packages/stripe_android/android/src/main/kotlin/com/facebook/react/bridge/ReactApplicationContext.java index 9f56686..39ecf20 100644 --- a/packages/stripe_android/android/src/main/kotlin/com/facebook/react/bridge/ReactApplicationContext.java +++ b/packages/stripe_android/android/src/main/kotlin/com/facebook/react/bridge/ReactApplicationContext.java @@ -14,17 +14,14 @@ public class ReactApplicationContext extends ContextWrapper { private final ActivityPluginBinding binding; - private final StripeAndroidPlugin pluginInstance; - public ReactApplicationContext(ActivityPluginBinding binding, StripeAndroidPlugin pluginInstance) { + public ReactApplicationContext(ActivityPluginBinding binding) { super(binding.getActivity()); this.binding = binding; - this.pluginInstance = pluginInstance; } public void addActivityEventListener(@NotNull BaseActivityEventListener activityEventListener) { - activityEventListener.activity = new WeakReference(binding.getActivity()); - activityEventListener.setPluginInstance(pluginInstance); + activityEventListener.activity = new WeakReference<>(binding.getActivity()); binding.addActivityResultListener(activityEventListener); } diff --git a/packages/stripe_android/android/src/main/kotlin/com/flutter/stripe/StripeAndroidPlugin.kt b/packages/stripe_android/android/src/main/kotlin/com/flutter/stripe/StripeAndroidPlugin.kt index bfc2496..fff22ef 100644 --- a/packages/stripe_android/android/src/main/kotlin/com/flutter/stripe/StripeAndroidPlugin.kt +++ b/packages/stripe_android/android/src/main/kotlin/com/flutter/stripe/StripeAndroidPlugin.kt @@ -27,10 +27,6 @@ class StripeAndroidPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { private lateinit var channel: MethodChannel lateinit var stripeSdk: StripeSdkModule - // set to true when the plugin has initialized - this is used as an indicator to receive - // activity results - var isInitialized = false - private val stripeSdkCardViewManager: StripeSdkCardViewManager by lazy { StripeSdkCardViewManager() } @@ -58,7 +54,6 @@ class StripeAndroidPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { params = ReadableMap(call.arguments as JSONObject), promise = Promise(result), ) - isInitialized = true } "createPaymentMethod" -> stripeSdk.createPaymentMethod( data = call.requiredArgument("data"), @@ -100,6 +95,10 @@ class StripeAndroidPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { "confirmPaymentSheetPayment" -> stripeSdk.confirmPaymentSheetPayment( promise = Promise(result) ) + "createToken" -> stripeSdk.createToken( + promise = Promise(result), + params = call.requiredArgument("params") + ) /*"registerConfirmSetupIntentCallbacks" -> stripeSdk.registerConfirmSetupIntentCallbacks( successCallback = Promise(result), errorCallback = Promise(result), @@ -118,7 +117,7 @@ class StripeAndroidPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { override fun onAttachedToActivity(binding: ActivityPluginBinding) { if (binding.activity is FlutterFragmentActivity) { - stripeSdk = StripeSdkModule(ReactApplicationContext(binding, this), stripeSdkCardViewManager) + stripeSdk = StripeSdkModule(ReactApplicationContext(binding), stripeSdkCardViewManager) } else { // no-op - will throw errors when method channel is called } diff --git a/packages/stripe_android/android/src/main/kotlin/com/flutter/stripe/StripeSdkCardPlatformView.kt b/packages/stripe_android/android/src/main/kotlin/com/flutter/stripe/StripeSdkCardPlatformView.kt index daa8961..1a428c4 100644 --- a/packages/stripe_android/android/src/main/kotlin/com/flutter/stripe/StripeSdkCardPlatformView.kt +++ b/packages/stripe_android/android/src/main/kotlin/com/flutter/stripe/StripeSdkCardPlatformView.kt @@ -41,6 +41,12 @@ class StripeSdkCardPlatformView( if (creationParams?.containsKey("postalCodeEnabled") == true) { stripeSdkCardViewManager.setPostalCodeEnabled(cardView, creationParams["postalCodeEnabled"] as Boolean) } + if (creationParams?.containsKey("dangerouslyGetFullCardDetails") == true) { + stripeSdkCardViewManager.setDangerouslyGetFullCardDetails(cardView, creationParams["dangerouslyGetFullCardDetails"] as Boolean) + } + if (creationParams?.containsKey("autofocus") == true) { + stripeSdkCardViewManager.setAutofocus(cardView, creationParams["autofocus"] as Boolean) + } applyFocusFix() } @@ -90,7 +96,17 @@ class StripeSdkCardPlatformView( } "onPostalCodeEnabledChanged" -> { val arguments = ReadableMap(call.arguments as Map) - stripeSdkCardViewManager.setPostalCodeEnabled(cardView, arguments.getBoolean("postalCodeEnabled") as Boolean) + stripeSdkCardViewManager.setPostalCodeEnabled(cardView, arguments.getBoolean("postalCodeEnabled")) + result.success(null) + } + "dangerouslyGetFullCardDetails" -> { + val arguments = ReadableMap(call.arguments as Map) + stripeSdkCardViewManager.setDangerouslyGetFullCardDetails(cardView, arguments.getBoolean("dangerouslyGetFullCardDetails")) + result.success(null) + } + "autofocus" -> { + val arguments = ReadableMap(call.arguments as Map) + stripeSdkCardViewManager.setAutofocus(cardView, arguments.getBoolean("autofocus")) result.success(null) } "requestFocus" -> { diff --git a/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/CardChangedEvent.kt b/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/CardChangedEvent.kt index 93fb805..d084f30 100644 --- a/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/CardChangedEvent.kt +++ b/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/CardChangedEvent.kt @@ -5,7 +5,7 @@ import com.facebook.react.bridge.WritableMap import com.facebook.react.uimanager.events.Event import com.facebook.react.uimanager.events.RCTEventEmitter -internal class CardChangedEvent constructor(viewTag: Int, private val cardDetails: MutableMap, private val postalCodeEnabled: Boolean, private val complete: Boolean) : Event(viewTag) { +internal class CardChangedEvent constructor(viewTag: Int, private val cardDetails: MutableMap, private val postalCodeEnabled: Boolean, private val complete: Boolean, private val dangerouslyGetFullCardDetails: Boolean) : Event(viewTag) { override fun getEventName(): String { return EVENT_NAME } @@ -22,14 +22,29 @@ internal class CardChangedEvent constructor(viewTag: Int, private val cardDetail val eventData = Arguments.createMap() eventData.putString("brand", cardDetails["brand"]?.toString()) eventData.putString("last4", cardDetails["last4"]?.toString()) - eventData.putString("expiryMonth", cardDetails["expiryMonth"]?.toString()) - eventData.putString("expiryYear", cardDetails["expiryYear"]?.toString()) + + (cardDetails["expiryMonth"] as Int?)?.let { + eventData.putInt("expiryMonth", it) + } ?: run { + eventData.putNull("expiryMonth") + } + + (cardDetails["expiryYear"] as Int?)?.let { + eventData.putInt("expiryYear", it) + } ?: run { + eventData.putNull("expiryYear") + } + eventData.putBoolean("complete", complete) if (postalCodeEnabled) { eventData.putString("postalCode", cardDetails["postalCode"]?.toString()) } + if (dangerouslyGetFullCardDetails) { + eventData.putString("number", cardDetails["number"]?.toString()?.replace(" ", "")) + } + return eventData } diff --git a/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/Errors.kt b/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/Errors.kt index 106c4f7..eea67eb 100644 --- a/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/Errors.kt +++ b/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/Errors.kt @@ -2,11 +2,21 @@ package com.reactnativestripesdk import com.facebook.react.bridge.WritableMap import com.facebook.react.bridge.WritableNativeMap +import com.stripe.android.exception.APIException +import com.stripe.android.exception.AuthenticationException +import com.stripe.android.exception.CardException +import com.stripe.android.exception.InvalidRequestException +import com.stripe.android.model.PaymentIntent +import com.stripe.android.model.SetupIntent enum class ConfirmPaymentErrorType { Failed, Canceled, Unknown } +enum class CreateTokenErrorType { + Failed +} + enum class NextPaymentActionErrorType { Failed, Canceled, Unknown } @@ -19,14 +29,58 @@ enum class RetrievePaymentIntentErrorType { Unknown } +enum class RetrieveSetupIntentErrorType { + Unknown +} + enum class PaymentSheetErrorType { Failed, Canceled } -internal fun createError(errorType: String, message: String): WritableMap { +internal fun mapError(code: String, message: String?, localizedMessage: String?, declineCode: String?, type: String?, stripeErrorCode: String?): WritableMap { val map: WritableMap = WritableNativeMap() - map.putString("message", message) - map.putString("code", errorType) + val details: WritableMap = WritableNativeMap() + details.putString("code", code) + details.putString("message", message) + details.putString("localizedMessage", localizedMessage) + details.putString("declineCode", declineCode) + details.putString("type", type) + details.putString("stripeErrorCode", stripeErrorCode) + map.putMap("error", details) return map } + +internal fun createError(code: String, message: String?): WritableMap { + return mapError(code, message, message, null, null, null) +} + +internal fun createError(code: String, error: PaymentIntent.Error?): WritableMap { + return mapError(code, error?.message, error?.message, error?.declineCode, error?.type?.code, error?.code) +} + +internal fun createError(code: String, error: SetupIntent.Error?): WritableMap { + return mapError(code, error?.message, error?.message, error?.declineCode, error?.type?.code, error?.code) +} + +internal fun createError(code: String, error: Exception): WritableMap { + return when (error) { + is CardException -> { + mapError(code, error.message, error.localizedMessage, error.declineCode, error.stripeError?.type, error.stripeError?.code) + } + is InvalidRequestException -> { + mapError(code, error.message, error.localizedMessage, error.stripeError?.declineCode, error.stripeError?.type, error.stripeError?.code) + } + is AuthenticationException -> { + mapError(code, error.message, error.localizedMessage, error.stripeError?.declineCode, error.stripeError?.type, error.stripeError?.code) + } + is APIException -> { + mapError(code, error.message, error.localizedMessage, error.stripeError?.declineCode, error.stripeError?.type, error.stripeError?.code) + } + else -> mapError(code, error.message, error.localizedMessage.orEmpty(), null, null, null) + } +} + +internal fun createError(code: String, error: Throwable): WritableMap { + return mapError(code, error.message, error.localizedMessage, null, null, null) +} diff --git a/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/Mappers.kt b/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/Mappers.kt index b67917e..396f98e 100644 --- a/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/Mappers.kt +++ b/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/Mappers.kt @@ -4,6 +4,11 @@ import com.facebook.react.bridge.* import com.stripe.android.PaymentAuthConfig import com.stripe.android.model.* +internal fun createResult(key: String, value: WritableMap): WritableMap { + val map = WritableNativeMap() + map.putMap(key, value) + return map +} internal fun mapIntentStatus(status: StripeIntent.Status?): String { return when (status) { @@ -142,6 +147,110 @@ internal fun mapFromBillingDetails(billingDatails: PaymentMethod.BillingDetails? return details } +internal fun mapTokenType(type: Token.Type): String { + return when (type) { + Token.Type.Account -> "Account" + Token.Type.BankAccount -> "BankAccount" + Token.Type.Card -> "Card" + Token.Type.CvcUpdate -> "CvcUpdate" + Token.Type.Person -> "Person" + Token.Type.Pii -> "Pii" + else -> "Unknown" + } +} + +internal fun mapFromBankAccountType(type: BankAccount.Type?): String { + return when (type) { + BankAccount.Type.Company -> "Company" + BankAccount.Type.Individual -> "Individual" + else -> "Unknown" + } +} + +internal fun mapFromBankAccountStatus(status: BankAccount.Status?): String { + return when (status) { + BankAccount.Status.Errored -> "Errored" + BankAccount.Status.New -> "New" + BankAccount.Status.Validated -> "Validated" + BankAccount.Status.VerificationFailed -> "VerificationFailed" + BankAccount.Status.Verified -> "Verified" + else -> "Unknown" + } +} + +internal fun mapFromBankAccount(bankAccount: BankAccount?): WritableMap? { + val bankAccountMap: WritableMap = WritableNativeMap() + + if (bankAccount == null) { + return null + } + + bankAccountMap.putString("bankName", bankAccount.bankName) + bankAccountMap.putString("accountHolderName", bankAccount.accountHolderName) + bankAccountMap.putString("accountHolderType", mapFromBankAccountType(bankAccount.accountHolderType)) + bankAccountMap.putString("currency", bankAccount.currency) + bankAccountMap.putString("country", bankAccount.countryCode) + bankAccountMap.putString("routingNumber", bankAccount.routingNumber) + bankAccountMap.putString("status", mapFromBankAccountStatus(bankAccount.status)) + + return bankAccountMap +} + +internal fun mapFromCard(card: Card?): WritableMap? { + val cardMap: WritableMap = WritableNativeMap() + + if (card == null) { + return null + } + + val address: WritableMap = WritableNativeMap() + + cardMap.putString("country", card.country) + cardMap.putString("brand", mapCardBrand(card.brand)) + cardMap.putString("currency", card.currency) + + (card.expMonth)?.let { + cardMap.putInt("expMonth", it) + } ?: run { + cardMap.putNull("expMonth") + } + + (card.expYear)?.let { + cardMap.putInt("expYear", it) + } ?: run { + cardMap.putNull("expYear") + } + + cardMap.putString("last4", card.last4) + cardMap.putString("funding", card.funding?.name) + cardMap.putString("name", card.name) + + address.putString("city", card.addressCity) + address.putString("country", card.addressCountry) + address.putString("line1", card.addressLine1) + address.putString("line2", card.addressLine2) + address.putString("state", card.addressState) + address.putString("postalCode", card.addressZip) + + cardMap.putMap("address", address) + + return cardMap +} + + +internal fun mapFromToken(token: Token): WritableMap { + val tokenMap: WritableMap = WritableNativeMap() + + tokenMap.putString("id", token.id) + tokenMap.putString("created", token.created.time.toString()) + tokenMap.putString("type", mapTokenType(token.type)) + tokenMap.putBoolean("livemode", token.livemode) + tokenMap.putMap("bankAccount", mapFromBankAccount(token.bankAccount)) + tokenMap.putMap("card", mapFromCard(token.card)) + + return tokenMap +} + internal fun mapFromPaymentMethod(paymentMethod: PaymentMethod): WritableMap { val pm: WritableMap = WritableNativeMap() val card: WritableMap = WritableNativeMap() @@ -216,7 +325,7 @@ internal fun mapFromPaymentIntentResult(paymentIntent: PaymentIntent): WritableM map.putString("status", mapIntentStatus(paymentIntent.status)) map.putString("description", paymentIntent.description) map.putString("receiptEmail", paymentIntent.receiptEmail) - map.putInt("created", convertToUnixTimestamp(paymentIntent.created)) + map.putString("created", convertToUnixTimestamp(paymentIntent.created)) map.putString("captureMethod", mapCaptureMethod(paymentIntent.captureMethod)) map.putString("confirmationMethod", mapConfirmationMethod(paymentIntent.confirmationMethod)) map.putNull("lastPaymentError") @@ -246,21 +355,34 @@ internal fun mapFromPaymentIntentResult(paymentIntent: PaymentIntent): WritableM map.putDouble("amount", it.toDouble()) } paymentIntent.canceledAt?.let { - map.putInt("canceledAt", convertToUnixTimestamp(it)) + map.putString("canceledAt", convertToUnixTimestamp(it)) } return map } internal fun mapFromPaymentIntentLastErrorType(errorType: PaymentIntent.Error.Type?): String? { return when (errorType) { - PaymentIntent.Error.Type.ApiConnectionError -> "ApiConnection" - PaymentIntent.Error.Type.AuthenticationError -> "Authentication" - PaymentIntent.Error.Type.ApiError -> "Api" - PaymentIntent.Error.Type.CardError -> "Card" - PaymentIntent.Error.Type.IdempotencyError -> "Idempotency" - PaymentIntent.Error.Type.InvalidRequestError -> "InvalidRequest" - PaymentIntent.Error.Type.RateLimitError -> "RateLimit" - else -> "Unknown" + PaymentIntent.Error.Type.ApiConnectionError -> "api_connection_error" + PaymentIntent.Error.Type.AuthenticationError -> "authentication_error" + PaymentIntent.Error.Type.ApiError -> "api_error" + PaymentIntent.Error.Type.CardError -> "card_error" + PaymentIntent.Error.Type.IdempotencyError -> "idempotency_error" + PaymentIntent.Error.Type.InvalidRequestError -> "invalid_request_error" + PaymentIntent.Error.Type.RateLimitError -> "rate_limit_error" + else -> null + } +} + +internal fun mapFromSetupIntentLastErrorType(errorType: SetupIntent.Error.Type?): String? { + return when (errorType) { + SetupIntent.Error.Type.ApiConnectionError -> "api_connection_error" + SetupIntent.Error.Type.AuthenticationError -> "authentication_error" + SetupIntent.Error.Type.ApiError -> "api_error" + SetupIntent.Error.Type.CardError -> "card_error" + SetupIntent.Error.Type.IdempotencyError -> "idempotency_error" + SetupIntent.Error.Type.InvalidRequestError -> "invalid_request_error" + SetupIntent.Error.Type.RateLimitError -> "rate_limit_error" + else -> null } } @@ -268,6 +390,20 @@ fun getValOr(map: ReadableMap, key: String, default: String? = ""): String? { return if (map.hasKey(key)) map.getString(key) else default } +internal fun mapToAddress(addressMap: ReadableMap?): Address? { + if (addressMap == null) { + return null + } + return Address.Builder() + .setPostalCode(getValOr(addressMap, "postalCode")) + .setCity(getValOr(addressMap, "city")) + .setCountry(getValOr(addressMap, "country")) + .setLine1(getValOr(addressMap, "line1")) + .setLine2(getValOr(addressMap, "line2")) + .setState(getValOr(addressMap, "state")) + .build() +} + internal fun mapToBillingDetails(billingDetails: ReadableMap?): PaymentMethod.BillingDetails? { if (billingDetails == null) { return null @@ -327,20 +463,29 @@ fun getBooleanOrFalse(map: ReadableMap?, key: String): Boolean { return if (map?.hasKey(key) == true) map.getBoolean(key) else false } -private fun convertToUnixTimestamp(timestamp: Long): Int { - return (timestamp * 1000).toInt() +private fun convertToUnixTimestamp(timestamp: Long): String { + return (timestamp * 1000).toInt().toString() } fun mapToUICustomization(params: ReadableMap): PaymentAuthConfig.Stripe3ds2UiCustomization { val labelCustomization = getMapOrNull(params, "label") val navigationBarCustomization = params.getMap("navigationBar") val textBoxCustomization = getMapOrNull(params, "textField") - val buttonCustomization = getMapOrNull(params, "submitButton") + val submitButtonCustomization = getMapOrNull(params, "submitButton") + val cancelButtonCustomization = getMapOrNull(params, "cancelButton") + val nextButtonCustomization = getMapOrNull(params, "nextButton") + val continueButtonCustomization = getMapOrNull(params, "continueButton") + val resendButtonCustomization = getMapOrNull(params, "resendButton") val labelCustomizationBuilder = PaymentAuthConfig.Stripe3ds2LabelCustomization.Builder() val toolbarCustomizationBuilder = PaymentAuthConfig.Stripe3ds2ToolbarCustomization.Builder() val textBoxCustomizationBuilder = PaymentAuthConfig.Stripe3ds2TextBoxCustomization.Builder() - val buttonCustomizationBuilder = PaymentAuthConfig.Stripe3ds2ButtonCustomization.Builder() + + val submitButtonCustomizationBuilder = PaymentAuthConfig.Stripe3ds2ButtonCustomization.Builder() + val cancelButtonCustomizationBuilder = PaymentAuthConfig.Stripe3ds2ButtonCustomization.Builder() + val nextButtonCustomizationBuilder = PaymentAuthConfig.Stripe3ds2ButtonCustomization.Builder() + val continueButtonCustomizationBuilder = PaymentAuthConfig.Stripe3ds2ButtonCustomization.Builder() + val resendButtonCustomizationBuilder = PaymentAuthConfig.Stripe3ds2ButtonCustomization.Builder() getStringOrNull(labelCustomization,"headingTextColor")?.let { labelCustomizationBuilder.setHeadingTextColor(it) @@ -390,20 +535,78 @@ fun mapToUICustomization(params: ReadableMap): PaymentAuthConfig.Stripe3ds2UiCus textBoxCustomizationBuilder.setTextFontSize(it) } - getStringOrNull(buttonCustomization, "backgroundColor")?.let { - buttonCustomizationBuilder.setBackgroundColor(it) + // Submit button + getStringOrNull(submitButtonCustomization, "backgroundColor")?.let { + submitButtonCustomizationBuilder.setBackgroundColor(it) + } + getIntOrNull(submitButtonCustomization, "borderRadius")?.let { + submitButtonCustomizationBuilder.setCornerRadius(it) + } + getStringOrNull(submitButtonCustomization, "textColor")?.let { + submitButtonCustomizationBuilder.setTextColor(it) + } + getIntOrNull(submitButtonCustomization, "textFontSize")?.let { + submitButtonCustomizationBuilder.setTextFontSize(it) + } + + // Cancel button + getStringOrNull(cancelButtonCustomization, "backgroundColor")?.let { + cancelButtonCustomizationBuilder.setBackgroundColor(it) + } + getIntOrNull(cancelButtonCustomization, "borderRadius")?.let { + cancelButtonCustomizationBuilder.setCornerRadius(it) + } + getStringOrNull(cancelButtonCustomization, "textColor")?.let { + cancelButtonCustomizationBuilder.setTextColor(it) + } + getIntOrNull(cancelButtonCustomization, "textFontSize")?.let { + cancelButtonCustomizationBuilder.setTextFontSize(it) + } + + // Continue button + getStringOrNull(continueButtonCustomization, "backgroundColor")?.let { + continueButtonCustomizationBuilder.setBackgroundColor(it) + } + getIntOrNull(continueButtonCustomization, "borderRadius")?.let { + continueButtonCustomizationBuilder.setCornerRadius(it) + } + getStringOrNull(continueButtonCustomization, "textColor")?.let { + continueButtonCustomizationBuilder.setTextColor(it) + } + getIntOrNull(continueButtonCustomization, "textFontSize")?.let { + continueButtonCustomizationBuilder.setTextFontSize(it) + } + + // Next button + getStringOrNull(nextButtonCustomization, "backgroundColor")?.let { + nextButtonCustomizationBuilder.setBackgroundColor(it) + } + getIntOrNull(nextButtonCustomization, "borderRadius")?.let { + nextButtonCustomizationBuilder.setCornerRadius(it) + } + getStringOrNull(nextButtonCustomization, "textColor")?.let { + nextButtonCustomizationBuilder.setTextColor(it) + } + getIntOrNull(nextButtonCustomization, "textFontSize")?.let { + nextButtonCustomizationBuilder.setTextFontSize(it) + } + + // Resend button + getStringOrNull(resendButtonCustomization, "backgroundColor")?.let { + resendButtonCustomizationBuilder.setBackgroundColor(it) } - getIntOrNull(buttonCustomization, "borderRadius")?.let { - buttonCustomizationBuilder.setCornerRadius(it) + getIntOrNull(resendButtonCustomization, "borderRadius")?.let { + resendButtonCustomizationBuilder.setCornerRadius(it) } - getStringOrNull(buttonCustomization, "textColor")?.let { - buttonCustomizationBuilder.setTextColor(it) + getStringOrNull(resendButtonCustomization, "textColor")?.let { + resendButtonCustomizationBuilder.setTextColor(it) } - getIntOrNull(buttonCustomization, "textFontSize")?.let { - buttonCustomizationBuilder.setTextFontSize(it) + getIntOrNull(resendButtonCustomization, "textFontSize")?.let { + resendButtonCustomizationBuilder.setTextFontSize(it) } + val uiCustomization = PaymentAuthConfig.Stripe3ds2UiCustomization.Builder() .setLabelCustomization( labelCustomizationBuilder.build() @@ -412,16 +615,27 @@ fun mapToUICustomization(params: ReadableMap): PaymentAuthConfig.Stripe3ds2UiCus toolbarCustomizationBuilder.build() ) .setButtonCustomization( - buttonCustomizationBuilder.build(), + submitButtonCustomizationBuilder.build(), PaymentAuthConfig.Stripe3ds2UiCustomization.ButtonType.SUBMIT ) - .setButtonCustomization( - buttonCustomizationBuilder.build(), + continueButtonCustomizationBuilder.build(), PaymentAuthConfig.Stripe3ds2UiCustomization.ButtonType.CONTINUE ) + .setButtonCustomization( + nextButtonCustomizationBuilder.build(), + PaymentAuthConfig.Stripe3ds2UiCustomization.ButtonType.SELECT + ) + .setButtonCustomization( + cancelButtonCustomizationBuilder.build(), + PaymentAuthConfig.Stripe3ds2UiCustomization.ButtonType.CANCEL + ) + .setButtonCustomization( + resendButtonCustomizationBuilder.build(), + PaymentAuthConfig.Stripe3ds2UiCustomization.ButtonType.RESEND + ) - getStringOrNull(params, "backgroundColor")?.let { + getStringOrNull(params, "accentColor")?.let { uiCustomization.setAccentColor(it) } @@ -440,13 +654,18 @@ internal fun mapFromSetupIntentResult(setupIntent: SetupIntent): WritableMap { map.putString("usage", mapSetupIntentUsage(setupIntent.usage)) if(setupIntent.created != null) { - map.putInt("created", convertToUnixTimestamp(setupIntent.created)) + map.putString("created", convertToUnixTimestamp(setupIntent.created)) } setupIntent.lastSetupError?.let { val setupError: WritableMap = WritableNativeMap() setupError.putString("code", it.code) setupError.putString("message", it.message) + setupError.putString("type", mapFromSetupIntentLastErrorType(it.type)) + + setupIntent.lastSetupError?.paymentMethod?.let { paymentMethod -> + setupError.putMap("paymentMethod", mapFromPaymentMethod(paymentMethod)) + } map.putMap("lastSetupError", setupError) } diff --git a/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/PaymentMethodCreateParamsFactory.kt b/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/PaymentMethodCreateParamsFactory.kt index b781ad2..dcef630 100644 --- a/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/PaymentMethodCreateParamsFactory.kt +++ b/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/PaymentMethodCreateParamsFactory.kt @@ -92,7 +92,7 @@ class PaymentMethodCreateParamsFactory(private val clientSecret: String, private val token = getValOr(params, "token", null) if (cardParams == null && paymentMethodId == null && token == null) { - throw PaymentMethodCreateParamsException("You must provide cardDetails, token or paymentMethodId") + throw PaymentMethodCreateParamsException("Card details not complete") } val setupFutureUsage = mapToPaymentIntentFutureUsage(getValOr(params, "setupFutureUsage")) diff --git a/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/PaymentSheetFragment.kt b/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/PaymentSheetFragment.kt index 692c601..08d99e0 100644 --- a/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/PaymentSheetFragment.kt +++ b/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/PaymentSheetFragment.kt @@ -22,6 +22,8 @@ import java.io.ByteArrayOutputStream class PaymentSheetFragment : Fragment() { private var paymentSheet: PaymentSheet? = null private var flowController: PaymentSheet.FlowController? = null + private var paymentIntentClientSecret: String? = null + private var setupIntentClientSecret: String? = null private lateinit var paymentSheetConfiguration: PaymentSheet.Configuration override fun onCreateView( @@ -39,9 +41,10 @@ class PaymentSheetFragment : Fragment() { val merchantDisplayName = arguments?.getString("merchantDisplayName").orEmpty() val customerId = arguments?.getString("customerId").orEmpty() val customerEphemeralKeySecret = arguments?.getString("customerEphemeralKeySecret").orEmpty() - val paymentIntentClientSecret = arguments?.getString("paymentIntentClientSecret").orEmpty() val countryCode = arguments?.getString("countryCode").orEmpty() val testEnv = arguments?.getBoolean("testEnv") + paymentIntentClientSecret = arguments?.getString("paymentIntentClientSecret").orEmpty() + setupIntentClientSecret = arguments?.getString("setupIntentClientSecret").orEmpty() val paymentOptionCallback = object: PaymentOptionCallback { override fun onPaymentOption(paymentOption: PaymentOption?) { @@ -67,7 +70,7 @@ class PaymentSheetFragment : Fragment() { } } - this.paymentSheetConfiguration = PaymentSheet.Configuration( + paymentSheetConfiguration = PaymentSheet.Configuration( merchantDisplayName = merchantDisplayName, customer = if (customerId.isNotEmpty() && customerEphemeralKeySecret.isNotEmpty()) PaymentSheet.CustomerConfiguration( id = customerId, @@ -81,7 +84,7 @@ class PaymentSheetFragment : Fragment() { if (arguments?.getBoolean("customFlow") == true) { flowController = PaymentSheet.FlowController.create(this, paymentOptionCallback, paymentResultCallback) - configureFlowController(paymentIntentClientSecret) + configureFlowController() } else { paymentSheet = PaymentSheet(this, paymentResultCallback) } @@ -90,8 +93,12 @@ class PaymentSheetFragment : Fragment() { activity?.sendBroadcast(intent) } - fun present(clientSecret: String) { - paymentSheet?.presentWithPaymentIntent(clientSecret, paymentSheetConfiguration) + fun present() { + if (!paymentIntentClientSecret.isNullOrEmpty()) { + paymentSheet?.presentWithPaymentIntent(paymentIntentClientSecret!!, paymentSheetConfiguration) + } else if (!setupIntentClientSecret.isNullOrEmpty()) { + paymentSheet?.presentWithSetupIntent(setupIntentClientSecret!!, paymentSheetConfiguration) + } } fun presentPaymentOptions() { @@ -102,7 +109,7 @@ class PaymentSheetFragment : Fragment() { flowController?.confirm() } - private fun configureFlowController(paymentIntentClientSecret: String) { + private fun configureFlowController() { val onFlowControllerConfigure = object : PaymentSheet.FlowController.ConfigCallback { override fun onConfigured(success: Boolean, error: Throwable?) { val paymentOption = flowController?.getPaymentOption() @@ -119,11 +126,19 @@ class PaymentSheetFragment : Fragment() { } } - flowController?.configureWithPaymentIntent( - paymentIntentClientSecret = paymentIntentClientSecret, - configuration = this.paymentSheetConfiguration, - callback = onFlowControllerConfigure - ) + if (!paymentIntentClientSecret.isNullOrEmpty()) { + flowController?.configureWithPaymentIntent( + paymentIntentClientSecret = paymentIntentClientSecret!!, + configuration = paymentSheetConfiguration, + callback = onFlowControllerConfigure + ) + } else if (!setupIntentClientSecret.isNullOrEmpty()) { + flowController?.configureWithSetupIntent( + setupIntentClientSecret = setupIntentClientSecret!!, + configuration = paymentSheetConfiguration, + callback = onFlowControllerConfigure + ) + } } } diff --git a/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/StripeSdkCardView.kt b/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/StripeSdkCardView.kt index 8b7f38e..b346168 100644 --- a/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/StripeSdkCardView.kt +++ b/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/StripeSdkCardView.kt @@ -1,27 +1,33 @@ package com.reactnativestripesdk +import android.content.Context import android.content.res.ColorStateList import android.graphics.Color +import android.graphics.Typeface import android.text.Editable import android.text.TextWatcher +import android.view.View +import android.view.inputmethod.InputMethodManager import android.widget.FrameLayout import com.facebook.react.bridge.ReadableMap import com.facebook.react.uimanager.ThemedReactContext import com.facebook.react.uimanager.UIManagerModule import com.facebook.react.uimanager.events.EventDispatcher -import com.stripe.android.databinding.CardInputWidgetBinding import com.google.android.material.shape.CornerFamily import com.google.android.material.shape.MaterialShapeDrawable import com.google.android.material.shape.ShapeAppearanceModel +import com.stripe.android.databinding.CardInputWidgetBinding import com.stripe.android.model.PaymentMethodCreateParams import com.stripe.android.view.CardInputListener import com.stripe.android.view.CardInputWidget + class StripeSdkCardView(private val context: ThemedReactContext) : FrameLayout(context) { var mCardWidget: CardInputWidget - val cardDetails: MutableMap = mutableMapOf("brand" to "", "last4" to "", "expiryMonth" to "", "expiryYear" to "", "postalCode" to "") + val cardDetails: MutableMap = mutableMapOf("brand" to "", "last4" to "", "expiryMonth" to null, "expiryYear" to null, "postalCode" to "") var cardParams: PaymentMethodCreateParams.Card? = null private var mEventDispatcher: EventDispatcher? + private var dangerouslyGetFullCardDetails: Boolean = false init { mCardWidget = CardInputWidget(context); @@ -38,6 +44,15 @@ class StripeSdkCardView(private val context: ThemedReactContext) : FrameLayout(c viewTreeObserver.addOnGlobalLayoutListener { requestLayout() } } + fun setAutofocus(value: Boolean) { + if (value) { + val binding = CardInputWidgetBinding.bind(mCardWidget) + binding.cardNumberEditText.requestFocus() + binding.cardNumberEditText.showSoftKeyboard() + } + } + + fun setCardStyle(value: ReadableMap) { val binding = CardInputWidgetBinding.bind(mCardWidget) val borderWidth = getIntOrNull(value, "borderWidth") @@ -45,7 +60,8 @@ class StripeSdkCardView(private val context: ThemedReactContext) : FrameLayout(c val borderColor = getValOr(value, "borderColor", null) val borderRadius = getIntOrNull(value, "borderRadius") ?: 0 val textColor = getValOr(value, "textColor", null) - val fontSize = getIntOrNull(value,"fontSize") + val fontSize = getIntOrNull(value, "fontSize") + val fontFamily = getValOr(value, "fontFamily") val placeholderColor = getValOr(value, "placeholderColor", null) val textErrorColor = getValOr(value, "textErrorColor", null) @@ -73,8 +89,14 @@ class StripeSdkCardView(private val context: ThemedReactContext) : FrameLayout(c binding.expiryDateEditText.textSize = it.toFloat() binding.postalCodeEditText.textSize = it.toFloat() } + fontFamily?.let { + binding.cardNumberEditText.typeface = Typeface.create(it, Typeface.NORMAL) + binding.cvcEditText.typeface = Typeface.create(it, Typeface.NORMAL) + binding.expiryDateEditText.typeface = Typeface.create(it, Typeface.NORMAL) + binding.postalCodeEditText.typeface = Typeface.create(it, Typeface.NORMAL) + } - mCardWidget.setPadding(40, 0 ,40 ,0) + mCardWidget.setPadding(40, 0, 40, 0) mCardWidget.background = MaterialShapeDrawable( ShapeAppearanceModel() .toBuilder() @@ -117,37 +139,39 @@ class StripeSdkCardView(private val context: ThemedReactContext) : FrameLayout(c } } + fun setDangerouslyGetFullCardDetails(isEnabled: Boolean) { + dangerouslyGetFullCardDetails = isEnabled + } + fun setPostalCodeEnabled(isEnabled: Boolean) { mCardWidget.postalCodeEnabled = isEnabled } - fun getValue(): MutableMap { + fun getValue(): MutableMap { return cardDetails } fun onCardChanged() { - mCardWidget.paymentMethodCard?.let { cardParams = it } + mCardWidget.paymentMethodCard?.let { cardParams = it } ?: run { + cardParams = null + } + mCardWidget.cardParams?.let { + cardDetails["brand"] = mapCardBrand(it.brand) + cardDetails["last4"] = it.last4 + } ?: run { + cardDetails["brand"] = null + cardDetails["last4"] = null + } mEventDispatcher?.dispatchEvent( - CardChangedEvent(id, cardDetails, mCardWidget.postalCodeEnabled, cardParams != null)) + CardChangedEvent(id, cardDetails, mCardWidget.postalCodeEnabled, cardParams != null, dangerouslyGetFullCardDetails)) } private fun setListeners() { mCardWidget.setCardInputListener(object : CardInputListener { - override fun onCardComplete() { - mCardWidget.cardParams?.let { - cardDetails["brand"] = mapCardBrand(it.brand) - cardDetails["last4"] = it.last4 - } - onCardChanged() - } + override fun onCardComplete() {} override fun onExpirationComplete() {} - override fun onCvcComplete() { - mCardWidget.cardParams?.let { - cardDetails["brand"] = mapCardBrand(it.brand) - cardDetails["last4"] = it.last4 - } - onCardChanged() - } + override fun onCvcComplete() {} + override fun onFocusChange(focusField: CardInputListener.FocusField) { if (mEventDispatcher != null) { mEventDispatcher?.dispatchEvent( @@ -161,10 +185,10 @@ class StripeSdkCardView(private val context: ThemedReactContext) : FrameLayout(c override fun afterTextChanged(p0: Editable?) {} override fun onTextChanged(var1: CharSequence?, var2: Int, var3: Int, var4: Int) { val splitted = var1.toString().split("/") - cardDetails["expiryMonth"] = splitted[0] + cardDetails["expiryMonth"] = splitted[0].toIntOrNull() if (splitted.size == 2) { - cardDetails["expiryYear"] = var1.toString().split("/")[1] + cardDetails["expiryYear"] = var1.toString().split("/")[1].toIntOrNull() } onCardChanged() @@ -180,6 +204,24 @@ class StripeSdkCardView(private val context: ThemedReactContext) : FrameLayout(c } }) + mCardWidget.setCardNumberTextWatcher(object : TextWatcher { + override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {} + override fun afterTextChanged(p0: Editable?) {} + override fun onTextChanged(var1: CharSequence?, var2: Int, var3: Int, var4: Int) { + if (dangerouslyGetFullCardDetails) { + cardDetails["number"] = var1.toString().replace(" ", "") + } + onCardChanged() + } + }) + + mCardWidget.setCvcNumberTextWatcher(object : TextWatcher { + override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {} + override fun afterTextChanged(p0: Editable?) {} + override fun onTextChanged(var1: CharSequence?, var2: Int, var3: Int, var4: Int) { + onCardChanged() + } + }) } override fun requestLayout() { @@ -194,3 +236,12 @@ class StripeSdkCardView(private val context: ThemedReactContext) : FrameLayout(c layout(left, top, right, bottom) } } + +fun View.showSoftKeyboard() { + post { + if (this.requestFocus()) { + val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager? + imm?.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT) + } + } +} diff --git a/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/StripeSdkCardViewManager.kt b/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/StripeSdkCardViewManager.kt index c41d6a6..e018731 100644 --- a/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/StripeSdkCardViewManager.kt +++ b/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/StripeSdkCardViewManager.kt @@ -1,6 +1,6 @@ package com.reactnativestripesdk -import com.facebook.react.bridge.ReadableMap +import com.facebook.react.bridge.* import com.facebook.react.common.MapBuilder import com.facebook.react.uimanager.SimpleViewManager import com.facebook.react.uimanager.ThemedReactContext @@ -19,11 +19,21 @@ class StripeSdkCardViewManager : SimpleViewManager() { CardChangedEvent.EVENT_NAME, MapBuilder.of("registrationName", "onCardChange")) } + @ReactProp(name = "dangerouslyGetFullCardDetails") + fun setDangerouslyGetFullCardDetails(view: StripeSdkCardView, dangerouslyGetFullCardDetails: Boolean = false) { + view.setDangerouslyGetFullCardDetails(dangerouslyGetFullCardDetails); + } + @ReactProp(name = "postalCodeEnabled") fun setPostalCodeEnabled(view: StripeSdkCardView, postalCodeEnabled: Boolean = true) { view.setPostalCodeEnabled(postalCodeEnabled); } + @ReactProp(name = "autofocus") + fun setAutofocus(view: StripeSdkCardView, autofocus: Boolean = false) { + view.setAutofocus(autofocus); + } + @ReactProp(name = "cardStyle") fun setCardStyle(view: StripeSdkCardView, cardStyle: ReadableMap) { view.setCardStyle(cardStyle); diff --git a/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/StripeSdkModule.kt b/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/StripeSdkModule.kt index 2bd82ce..6576adf 100644 --- a/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/StripeSdkModule.kt +++ b/packages/stripe_android/android/src/main/kotlin/com/reactnativestripesdk/StripeSdkModule.kt @@ -15,7 +15,7 @@ import com.stripe.android.* import com.stripe.android.model.* import com.stripe.android.paymentsheet.PaymentSheetResult import com.stripe.android.view.AddPaymentMethodActivityStarter - +import kotlinx.coroutines.runBlocking class StripeSdkModule(reactContext: ReactApplicationContext, cardFieldManager: StripeSdkCardViewManager) : ReactContextBaseJavaModule(reactContext) { private var cardFieldManager: StripeSdkCardViewManager = cardFieldManager @@ -23,131 +23,136 @@ class StripeSdkModule(reactContext: ReactApplicationContext, cardFieldManager: S override fun getName(): String { return "StripeSdk" } + private lateinit var stripe: Stripe private lateinit var publishableKey: String + private var stripeAccountId: String? = null private var paymentSheetFragment: PaymentSheetFragment? = null - private var onConfirmSetupIntentError: Callback? = null - private var onConfirmSetupIntentSuccess: Callback? = null private var urlScheme: String? = null - private var confirmPromise: Promise? = null private var handleCardActionPromise: Promise? = null private var confirmSetupIntentPromise: Promise? = null private var confirmPaymentSheetPaymentPromise: Promise? = null private var presentPaymentSheetPromise: Promise? = null private var initPaymentSheetPromise: Promise? = null - private var confirmPaymentClientSecret: String? = null private val mActivityEventListener = object : BaseActivityEventListener() { override fun onActivityResult(activity: Activity, requestCode: Int, resultCode: Int, data: Intent?) { - stripe.onSetupResult(requestCode, data, object : ApiResultCallback { - override fun onSuccess(result: SetupIntentResult) { - val setupIntent = result.intent - when (setupIntent.status) { - StripeIntent.Status.Succeeded -> { - confirmSetupIntentPromise?.resolve(mapFromSetupIntentResult(setupIntent)) - } - StripeIntent.Status.Canceled -> { - val errorMessage = setupIntent.lastSetupError?.message.orEmpty() - confirmSetupIntentPromise?.reject(ConfirmSetupIntentErrorType.Canceled.toString(), errorMessage) - } - else -> { - val errorMessage = "unhandled error: ${setupIntent.status}" - confirmSetupIntentPromise?.reject(ConfirmSetupIntentErrorType.Unknown.toString(), errorMessage) + if (::stripe.isInitialized) { + stripe.onSetupResult(requestCode, data, object : ApiResultCallback { + override fun onSuccess(result: SetupIntentResult) { + val setupIntent = result.intent + when (setupIntent.status) { + StripeIntent.Status.Succeeded -> { + confirmSetupIntentPromise?.resolve(createResult("setupIntent", mapFromSetupIntentResult(setupIntent))) + } + StripeIntent.Status.Canceled -> { + confirmSetupIntentPromise?.resolve(createError(ConfirmSetupIntentErrorType.Canceled.toString(), setupIntent.lastSetupError)) + } + StripeIntent.Status.RequiresAction -> { + confirmSetupIntentPromise?.resolve(createError(ConfirmSetupIntentErrorType.Canceled.toString(), setupIntent.lastSetupError)) + } + else -> { + val errorMessage = "unhandled error: ${setupIntent.status}" + confirmSetupIntentPromise?.resolve(createError(ConfirmSetupIntentErrorType.Failed.toString(), errorMessage)) + } } } - } - override fun onError(e: Exception) { - confirmSetupIntentPromise?.reject(ConfirmSetupIntentErrorType.Failed.toString(), e.message.orEmpty()) - } - }) - - stripe.onPaymentResult(requestCode, data, object : ApiResultCallback { - override fun onSuccess(result: PaymentIntentResult) { - val paymentIntent = result.intent - - when (paymentIntent.status) { - StripeIntent.Status.Succeeded, - StripeIntent.Status.Processing, - StripeIntent.Status.RequiresCapture -> { - confirmPromise?.resolve(mapFromPaymentIntentResult(paymentIntent)) - handleCardActionPromise?.resolve(mapFromPaymentIntentResult(paymentIntent)) - } - StripeIntent.Status.RequiresAction -> { - if (isPaymentIntentNextActionVoucherBased(paymentIntent.nextActionType)) { - confirmPromise?.resolve(mapFromPaymentIntentResult(paymentIntent)) - handleCardActionPromise?.resolve(mapFromPaymentIntentResult(paymentIntent)) - } else { - val errorMessage = paymentIntent.lastPaymentError?.message.orEmpty() - confirmPromise?.reject(ConfirmPaymentErrorType.Canceled.toString(), errorMessage) - handleCardActionPromise?.reject(NextPaymentActionErrorType.Canceled.toString(), errorMessage) + override fun onError(e: Exception) { + confirmSetupIntentPromise?.resolve(createError(ConfirmSetupIntentErrorType.Failed.toString(), e)) + } + }) + + stripe.onPaymentResult(requestCode, data, object : ApiResultCallback { + override fun onSuccess(result: PaymentIntentResult) { + val paymentIntent = result.intent + + when (paymentIntent.status) { + StripeIntent.Status.Succeeded, + StripeIntent.Status.Processing, + StripeIntent.Status.RequiresCapture -> { + val pi = createResult("paymentIntent", mapFromPaymentIntentResult(paymentIntent)) + confirmPromise?.resolve(pi) + handleCardActionPromise?.resolve(pi) + } + StripeIntent.Status.RequiresAction -> { + if (isPaymentIntentNextActionVoucherBased(paymentIntent.nextActionType)) { + val pi = createResult("paymentIntent", mapFromPaymentIntentResult(paymentIntent)) + confirmPromise?.resolve(pi) + handleCardActionPromise?.resolve(pi) + } else { + (paymentIntent.lastPaymentError)?.let { + confirmPromise?.resolve(createError(ConfirmPaymentErrorType.Canceled.toString(), it)) + handleCardActionPromise?.resolve(createError(NextPaymentActionErrorType.Canceled.toString(), it)) + } ?: run { + confirmPromise?.resolve(createError(ConfirmPaymentErrorType.Canceled.toString(), "The payment has been canceled")) + handleCardActionPromise?.resolve(createError(NextPaymentActionErrorType.Canceled.toString(), "The payment has been canceled")) + } + } + } + StripeIntent.Status.RequiresPaymentMethod -> { + val error = paymentIntent.lastPaymentError + confirmPromise?.resolve(createError(ConfirmPaymentErrorType.Failed.toString(), error)) + handleCardActionPromise?.resolve(createError(NextPaymentActionErrorType.Failed.toString(), error)) + } + StripeIntent.Status.RequiresConfirmation -> { + val pi = createResult("paymentIntent", mapFromPaymentIntentResult(paymentIntent)) + handleCardActionPromise?.resolve(pi) + } + StripeIntent.Status.Canceled -> { + val error = paymentIntent.lastPaymentError + confirmPromise?.resolve(createError(ConfirmPaymentErrorType.Canceled.toString(), error)) + handleCardActionPromise?.resolve(createError(NextPaymentActionErrorType.Canceled.toString(), error)) + } + else -> { + val errorMessage = "unhandled error: ${paymentIntent.status}" + confirmPromise?.resolve(createError(ConfirmPaymentErrorType.Unknown.toString(), errorMessage)) + handleCardActionPromise?.resolve(createError(NextPaymentActionErrorType.Unknown.toString(), errorMessage)) } - } - StripeIntent.Status.RequiresPaymentMethod -> { - val errorMessage = paymentIntent.lastPaymentError?.message.orEmpty() - confirmPromise?.reject(ConfirmPaymentErrorType.Failed.toString(), errorMessage) - handleCardActionPromise?.reject(NextPaymentActionErrorType.Failed.toString(), errorMessage) - } - StripeIntent.Status.RequiresConfirmation -> { - handleCardActionPromise?.resolve(mapFromPaymentIntentResult(paymentIntent)) - } - StripeIntent.Status.Canceled -> { - val errorMessage = paymentIntent.lastPaymentError?.message.orEmpty() - confirmPromise?.reject(ConfirmPaymentErrorType.Canceled.toString(), errorMessage) - handleCardActionPromise?.reject(NextPaymentActionErrorType.Canceled.toString(), errorMessage) - } - else -> { - val errorMessage = "unhandled error: ${paymentIntent.status}" - confirmPromise?.reject(ConfirmPaymentErrorType.Unknown.toString(), errorMessage) - handleCardActionPromise?.reject(NextPaymentActionErrorType.Unknown.toString(), errorMessage) } } - } - override fun onError(e: Exception) { - confirmPromise?.reject(ConfirmPaymentErrorType.Failed.toString(), e.toString()) - handleCardActionPromise?.reject(NextPaymentActionErrorType.Failed.toString(), e.toString()) - } - }) + override fun onError(e: Exception) { + confirmPromise?.resolve(createError(ConfirmPaymentErrorType.Failed.toString(), e)) + handleCardActionPromise?.resolve(createError(NextPaymentActionErrorType.Failed.toString(), e)) + } + }) - // TODO add an integration test for commenting this out - // paymentSheetFragment?.activity?.activityResultRegistry?.dispatchResult(requestCode, resultCode, data) + // TODO add an integration test for commenting this out + //paymentSheetFragment?.activity?.dispatchResult(requestCode, resultCode, data) - try { - val result = AddPaymentMethodActivityStarter.Result.fromIntent(data) - if (data?.getParcelableExtra("extra_activity_result") != null) { - onFpxPaymentMethodResult(result) + try { + val result = AddPaymentMethodActivityStarter.Result.fromIntent(data) + if (data?.getParcelableExtra("extra_activity_result") != null) { + onFpxPaymentMethodResult(result) + } + } catch (e: java.lang.Exception) { + Log.d("Error", e.localizedMessage ?: e.toString()) } - } catch (e: java.lang.Exception) { - Log.d("Error", e.localizedMessage) } } } - private lateinit var stripe: Stripe - init { reactContext.addActivityEventListener(mActivityEventListener); } private fun configure3dSecure(params: ReadableMap) { val stripe3dsConfigBuilder = PaymentAuthConfig.Stripe3ds2Config.Builder() - if (params.hasKey("timeout")) stripe3dsConfigBuilder.setTimeout(params.getInt("timeout")) - val uiCustomization = mapToUICustomization(params) PaymentAuthConfig.init( - PaymentAuthConfig.Builder() - .set3ds2Config( - stripe3dsConfigBuilder - .setUiCustomization(uiCustomization) - .build() - ) - .build() + PaymentAuthConfig.Builder() + .set3ds2Config( + stripe3dsConfigBuilder + .setUiCustomization(uiCustomization) + .build() + ) + .build() ) } @@ -157,18 +162,19 @@ class StripeSdkModule(reactContext: ReactApplicationContext, cardFieldManager: S paymentSheetFragment = currentActivity.activity.supportFragmentManager.findFragmentByTag("payment_sheet_launch_fragment") as PaymentSheetFragment } if (intent.action == ON_PAYMENT_RESULT_ACTION) { - when (intent.extras?.getParcelable("paymentResult")) { + when (val result = intent.extras?.getParcelable("paymentResult")) { is PaymentSheetResult.Canceled -> { - confirmPaymentSheetPaymentPromise?.reject(PaymentSheetErrorType.Canceled.toString(), "") - presentPaymentSheetPromise?.reject(PaymentSheetErrorType.Canceled.toString(), "") + val message = "The payment has been canceled" + confirmPaymentSheetPaymentPromise?.resolve(createError(PaymentSheetErrorType.Canceled.toString(), message)) + presentPaymentSheetPromise?.resolve(createError(PaymentSheetErrorType.Canceled.toString(), message)) } is PaymentSheetResult.Failed -> { - confirmPaymentSheetPaymentPromise?.reject(PaymentSheetErrorType.Failed.toString(), "") - presentPaymentSheetPromise?.reject(PaymentSheetErrorType.Failed.toString(), "") + confirmPaymentSheetPaymentPromise?.resolve(createError(PaymentSheetErrorType.Failed.toString(), result.error)) + presentPaymentSheetPromise?.resolve(createError(PaymentSheetErrorType.Failed.toString(), result.error)) } is PaymentSheetResult.Completed -> { - confirmPaymentSheetPaymentPromise?.resolve(Arguments.createMap()) - presentPaymentSheetPromise?.resolve(Arguments.createMap()) + confirmPaymentSheetPaymentPromise?.resolve(WritableNativeMap()) + presentPaymentSheetPromise?.resolve(WritableNativeMap()) } } } else if (intent.action == ON_PAYMENT_OPTION_ACTION) { @@ -177,13 +183,11 @@ class StripeSdkModule(reactContext: ReactApplicationContext, cardFieldManager: S if (label != null && image != null) { val option: WritableMap = WritableNativeMap() - val result: WritableMap = WritableNativeMap() option.putString("label", label) option.putString("image", image) - result.putMap("paymentOption", option) - presentPaymentSheetPromise?.resolve(result) + presentPaymentSheetPromise?.resolve(createResult("paymentOption", option)) } else { - presentPaymentSheetPromise?.resolve(Arguments.createMap()) + presentPaymentSheetPromise?.resolve(WritableNativeMap()) } } else if (intent.action == ON_CONFIGURE_FLOW_CONTROLLER) { @@ -194,29 +198,19 @@ class StripeSdkModule(reactContext: ReactApplicationContext, cardFieldManager: S val option: WritableMap = WritableNativeMap() option.putString("label", label) option.putString("image", image) - initPaymentSheetPromise?.resolve(option) + initPaymentSheetPromise?.resolve(createResult("paymentOption", option)) } else { - initPaymentSheetPromise?.resolve(null) + initPaymentSheetPromise?.resolve(WritableNativeMap()) } } } } - /// Check paymentIntent.nextAction is voucher-based payment method. - /// If it's voucher-based, the paymentIntent status stays in requiresAction until the voucher is paid or expired. - /// Currently only OXXO payment is voucher-based. - private fun isPaymentIntentNextActionVoucherBased(nextAction: StripeIntent.NextActionType?): Boolean { - nextAction?.let { - return it == StripeIntent.NextActionType.DisplayOxxoDetails - } - return false - } - @ReactMethod fun initialise(params: ReadableMap, promise: Promise) { val publishableKey = getValOr(params, "publishableKey", null) as String val appInfo = getMapOrNull(params, "appInfo") as ReadableMap - val stripeAccountId = getValOr(params, "stripeAccountId", null) + this.stripeAccountId = getValOr(params, "stripeAccountId", null) val urlScheme = getValOr(params, "urlScheme", null) val setUrlSchemeOnAndroid = getBooleanOrFalse(params, "setUrlSchemeOnAndroid") this.urlScheme = if (setUrlSchemeOnAndroid) urlScheme else null @@ -247,19 +241,17 @@ class StripeSdkModule(reactContext: ReactApplicationContext, cardFieldManager: S @ReactMethod fun initPaymentSheet(params: ReadableMap, promise: Promise) { - val activity = currentActivity + val activity = currentActivity.activity if (activity == null) { - promise.reject("Fail", "Activity doesn't exist") + promise.resolve(createError("Failed", "Activity doesn't exist")) return } val customFlow = getBooleanOrNull(params, "customFlow") ?: false - - PaymentConfiguration.init(reactApplicationContext, publishableKey) - val customerId = getValOr(params, "customerId") val customerEphemeralKeySecret = getValOr(params, "customerEphemeralKeySecret") val paymentIntentClientSecret = getValOr(params, "paymentIntentClientSecret") + val setupIntentClientSecret = getValOr(params, "setupIntentClientSecret") val merchantDisplayName = getValOr(params, "merchantDisplayName") val countryCode = getValOr(params, "merchantCountryCode") val testEnv = getBooleanOrNull(params, "testEnv") ?: false @@ -271,6 +263,7 @@ class StripeSdkModule(reactContext: ReactApplicationContext, cardFieldManager: S bundle.putString("customerId", customerId) bundle.putString("customerEphemeralKeySecret", customerEphemeralKeySecret) bundle.putString("paymentIntentClientSecret", paymentIntentClientSecret) + bundle.putString("setupIntentClientSecret", setupIntentClientSecret) bundle.putString("merchantDisplayName", merchantDisplayName) bundle.putString("countryCode", countryCode) bundle.putBoolean("customFlow", customFlow) @@ -278,23 +271,22 @@ class StripeSdkModule(reactContext: ReactApplicationContext, cardFieldManager: S it.arguments = bundle } - activity.activity.supportFragmentManager.beginTransaction() - .add(fragment, "payment_sheet_launch_fragment") - .commit() + activity.supportFragmentManager.beginTransaction() + .add(fragment, "payment_sheet_launch_fragment") + .commit() if (!customFlow) { - this.initPaymentSheetPromise?.resolve(null) + this.initPaymentSheetPromise?.resolve(WritableNativeMap()) } } @ReactMethod - fun presentPaymentSheet(params: ReadableMap, promise: Promise) { - val clientSecret = getValOr(params, "clientSecret") as String + fun presentPaymentSheet(params: ReadableMap?, promise: Promise) { val confirmPayment = getBooleanOrNull(params, "confirmPayment") this.presentPaymentSheetPromise = promise if (confirmPayment == false) { paymentSheetFragment?.presentPaymentOptions() } else { - paymentSheetFragment?.present(clientSecret) + paymentSheetFragment?.present() } } @@ -305,28 +297,28 @@ class StripeSdkModule(reactContext: ReactApplicationContext, cardFieldManager: S } private fun payWithFpx() { - AddPaymentMethodActivityStarter(currentActivity.activity as AppCompatActivity) - .startForResult(AddPaymentMethodActivityStarter.Args.Builder() - .setPaymentMethodType(PaymentMethod.Type.Fpx) - .build() - ) + AddPaymentMethodActivityStarter(currentActivity.activity) + .startForResult(AddPaymentMethodActivityStarter.Args.Builder() + .setPaymentMethodType(PaymentMethod.Type.Fpx) + .build() + ) } private fun onFpxPaymentMethodResult(result: AddPaymentMethodActivityStarter.Result) { when (result) { is AddPaymentMethodActivityStarter.Result.Success -> { stripe.confirmPayment(currentActivity!!.activity, - ConfirmPaymentIntentParams.createWithPaymentMethodId( - result.paymentMethod.id!!, - confirmPaymentClientSecret!!, - returnUrl = mapToReturnURL(urlScheme) - )); + ConfirmPaymentIntentParams.createWithPaymentMethodId( + result.paymentMethod.id!!, + confirmPaymentClientSecret!!, + returnUrl = mapToReturnURL(urlScheme) + )); } is AddPaymentMethodActivityStarter.Result.Failure -> { - confirmPromise?.reject(ConfirmPaymentErrorType.Failed.toString(), result.exception.localizedMessage) + confirmPromise?.resolve(createError(ConfirmPaymentErrorType.Failed.toString(), result.exception)) } is AddPaymentMethodActivityStarter.Result.Canceled -> { - confirmPromise?.reject(ConfirmPaymentErrorType.Canceled.toString(), "Fpx payment has been canceled") + confirmPromise?.resolve(createError(ConfirmPaymentErrorType.Canceled.toString(), "The payment has been canceled")) } } this.confirmPaymentClientSecret = null @@ -336,37 +328,73 @@ class StripeSdkModule(reactContext: ReactApplicationContext, cardFieldManager: S fun createPaymentMethod(data: ReadableMap, options: ReadableMap, promise: Promise) { val billingDetailsParams = mapToBillingDetails(getMapOrNull(data, "billingDetails")) val instance = cardFieldManager.getCardViewInstance() - val cardParams = instance?.cardParams - ?: throw PaymentMethodCreateParamsException("Card details not complete") + val cardParams = instance?.cardParams ?: run { + promise.reject("Failed", "Card details not complete") + return + } val paymentMethodCreateParams = PaymentMethodCreateParams.create(cardParams, billingDetailsParams) stripe.createPaymentMethod( - paymentMethodCreateParams, - callback = object : ApiResultCallback { - override fun onError(e: Exception) { - promise.reject("Failed", e.localizedMessage) - } + paymentMethodCreateParams, + callback = object : ApiResultCallback { + override fun onError(error: Exception) { + promise.resolve(createError("Failed", error)) + } - override fun onSuccess(result: PaymentMethod) { - val paymentMethodMap: WritableMap = mapFromPaymentMethod(result) - promise.resolve(paymentMethodMap) - } - }) + override fun onSuccess(result: PaymentMethod) { + val paymentMethodMap: WritableMap = mapFromPaymentMethod(result) + promise.resolve(createResult("paymentMethod", paymentMethodMap)) + } + }) + } + + @ReactMethod + fun createToken(params: ReadableMap, promise: Promise) { + val type = getValOr(params, "type", null)?.let { + if (it != "Card") { + promise.reject(CreateTokenErrorType.Failed.toString(), "$it type is not supported yet") + return + } + } + val address = getMapOrNull(params, "address") + val instance = cardFieldManager.getCardViewInstance() + val cardParams = instance?.cardParams?.toParamMap() ?: run { + promise.reject(CreateTokenErrorType.Failed.toString(), "Card details not complete") + return + } + + val params = CardParams( + number = cardParams["number"] as String, + expMonth = cardParams["exp_month"] as Int, + expYear = cardParams["exp_year"] as Int, + cvc = cardParams["cvc"] as String, + address = mapToAddress(address), + name = getValOr(params, "name", null) + ) + runBlocking { + val token = stripe.createCardToken( + cardParams = params, + stripeAccountId = stripeAccountId + ) + promise.resolve(mapFromToken(token)) + } } @ReactMethod fun createTokenForCVCUpdate(cvc: String, promise: Promise) { stripe.createCvcUpdateToken( - cvc, - callback = object : ApiResultCallback { - override fun onSuccess(result: Token) { - val tokenId = result.id - promise.resolve(tokenId) - } + cvc, + callback = object : ApiResultCallback { + override fun onSuccess(result: Token) { + val tokenId = result.id + val res = WritableNativeMap() + res.putString("tokenId", tokenId) + promise.resolve(res) + } - override fun onError(e: Exception) { - promise.reject("Failed", e.localizedMessage) - } - } + override fun onError(error: Exception) { + promise.resolve(createError("Failed", error)) + } + } ) } @@ -388,7 +416,7 @@ class StripeSdkModule(reactContext: ReactApplicationContext, cardFieldManager: S val cardParams = instance?.cardParams val paymentMethodType = getValOr(params, "type")?.let { mapToPaymentMethodType(it) } ?: run { - promise.reject(ConfirmPaymentErrorType.Failed.toString(), "You must provide paymentMethodType") + promise.resolve(createError(ConfirmPaymentErrorType.Failed.toString(), "You must provide paymentMethodType")) return } @@ -406,7 +434,7 @@ class StripeSdkModule(reactContext: ReactApplicationContext, cardFieldManager: S confirmParams.shipping = mapToShippingDetails(getMapOrNull(params, "shippingDetails")) stripe.confirmPayment(currentActivity!!.activity, confirmParams) } catch (error: PaymentMethodCreateParamsException) { - promise.reject(ConfirmPaymentErrorType.Failed.toString(), error.localizedMessage) + promise.resolve(createError(ConfirmPaymentErrorType.Failed.toString(), error)) } } @@ -415,23 +443,23 @@ class StripeSdkModule(reactContext: ReactApplicationContext, cardFieldManager: S AsyncTask.execute { val paymentIntent = stripe.retrievePaymentIntentSynchronous(clientSecret) paymentIntent?.let { - promise.resolve(mapFromPaymentIntentResult(it)) + promise.resolve(createResult("paymentIntent", mapFromPaymentIntentResult(it))) } ?: run { - promise.reject(RetrievePaymentIntentErrorType.Unknown.toString(), "Retrieving payment intent failed") + promise.resolve(createError(RetrievePaymentIntentErrorType.Unknown.toString(), "Failed to retrieve the PaymentIntent")) } } } @ReactMethod - fun registerConfirmSetupIntentCallbacks(successCallback: Callback, errorCallback: Callback) { - onConfirmSetupIntentError = errorCallback - onConfirmSetupIntentSuccess = successCallback - } - - @ReactMethod - fun unregisterConfirmSetupIntentCallbacks() { - onConfirmSetupIntentError = null - onConfirmSetupIntentSuccess = null + fun retrieveSetupIntent(clientSecret: String, promise: Promise) { + AsyncTask.execute { + val setupIntent = stripe.retrieveSetupIntentSynchronous(clientSecret) + setupIntent?.let { + promise.resolve(createResult("setupIntent", mapFromSetupIntentResult(it))) + } ?: run { + promise.resolve(createError(RetrieveSetupIntentErrorType.Unknown.toString(), "Failed to retrieve the SetupIntent")) + } + } } @ReactMethod @@ -442,7 +470,7 @@ class StripeSdkModule(reactContext: ReactApplicationContext, cardFieldManager: S val cardParams = instance?.cardParams val paymentMethodType = getValOr(params, "type")?.let { mapToPaymentMethodType(it) } ?: run { - promise.reject(ConfirmPaymentErrorType.Failed.toString(), "You must provide paymentMethodType") + promise.resolve(createError(ConfirmPaymentErrorType.Failed.toString(), "You must provide paymentMethodType")) return } @@ -450,10 +478,19 @@ class StripeSdkModule(reactContext: ReactApplicationContext, cardFieldManager: S try { val confirmParams = factory.createSetupParams(paymentMethodType) - stripe.confirmSetupIntent(currentActivity!!.activity, confirmParams) + stripe.confirmSetupIntent(currentActivity.activity, confirmParams) } catch (error: PaymentMethodCreateParamsException) { - promise.reject(ConfirmPaymentErrorType.Failed.toString(), error.localizedMessage) + promise.resolve(createError(ConfirmPaymentErrorType.Failed.toString(), error)) } } -} \ No newline at end of file + /// Check paymentIntent.nextAction is voucher-based payment method. + /// If it's voucher-based, the paymentIntent status stays in requiresAction until the voucher is paid or expired. + /// Currently only OXXO payment is voucher-based. + private fun isPaymentIntentNextActionVoucherBased(nextAction: StripeIntent.NextActionType?): Boolean { + nextAction?.let { + return it == StripeIntent.NextActionType.DisplayOxxoDetails + } + return false + } +} diff --git a/packages/stripe_android/pubspec.yaml b/packages/stripe_android/pubspec.yaml index 08f4146..cc87239 100644 --- a/packages/stripe_android/pubspec.yaml +++ b/packages/stripe_android/pubspec.yaml @@ -15,7 +15,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.11.0 + flutter_lints: ^1.0.3 flutter: plugin: diff --git a/packages/stripe_ios/ios/Classes/CardFieldView.swift b/packages/stripe_ios/ios/Classes/CardFieldView.swift index 00e22aa..0c1e377 100644 --- a/packages/stripe_ios/ios/Classes/CardFieldView.swift +++ b/packages/stripe_ios/ios/Classes/CardFieldView.swift @@ -254,10 +254,11 @@ class CardFieldView: NSObject, FlutterPlatformView, STPPaymentCardTextFieldDeleg } func paymentCardTextFieldDidChange(_ textField: STPPaymentCardTextField) { + let brand = STPCardValidator.brand(forNumber: textField.cardParams.number ?? "") - var cardData: [String: Any] = [ - "expiryMonth": textField.cardParams.expMonth?.stringValue ?? "", - "expiryYear": textField.cardParams.expYear?.stringValue ?? "", + var cardData: [String: Any?] = [ + "expiryMonth": textField.cardParams.expMonth, + "expiryYear": textField.cardParams.expYear, "complete": textField.isValid, "brand": Mappers.mapCardBrand(brand), "last4": textField.cardParams.last4 ?? "" @@ -268,7 +269,10 @@ class CardFieldView: NSObject, FlutterPlatformView, STPPaymentCardTextFieldDeleg onCardChange(cardData) if (textField.isValid) { self.cardParams = textField.cardParams + } else { + self.cardParams = nil } + } func focus() { diff --git a/packages/stripe_ios/ios/Classes/Errors.swift b/packages/stripe_ios/ios/Classes/Errors.swift index 31a53a8..fea3246 100644 --- a/packages/stripe_ios/ios/Classes/Errors.swift +++ b/packages/stripe_ios/ios/Classes/Errors.swift @@ -1,3 +1,5 @@ +import Stripe + enum ConfirmPaymentErrorType: String { case Failed, Canceled, Unknown } @@ -18,27 +20,66 @@ enum RetrievePaymentIntentErrorType: String { case Unknown } +enum RetrieveSetupIntentErrorType: String { + case Unknown +} + enum PaymentSheetErrorType: String { case Failed, Canceled } +enum CreateTokenErrorType: String { + case Failed +} + class Errors { - class func createError (code: String, message: String) -> NSDictionary { - let error: NSDictionary = [ + class func createError (_ code: String, _ message: String?) -> NSDictionary { + let value: NSDictionary = [ "code": code, - "message": message, + "message": message ?? NSNull(), + "localizedMessage": message ?? NSNull(), + "declineCode": NSNull(), + "stripeErrorCode": NSNull(), + "type": NSNull() ] - return error + return ["error": value] } -} - -extension FlutterError { - static func invalidParams(_ message: String?) -> FlutterError { - return FlutterError.init(code: "Invalid Params", message: message, details: nil) + class func createError (_ code: String, _ error: NSError?) -> NSDictionary { + let value: NSDictionary = [ + "code": code, + "message": error?.userInfo["com.stripe.lib:ErrorMessageKey"] ?? error?.userInfo["NSLocalizedDescription"] ?? NSNull(), + "localizedMessage": error?.userInfo["NSLocalizedDescription"] ?? NSNull(), + "declineCode": error?.userInfo["com.stripe.lib:DeclineCodeKey"] ?? NSNull(), + "stripeErrorCode": error?.userInfo["com.stripe.lib:StripeErrorCodeKey"] ?? NSNull(), + "type": error?.userInfo["com.stripe.lib:StripeErrorTypeKey"] ?? NSNull(), + ] + + return ["error": value] + } + class func createError (_ code: String, _ error: STPSetupIntentLastSetupError?) -> NSDictionary { + let value: NSDictionary = [ + "code": code, + "message": error?.message ?? NSNull(), + "localizedMessage": error?.message ?? NSNull(), + "declineCode": error?.declineCode ?? NSNull(), + "stripeErrorCode": error?.code ?? NSNull(), + "type": Mappers.mapFromSetupIntentLastPaymentErrorType(error?.type) ?? NSNull() + ] + + return ["error": value] } - static var invalidParams: FlutterError { - return FlutterError.init(code: "Invalid Params", message: "", details: "") + class func createError (_ code: String, _ error: STPPaymentIntentLastPaymentError?) -> NSDictionary { + let value: NSDictionary = [ + "code": code, + "message": error?.message ?? NSNull(), + "localizedMessage": error?.message ?? NSNull(), + "declineCode": error?.declineCode ?? NSNull(), + "stripeErrorCode": error?.code ?? NSNull(), + "type": Mappers.mapFromPaymentIntentLastPaymentErrorType(error?.type) ?? NSNull() + ] + + return ["error": value] } } diff --git a/packages/stripe_ios/ios/Classes/Mappers.swift b/packages/stripe_ios/ios/Classes/Mappers.swift index fb65c73..3b1cd41 100644 --- a/packages/stripe_ios/ios/Classes/Mappers.swift +++ b/packages/stripe_ios/ios/Classes/Mappers.swift @@ -1,6 +1,10 @@ import Stripe class Mappers { + class func createResult(_ key: String, _ value: NSDictionary?) -> NSDictionary { + return [key: value ?? NSNull()] + } + class func mapToPKContactField(field: String) -> PKContactField { switch field { case "emailAddress": return PKContactField.emailAddress @@ -23,6 +27,132 @@ class Mappers { return PKPaymentSummaryItemType.final } + class func mapFromBankAccountHolderType(_ type: STPBankAccountHolderType?) -> String? { + if let type = type { + switch type { + case STPBankAccountHolderType.company: return "Company" + case STPBankAccountHolderType.individual: return "Individual" + default: return nil + } + } + return nil + } + + class func mapFromBankAccountStatus(_ status: STPBankAccountStatus?) -> String? { + if let status = status { + switch status { + case STPBankAccountStatus.errored: return "Errored" + case STPBankAccountStatus.new: return "New" + case STPBankAccountStatus.validated: return "Validated" + case STPBankAccountStatus.verified: return "Verified" + case STPBankAccountStatus.verificationFailed: return "VerificationFailed" + default: return nil + } + } + return nil + } + + class func mapFromBankAccount(_ bankAccount: STPBankAccount?) -> NSDictionary? { + if (bankAccount == nil) { + return nil + } + let result: NSDictionary = [ + "bankName": bankAccount?.bankName ?? NSNull(), + "accountHolderName": bankAccount?.accountHolderName ?? NSNull(), + "accountHolderType": mapFromBankAccountHolderType(bankAccount?.accountHolderType) ?? NSNull(), + "country": bankAccount?.country ?? NSNull(), + "currency": bankAccount?.currency ?? NSNull(), + "routingNumber": bankAccount?.routingNumber ?? NSNull(), + "status": mapFromBankAccountStatus(bankAccount?.status) ?? NSNull(), + + ] + return result + } + + class func mapFromCard(_ card: STPCard?) -> NSDictionary? { + if (card == nil) { + return nil + } + let cardMap: NSDictionary = [ + "brand": mapCardBrand(card?.brand) ?? NSNull(), + "country": card?.country ?? NSNull(), + "currency": card?.currency ?? NSNull(), + "expMonth": card?.expMonth ?? NSNull(), + "expYear": card?.expYear ?? NSNull(), + "last4": card?.last4 ?? NSNull(), + "funding": mapFromFunding(card?.funding) ?? NSNull(), + "name": card?.name ?? NSNull(), + "address": mapFromAddress(address: card?.address) + ] + return cardMap + } + + class func mapFromAddress(address: STPAddress?) -> NSDictionary { + let result: NSDictionary = [ + "city": address?.city ?? NSNull(), + "postalCode": address?.postalCode ?? NSNull(), + "country": address?.country ?? NSNull(), + "line1": address?.line1 ?? NSNull(), + "line2": address?.line2 ?? NSNull(), + "state": address?.state ?? NSNull(), + ] + + return result + } + + class func mapToAddress(address: NSDictionary?) -> STPAddress { + let result = STPAddress() + result.city = address?["city"] as? String + result.country = address?["country"] as? String + result.line1 = address?["line1"] as? String + result.line2 = address?["line2"] as? String + result.postalCode = address?["postalCode"] as? String + result.state = address?["state"] as? String + + return result + } + + class func mapFromFunding(_ funding: STPCardFundingType?) -> String? { + if let funding = funding { + switch funding { + case STPCardFundingType.credit: return "Credit" + case STPCardFundingType.debit: return "Debit" + case STPCardFundingType.prepaid: return "Prepaid" + case STPCardFundingType.other: return "Unknown" + + default: return nil + } + } + return nil + } + + class func mapFromTokenType(_ type: STPTokenType?) -> String? { + if let type = type { + switch type { + case STPTokenType.PII: return "Pii" + case STPTokenType.account: return "Account" + case STPTokenType.bankAccount: return "BankAccount" + case STPTokenType.card: return "Card" + case STPTokenType.cvcUpdate: return "CvcUpdate" + default: return nil + } + } + return nil + } + + class func mapFromToken(token: STPToken) -> NSDictionary { + let tokenMap: NSDictionary = [ + "id": token.tokenId, + "bankAccount": mapFromBankAccount(token.bankAccount) ?? NSNull(), + "created": convertDateToUnixTimestamp(date: token.created) ?? NSNull(), + "card": mapFromCard(token.card) ?? NSNull(), + "livemode": token.livemode, + "type": mapFromTokenType(token.type) ?? NSNull(), + ] + + return tokenMap + } + class func mapToShippingMethods(shippingMethods: NSArray?) -> [PKShippingMethod] { var shippingMethodsList: [PKShippingMethod] = [] @@ -47,7 +177,7 @@ class Mappers { let method: NSDictionary = [ "detail": shippingMethod.detail ?? "", "identifier": shippingMethod.identifier ?? "", - "amount": shippingMethod.amount.stringValue, + "amount": shippingMethod.amount.stringValue, "type": shippingMethod.type, "label": shippingMethod.label ] @@ -57,12 +187,12 @@ class Mappers { class func mapFromShippingContact(shippingContact: PKContact) -> NSDictionary { let name: NSDictionary = [ - "familyName": shippingContact.name?.familyName ?? "", - "namePrefix": shippingContact.name?.namePrefix ?? "", - "nameSuffix": shippingContact.name?.nameSuffix ?? "", - "givenName": shippingContact.name?.givenName ?? "", - "middleName": shippingContact.name?.middleName ?? "", - "nickname": shippingContact.name?.nickname ?? "", + "familyName": shippingContact.name?.familyName ?? "", + "namePrefix": shippingContact.name?.namePrefix ?? "", + "nameSuffix": shippingContact.name?.nameSuffix ?? "", + "givenName": shippingContact.name?.givenName ?? "", + "middleName": shippingContact.name?.middleName ?? "", + "nickname": shippingContact.name?.nickname ?? "", ] let contact: NSDictionary = [ "emailAddress": shippingContact.emailAddress ?? "", @@ -83,6 +213,28 @@ class Mappers { return contact } + class func mapAddressFields(_ addressFields: [String]) -> [String] { + return addressFields.map { + if ($0 == "street") { + return CNPostalAddressStreetKey + } else if ($0 == "city") { + return CNPostalAddressCityKey + } else if ($0 == "subAdministrativeArea") { + return CNPostalAddressSubAdministrativeAreaKey + } else if ($0 == "state") { + return CNPostalAddressStateKey + } else if ($0 == "postalCode") { + return CNPostalAddressPostalCodeKey + } else if ($0 == "country") { + return CNPostalAddressCountryKey + } else if ($0 == "countryCode") { + return CNPostalAddressISOCountryCodeKey + } else if ($0 == "subLocality") { + return CNPostalAddressSubLocalityKey + } + return "" + } + } class func mapIntentStatus(status: STPPaymentIntentStatus?) -> String { if let status = status { @@ -205,7 +357,7 @@ class Mappers { "paymentMethodId": paymentIntent.paymentMethodId ?? NSNull(), "captureMethod": mapCaptureMethod(paymentIntent.captureMethod), "confirmationMethod": mapConfirmationMethod(paymentIntent.confirmationMethod), - "created": convertDateToUnixTimestamp(date: paymentIntent.created), + "created": convertDateToUnixTimestamp(date: paymentIntent.created) ?? NSNull(), "amount": paymentIntent.amount, "lastPaymentError": NSNull(), "shipping": NSNull(), @@ -216,12 +368,11 @@ class Mappers { let paymentError: NSMutableDictionary = [ "code": lastPaymentError.code ?? NSNull(), "message": lastPaymentError.message ?? NSNull(), - "type": mapFromPaymentIntentLastPaymentErrorType(lastPaymentError.type) + "type": mapFromPaymentIntentLastPaymentErrorType(lastPaymentError.type), + "declineCode": lastPaymentError.declineCode ?? NSNull(), + "paymentMethod": mapFromPaymentMethod(lastPaymentError.paymentMethod) ?? NSNull() ] - if let paymentMethod = paymentIntent.lastPaymentError?.paymentMethod { - paymentError.setValue(mapFromPaymentMethod(paymentMethod), forKey: "paymentMethod") - } intent.setValue(paymentError, forKey: "lastPaymentError") } @@ -236,21 +387,38 @@ class Mappers { return intent; } - class func mapFromPaymentIntentLastPaymentErrorType(_ errorType: STPPaymentIntentLastPaymentErrorType?) -> String { + class func mapFromPaymentIntentLastPaymentErrorType(_ errorType: STPPaymentIntentLastPaymentErrorType?) -> String? { if let errorType = errorType { switch errorType { - case STPPaymentIntentLastPaymentErrorType.apiConnection: return "ApiConnection" - case STPPaymentIntentLastPaymentErrorType.api: return "Api" - case STPPaymentIntentLastPaymentErrorType.authentication: return "Authentication" - case STPPaymentIntentLastPaymentErrorType.card: return "Card" - case STPPaymentIntentLastPaymentErrorType.idempotency: return "Idempotency" - case STPPaymentIntentLastPaymentErrorType.invalidRequest: return "InvalidRequest" - case STPPaymentIntentLastPaymentErrorType.rateLimit: return "RateLimit" - case STPPaymentIntentLastPaymentErrorType.unknown: return "Unknown" - default: return "Unknown" + case STPPaymentIntentLastPaymentErrorType.apiConnection: return "api_connection_error" + case STPPaymentIntentLastPaymentErrorType.api: return "api_error" + case STPPaymentIntentLastPaymentErrorType.authentication: return "authentication_error" + case STPPaymentIntentLastPaymentErrorType.card: return "card_error" + case STPPaymentIntentLastPaymentErrorType.idempotency: return "idempotency_error" + case STPPaymentIntentLastPaymentErrorType.invalidRequest: return "invalid_request_error" + case STPPaymentIntentLastPaymentErrorType.rateLimit: return "rate_limit_error" + case STPPaymentIntentLastPaymentErrorType.unknown: return nil + default: return nil } } - return "Unknown" + return nil + } + + class func mapFromSetupIntentLastPaymentErrorType(_ errorType: STPSetupIntentLastSetupErrorType?) -> String? { + if let errorType = errorType { + switch errorType { + case STPSetupIntentLastSetupErrorType.apiConnection: return "api_connection_error" + case STPSetupIntentLastSetupErrorType.API: return "api_error" + case STPSetupIntentLastSetupErrorType.authentication: return "authentication_error" + case STPSetupIntentLastSetupErrorType.card: return "card_error" + case STPSetupIntentLastSetupErrorType.idempotency: return "idempotency_error" + case STPSetupIntentLastSetupErrorType.invalidRequest: return "invalid_request_error" + case STPSetupIntentLastSetupErrorType.rateLimit: return "rate_limit_error" + case STPSetupIntentLastSetupErrorType.unknown: return nil + default: return nil + } + } + return nil } class func mapToBillingDetails(billingDetails: NSDictionary?) -> STPPaymentMethodBillingDetails? { @@ -288,12 +456,12 @@ class Mappers { shippingAddress.line1 = shippingDetails["addressLine1"] as? String ?? "" shippingAddress.line2 = shippingDetails["addressLine2"] as? String shippingAddress.state = shippingDetails["addressState"] as? String - + let shipping = STPPaymentIntentShippingDetailsParams(address: shippingAddress, name: shippingDetails["name"] as? String ?? "") - + return shipping } - + class func mapFromBillingDetails(billingDetails: STPPaymentMethodBillingDetails?) -> NSDictionary { let billing: NSDictionary = [ "email": billingDetails?.email ?? NSNull(), @@ -312,7 +480,7 @@ class Mappers { return billing } - class func mapCardBrand(_ brand: STPCardBrand?) -> String { + class func mapCardBrand(_ brand: STPCardBrand?) -> String? { if let brand = brand { switch brand { case STPCardBrand.visa: return "Visa" @@ -323,15 +491,18 @@ class Mappers { case STPCardBrand.dinersClub: return "DinersClub" case STPCardBrand.unionPay: return "UnionPay" case STPCardBrand.unknown: return "Unknown" - default: return "Unknown" + default: return nil } } - return "Unknown" + return nil } - class func mapFromPaymentMethod(_ paymentMethod: STPPaymentMethod) -> NSDictionary { + class func mapFromPaymentMethod(_ paymentMethod: STPPaymentMethod?) -> NSDictionary? { + guard let paymentMethod = paymentMethod else { + return nil + } let card: NSDictionary = [ - "brand": Mappers.mapCardBrand(paymentMethod.card?.brand), + "brand": Mappers.mapCardBrand(paymentMethod.card?.brand) ?? NSNull(), "country": paymentMethod.card?.country ?? NSNull(), "expYear": paymentMethod.card?.expYear ?? NSNull(), "expMonth": paymentMethod.card?.expMonth ?? NSNull(), @@ -438,7 +609,7 @@ class Mappers { "lastSetupError": NSNull() ] - + let types = setupIntent.paymentMethodTypes.map { mapPaymentMethodType(type: STPPaymentMethodType.init(rawValue: Int(truncating: $0))!) } @@ -447,14 +618,16 @@ class Mappers { intent.setValue(convertDateToUnixTimestamp(date: setupIntent.created), forKey: "created") if let lastSetupError = setupIntent.lastSetupError { - let setupError = [ - "code": lastSetupError.code, - "message": lastSetupError.description + let setupError: NSMutableDictionary = [ + "code": lastSetupError.code ?? NSNull(), + "message": lastSetupError.description, + "type": mapFromSetupIntentLastPaymentErrorType(lastSetupError.type) ?? NSNull(), + "declineCode": lastSetupError.declineCode ?? NSNull(), + "paymentMethod": mapFromPaymentMethod(lastSetupError.paymentMethod) ?? NSNull() ] intent.setValue(setupError, forKey: "lastSetupError") } - return intent } @@ -560,16 +733,98 @@ class Mappers { if let textColor = submitButtonSettings["textColor"] as? String { buttonCustomization.textColor = UIColor(hexString: textColor) } + + uiCustomization.setButtonCustomization(buttonCustomization, for: STPThreeDSCustomizationButtonType.submit) + } + + if let submitButtonSettings = params["cancelButton"] as? Dictionary { + let buttonCustomization = uiCustomization.buttonCustomization(for: STPThreeDSCustomizationButtonType.cancel) + + if let backgroundColor = submitButtonSettings["backgroundColor"] as? String { + buttonCustomization.backgroundColor = UIColor(hexString: backgroundColor) + } + if let borderRadius = submitButtonSettings["borderRadius"] as? Int { + buttonCustomization.cornerRadius = CGFloat(borderRadius) + } + if let textFontSize = submitButtonSettings["textFontSize"] as? Int { + buttonCustomization.font = UIFont.systemFont(ofSize: CGFloat(textFontSize)) + } + if let textColor = submitButtonSettings["textColor"] as? String { + buttonCustomization.textColor = UIColor(hexString: textColor) + } + + uiCustomization.setButtonCustomization(buttonCustomization, for: STPThreeDSCustomizationButtonType.cancel) + } + + if let submitButtonSettings = params["continueButton"] as? Dictionary { + let buttonCustomization = uiCustomization.buttonCustomization(for: STPThreeDSCustomizationButtonType.continue) + + if let backgroundColor = submitButtonSettings["backgroundColor"] as? String { + buttonCustomization.backgroundColor = UIColor(hexString: backgroundColor) + } + if let borderRadius = submitButtonSettings["borderRadius"] as? Int { + buttonCustomization.cornerRadius = CGFloat(borderRadius) + } + if let textFontSize = submitButtonSettings["textFontSize"] as? Int { + buttonCustomization.font = UIFont.systemFont(ofSize: CGFloat(textFontSize)) + } + if let textColor = submitButtonSettings["textColor"] as? String { + buttonCustomization.textColor = UIColor(hexString: textColor) + } + + uiCustomization.setButtonCustomization(buttonCustomization, for: STPThreeDSCustomizationButtonType.continue) + } + + if let submitButtonSettings = params["nextButton"] as? Dictionary { + let buttonCustomization = uiCustomization.buttonCustomization(for: STPThreeDSCustomizationButtonType.next) + + if let backgroundColor = submitButtonSettings["backgroundColor"] as? String { + buttonCustomization.backgroundColor = UIColor(hexString: backgroundColor) + } + if let borderRadius = submitButtonSettings["borderRadius"] as? Int { + buttonCustomization.cornerRadius = CGFloat(borderRadius) + } + if let textFontSize = submitButtonSettings["textFontSize"] as? Int { + buttonCustomization.font = UIFont.systemFont(ofSize: CGFloat(textFontSize)) + } + if let textColor = submitButtonSettings["textColor"] as? String { + buttonCustomization.textColor = UIColor(hexString: textColor) + } + + uiCustomization.setButtonCustomization(buttonCustomization, for: STPThreeDSCustomizationButtonType.next) + } + + if let submitButtonSettings = params["resendButton"] as? Dictionary { + let buttonCustomization = uiCustomization.buttonCustomization(for: STPThreeDSCustomizationButtonType.resend) + + if let backgroundColor = submitButtonSettings["backgroundColor"] as? String { + buttonCustomization.backgroundColor = UIColor(hexString: backgroundColor) + } + if let borderRadius = submitButtonSettings["borderRadius"] as? Int { + buttonCustomization.cornerRadius = CGFloat(borderRadius) + } + if let textFontSize = submitButtonSettings["textFontSize"] as? Int { + buttonCustomization.font = UIFont.systemFont(ofSize: CGFloat(textFontSize)) + } + if let textColor = submitButtonSettings["textColor"] as? String { + buttonCustomization.textColor = UIColor(hexString: textColor) + } + + uiCustomization.setButtonCustomization(buttonCustomization, for: STPThreeDSCustomizationButtonType.resend) } if let backgroundColor = params["backgroundColor"] as? String { uiCustomization.backgroundColor = UIColor(hexString: backgroundColor) } + return uiCustomization } - class func convertDateToUnixTimestamp(date: Date) -> UInt64 { - return UInt64(date.timeIntervalSince1970 * 1000.0) + class func convertDateToUnixTimestamp(date: Date?) -> String? { + if let date = date { + return String(date.timeIntervalSince1970 * 1000.0) + } + return nil } } diff --git a/packages/stripe_ios/ios/Classes/PaymentMethodFactory.swift b/packages/stripe_ios/ios/Classes/PaymentMethodFactory.swift index 9d80fbc..43a089f 100644 --- a/packages/stripe_ios/ios/Classes/PaymentMethodFactory.swift +++ b/packages/stripe_ios/ios/Classes/PaymentMethodFactory.swift @@ -272,7 +272,7 @@ extension PaymentMethodError: LocalizedError { public var errorDescription: String? { switch self { case .cardPaymentMissingParams: - return NSLocalizedString("You must provide card details", comment: "Create payment error") + return NSLocalizedString("Card details not complete", comment: "Create payment error") case .giropayPaymentMissingParams: return NSLocalizedString("You must provide billing details", comment: "Create payment error") case .idealPaymentMissingParams: diff --git a/packages/stripe_ios/ios/Classes/RCTBridge.swift b/packages/stripe_ios/ios/Classes/RCTBridge.swift index 9e503e1..dc9c64a 100644 --- a/packages/stripe_ios/ios/Classes/RCTBridge.swift +++ b/packages/stripe_ios/ios/Classes/RCTBridge.swift @@ -40,6 +40,15 @@ protocol FlutterPluginBinding { } +extension FlutterError { + static func invalidParams(_ message: String?) -> FlutterError { + return FlutterError.init(code: "Invalid Params", message: message, details: nil) + } + + static var invalidParams: FlutterError { + return FlutterError.init(code: "Invalid Params", message: "", details: "") + } +} class RCTBridge { diff --git a/packages/stripe_ios/ios/Classes/StripePlugin.swift b/packages/stripe_ios/ios/Classes/StripePlugin.swift index 21b985b..ecb2650 100644 --- a/packages/stripe_ios/ios/Classes/StripePlugin.swift +++ b/packages/stripe_ios/ios/Classes/StripePlugin.swift @@ -64,11 +64,13 @@ public class StripePlugin: StripeSdk, FlutterPlugin { case "handleCardAction": return handleCardAction(call, result: result) case "confirmPaymentMethod": - return confirmPaymentMethod(call, result: result) + return confirmPayment(call, result: result) case "retrievePaymentIntent": return retrievePaymentIntent(call, result: result) case "createPaymentMethod": return createPaymentMethod(call, result: result) + case "createToken": + return createToken(call, result: result) default: result(FlutterMethodNotImplemented) } @@ -160,8 +162,10 @@ extension StripePlugin { result(FlutterError.invalidParams) return } + let errorAddressFields = arguments["errorAddressFields"] as? [NSDictionary] ?? [] updateApplePaySummaryItems( summaryItems: summaryItems, + errorAddressFields: errorAddressFields, resolver: resolver(for: result), rejecter: rejecter(for: result) ) @@ -241,7 +245,7 @@ extension StripePlugin { ) } - func confirmPaymentMethod(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + func confirmPayment(_ call: FlutterMethodCall, result: @escaping FlutterResult) { guard let arguments = call.arguments as? FlutterMap, let paymentIntentClientSecret = arguments["paymentIntentClientSecret"] as? String, let params = arguments["params"] as? NSDictionary, @@ -249,7 +253,7 @@ extension StripePlugin { result(FlutterError.invalidParams) return } - confirmPaymentMethod( + confirmPayment( paymentIntentClientSecret: paymentIntentClientSecret, params: params, options: options, @@ -282,4 +286,15 @@ extension StripePlugin { result(nil) } + public func createToken(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + guard let arguments = call.arguments as? FlutterMap, + let params = arguments["params"] as? NSDictionary else { + result(FlutterError.invalidParams) + return + } + createToken(params: params, + resolver: resolver(for: result), + rejecter: rejecter(for: result)) + } + } diff --git a/packages/stripe_ios/ios/Classes/StripeSdk.swift b/packages/stripe_ios/ios/Classes/StripeSdk.swift index 7e6ed84..ec64608 100644 --- a/packages/stripe_ios/ios/Classes/StripeSdk.swift +++ b/packages/stripe_ios/ios/Classes/StripeSdk.swift @@ -1,8 +1,7 @@ import PassKit import Stripe - - +@objc(StripeSdk) public class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSelectionViewControllerDelegate, UIAdaptivePresentationControllerDelegate { var merchantIdentifier: String? = nil @@ -17,7 +16,6 @@ public class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSele var applePayCompletionRejecter: RCTPromiseRejectBlock? = nil var confirmApplePayPaymentResolver: RCTPromiseResolveBlock? = nil var confirmPaymentResolver: RCTPromiseResolveBlock? = nil - var confirmPaymentRejecter: RCTPromiseRejectBlock? = nil var confirmPaymentClientSecret: String? = nil @@ -28,7 +26,7 @@ public class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSele return ["onDidSetShippingMethod", "onDidSetShippingContact"] } - + @objc(initialise:resolver:rejecter:) func initialise(params: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { let publishableKey = params["publishableKey"] as! String @@ -60,12 +58,6 @@ public class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSele @objc(initPaymentSheet:resolver:rejecter:) func initPaymentSheet(params: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { - guard let paymentIntentClientSecret = params["paymentIntentClientSecret"] as? String else { - reject(PaymentSheetErrorType.Failed.rawValue, "You must provide the paymentIntentClientSecret", nil) - return - } - - var configuration = PaymentSheet.Configuration() if params["applePay"] as? Bool == true { @@ -73,7 +65,8 @@ public class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSele configuration.applePay = .init(merchantId: merchantIdentifier, merchantCountryCode: merchantCountryCode) } else { - reject(PaymentSheetErrorType.Failed.rawValue, "merchantIdentifier or merchantCountryCode is not provided", nil) + resolve(Errors.createError(PaymentSheetErrorType.Failed.rawValue, "Either merchantIdentifier or merchantCountryCode is missing")) + return } } @@ -93,29 +86,48 @@ public class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSele } } - if params["customFlow"] as? Bool == true { - PaymentSheet.FlowController.create(paymentIntentClientSecret: paymentIntentClientSecret, - configuration: configuration) { [weak self] result in - switch result { - case .failure(let error): - reject("Failed", error.localizedDescription, nil) - case .success(let paymentSheetFlowController): - self?.paymentSheetFlowController = paymentSheetFlowController - if let paymentOption = self?.paymentSheetFlowController?.paymentOption { - let option: NSDictionary = [ - "label": paymentOption.label, - "image": paymentOption.image.pngData()?.base64EncodedString() ?? "" - ] - resolve(option) - } else { - reject("Failed", "in else", nil) - } + func handlePaymentSheetFlowControllerResult(result: Result, stripeSdk: StripeSdk?) { + switch result { + case .failure(let error): + resolve(Errors.createError("Failed", error.localizedDescription)) + case .success(let paymentSheetFlowController): + stripeSdk?.paymentSheetFlowController = paymentSheetFlowController + if let paymentOption = stripeSdk?.paymentSheetFlowController?.paymentOption { + let option: NSDictionary = [ + "label": paymentOption.label, + "image": paymentOption.image.pngData()?.base64EncodedString() ?? "" + ] + resolve(Mappers.createResult("paymentOption", option)) + } else { + resolve(Mappers.createResult("paymentOption", nil)) + } + } + } + + if let paymentIntentClientSecret = params["paymentIntentClientSecret"] as? String { + if params["customFlow"] as? Bool == true { + PaymentSheet.FlowController.create(paymentIntentClientSecret: paymentIntentClientSecret, + configuration: configuration) { [weak self] result in + handlePaymentSheetFlowControllerResult(result: result, stripeSdk: self) } + } else { + self.paymentSheet = PaymentSheet(paymentIntentClientSecret: paymentIntentClientSecret, configuration: configuration) + resolve([]) + } + } else if let setupIntentClientSecret = params["setupIntentClientSecret"] as? String { + if params["customFlow"] as? Bool == true { + PaymentSheet.FlowController.create(setupIntentClientSecret: setupIntentClientSecret, + configuration: configuration) { [weak self] result in + handlePaymentSheetFlowControllerResult(result: result, stripeSdk: self) + } + } else { + self.paymentSheet = PaymentSheet(setupIntentClientSecret: setupIntentClientSecret, configuration: configuration) + resolve([]) } } else { - self.paymentSheet = PaymentSheet(paymentIntentClientSecret: paymentIntentClientSecret, configuration: configuration) - resolve(NSNull()) + resolve(Errors.createError(PaymentSheetErrorType.Failed.rawValue, "You must provide either paymentIntentClientSecret or setupIntentClientSecret")) } + } @objc(confirmPaymentSheetPayment:rejecter:) @@ -127,9 +139,9 @@ public class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSele case .completed: resolve([]) case .canceled: - reject(PaymentSheetErrorType.Canceled.rawValue, "The payment has been canceled", nil) + resolve(Errors.createError(PaymentSheetErrorType.Canceled.rawValue, "The payment has been canceled")) case .failed(let error): - reject(PaymentSheetErrorType.Failed.rawValue, error.localizedDescription, nil) + resolve(Errors.createError(PaymentSheetErrorType.Failed.rawValue, error.localizedDescription)) } } } @@ -148,9 +160,9 @@ public class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSele "label": paymentOption.label, "image": paymentOption.image.pngData()?.base64EncodedString() ?? "" ] - resolve(["paymentOption": option]) + resolve(Mappers.createResult("paymentOption", option)) } else { - resolve(NSNull()) + resolve(Mappers.createResult("paymentOption", nil)) } } } else { @@ -159,30 +171,28 @@ public class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSele case .completed: resolve([]) case .canceled: - reject(PaymentSheetErrorType.Canceled.rawValue, "The payment has been canceled", nil) + resolve(Errors.createError(PaymentSheetErrorType.Canceled.rawValue, "The payment has been canceled")) case .failed(let error): - reject(PaymentSheetErrorType.Failed.rawValue, error.localizedDescription, nil) + resolve(Errors.createError(PaymentSheetErrorType.Failed.rawValue, error.localizedDescription)) } } } } } - - @objc(createTokenForCVCUpdate:resolver:rejecter:) func createTokenForCVCUpdate(cvc: String?, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { guard let cvc = cvc else { - reject("Failed", "You must provide CVC", nil) + resolve(Errors.createError("Failed", "You must provide CVC")) return; } STPAPIClient.shared.createToken(forCVCUpdate: cvc) { (token, error) in if error != nil || token == nil { - reject("Failed", error?.localizedDescription, nil) + resolve(Errors.createError("Failed", error?.localizedDescription ?? "")) } else { let tokenId = token?.tokenId - resolve(tokenId) + resolve(["tokenId": tokenId]) } } } @@ -193,7 +203,7 @@ public class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSele rejecter reject: @escaping RCTPromiseRejectBlock) { let type = Mappers.mapToPaymentMethodType(type: params["type"] as? String) guard let paymentMethodType = type else { - reject(ConfirmPaymentErrorType.Failed.rawValue, "You must provide paymentMethodType", nil) + resolve(Errors.createError(ConfirmPaymentErrorType.Failed.rawValue, "You must provide paymentMethodType")) return } @@ -206,10 +216,11 @@ public class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSele do { paymentMethodParams = try factory.createParams(paymentMethodType: paymentMethodType) } catch { - reject(ConfirmPaymentErrorType.Failed.rawValue, error.localizedDescription, nil) + resolve(Errors.createError(ConfirmPaymentErrorType.Failed.rawValue, error.localizedDescription)) + return } guard paymentMethodParams != nil else { - reject(ConfirmPaymentErrorType.Unknown.rawValue, "Unhandled error occured", nil) + resolve(Errors.createError(ConfirmPaymentErrorType.Unknown.rawValue, "Unhandled error occured")) return } @@ -224,25 +235,29 @@ public class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSele paymentHandler.confirmSetupIntent(setupIntentParams, with: self) { status, setupIntent, error in switch (status) { case .failed: - reject(ConfirmSetupIntentErrorType.Failed.rawValue, error?.localizedDescription ?? "", nil) + resolve(Errors.createError(ConfirmSetupIntentErrorType.Failed.rawValue, error)) break case .canceled: - reject(ConfirmSetupIntentErrorType.Canceled.rawValue, error?.localizedDescription ?? "", nil) + if let lastError = setupIntent?.lastSetupError { + resolve(Errors.createError(ConfirmSetupIntentErrorType.Canceled.rawValue, lastError)) + } else { + resolve(Errors.createError(ConfirmSetupIntentErrorType.Canceled.rawValue, "The payment has been canceled")) + } break case .succeeded: let intent = Mappers.mapFromSetupIntent(setupIntent: setupIntent!) - resolve(intent) + resolve(Mappers.createResult("setupIntent", intent)) @unknown default: - reject(ConfirmSetupIntentErrorType.Unknown.rawValue, error?.localizedDescription ?? "", nil) + resolve(Errors.createError(ConfirmSetupIntentErrorType.Unknown.rawValue, error)) break } } } - @objc(updateApplePaySummaryItems:resolver:rejecter:) - func updateApplePaySummaryItems(summaryItems: NSArray, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { + @objc(updateApplePaySummaryItems:errorAddressFields:resolver:rejecter:) + func updateApplePaySummaryItems(summaryItems: NSArray, errorAddressFields: [NSDictionary], resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { if (shippingMethodUpdateHandler == nil && shippingContactUpdateHandler == nil) { - reject(ApplePayErrorType.Failed.rawValue, "You can use this method only after either onDidSetShippingMethod or onDidSetShippingContact events emitted", nil) + resolve(Errors.createError(ApplePayErrorType.Failed.rawValue, "You can use this method only after either onDidSetShippingMethod or onDidSetShippingContact events emitted")) return } var paymentSummaryItems: [PKPaymentSummaryItem] = [] @@ -254,11 +269,19 @@ public class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSele paymentSummaryItems.append(PKPaymentSummaryItem(label: label, amount: amount, type: type)) } } + var shippingAddressErrors: [Error] = [] + + for item in errorAddressFields { + let field = item["field"] as! String + let message = item["message"] as? String ?? field + " error" + shippingAddressErrors.append(PKPaymentRequest.paymentShippingAddressInvalidError(withKey: field, localizedDescription: message)) + } + shippingMethodUpdateHandler?(PKPaymentRequestShippingMethodUpdate.init(paymentSummaryItems: paymentSummaryItems)) - shippingContactUpdateHandler?(PKPaymentRequestShippingContactUpdate.init(paymentSummaryItems: paymentSummaryItems)) + shippingContactUpdateHandler?(PKPaymentRequestShippingContactUpdate.init(errors: shippingAddressErrors, paymentSummaryItems: paymentSummaryItems, shippingMethods: [])) self.shippingMethodUpdateHandler = nil self.shippingContactUpdateHandler = nil - resolve(NSNull()) + resolve([]) } @@ -274,14 +297,16 @@ public class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSele public func applePayContext(_ context: STPApplePayContext, didCreatePaymentMethod paymentMethod: STPPaymentMethod, paymentInformation: PKPayment, completion: @escaping STPIntentClientSecretCompletionBlock) { self.applePayCompletionCallback = completion - self.applePayRequestResolver?([NSNull()]) + let method = Mappers.mapFromPaymentMethod(paymentMethod) + self.applePayRequestResolver?(Mappers.createResult("paymentMethod", method)) + self.applePayRequestRejecter = nil } @objc(confirmApplePayPayment:resolver:rejecter:) func confirmApplePayPayment(clientSecret: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { self.applePayCompletionRejecter = reject - self.applePayCompletionCallback?(clientSecret, nil) self.confirmApplePayPaymentResolver = resolve + self.applePayCompletionCallback?(clientSecret, nil) } public func applePayContext(_ context: STPApplePayContext, didCompleteWith status: STPPaymentStatus, error: Error?) { @@ -289,24 +314,24 @@ public class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSele case .success: applePayCompletionRejecter = nil applePayRequestRejecter = nil - confirmApplePayPaymentResolver?([NSNull()]) + confirmApplePayPaymentResolver?([]) break case .error: - let message = "Apple pay completion failed" + let message = "Payment not completed" applePayCompletionRejecter?(ApplePayErrorType.Failed.rawValue, message, nil) applePayRequestRejecter?(ApplePayErrorType.Failed.rawValue, message, nil) applePayCompletionRejecter = nil applePayRequestRejecter = nil break case .userCancellation: - let message = "Apple pay payment has been cancelled" + let message = "The payment has been canceled" applePayCompletionRejecter?(ApplePayErrorType.Canceled.rawValue, message, nil) applePayRequestRejecter?(ApplePayErrorType.Canceled.rawValue, message, nil) applePayCompletionRejecter = nil applePayRequestRejecter = nil break @unknown default: - let message = "Cannot complete payment" + let message = "Payment not completed" applePayCompletionRejecter?(ApplePayErrorType.Unknown.rawValue, message, nil) applePayRequestRejecter?(ApplePayErrorType.Unknown.rawValue, message, nil) applePayCompletionRejecter = nil @@ -394,13 +419,13 @@ public class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSele paymentRequest.paymentSummaryItems = paymentSummaryItems if let applePayContext = STPApplePayContext(paymentRequest: paymentRequest, delegate: self) { DispatchQueue.main.async { - applePayContext.presentApplePay(on: UIApplication.shared.delegate?.window??.rootViewController ?? UIViewController()) + applePayContext.presentApplePay(completion: nil) } } else { - reject(ApplePayErrorType.Failed.rawValue, "Apple pay request failed", nil) + reject(ApplePayErrorType.Failed.rawValue, "Payment not completed", nil) } } - + func configure3dSecure(_ params: NSDictionary) { let threeDSCustomizationSettings = STPPaymentHandler.shared().threeDSCustomizationSettings let uiCustomization = Mappers.mapUICustomization(params) @@ -417,7 +442,7 @@ public class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSele ) -> Void { let type = Mappers.mapToPaymentMethodType(type: params["type"] as? String) guard let paymentMethodType = type else { - reject(NextPaymentActionErrorType.Failed.rawValue, "You must provide paymentMethodType", nil) + resolve(Errors.createError(NextPaymentActionErrorType.Failed.rawValue, "You must provide paymentMethodType")) return } @@ -430,22 +455,63 @@ public class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSele do { paymentMethodParams = try factory.createParams(paymentMethodType: paymentMethodType) } catch { - reject(NextPaymentActionErrorType.Failed.rawValue, error.localizedDescription, nil) + resolve(Errors.createError(NextPaymentActionErrorType.Failed.rawValue, error.localizedDescription)) + return } guard let params = paymentMethodParams else { - reject(NextPaymentActionErrorType.Unknown.rawValue, "Unhandled error occured", nil) + resolve(Errors.createError(NextPaymentActionErrorType.Unknown.rawValue, "Unhandled error occured")) return } STPAPIClient.shared.createPaymentMethod(with: params) { paymentMethod, error in if let createError = error { - reject(NextPaymentActionErrorType.Failed.rawValue, createError.localizedDescription, nil) + resolve(Errors.createError(NextPaymentActionErrorType.Failed.rawValue, createError.localizedDescription)) + return } if let paymentMethod = paymentMethod { let method = Mappers.mapFromPaymentMethod(paymentMethod) - resolve(method) + resolve(Mappers.createResult("paymentMethod", method)) + } + } + } + + @objc(createToken:resolver:rejecter:) + func createToken( + params: NSDictionary, + resolver resolve: @escaping RCTPromiseResolveBlock, + rejecter reject: @escaping RCTPromiseRejectBlock + ) -> Void { + let address = params["address"] as? NSDictionary + + if let type = params["type"] as? String { + if (type != "Card") { + resolve(Errors.createError(CreateTokenErrorType.Failed.rawValue, type + " type is not supported yet")) + } + } + + let cardFieldUIManager = bridge.module(forName: "CardFieldManager") as? CardFieldManager + let cardFieldView = cardFieldUIManager?.getCardFieldReference(id: CARD_FIELD_INSTANCE_ID) as? CardFieldView + + guard let cardParams = cardFieldView?.cardParams else { + resolve(Errors.createError(CreateTokenErrorType.Failed.rawValue, "Card details not complete")) + return + } + + let cardSourceParams = STPCardParams() + cardSourceParams.number = cardParams.number + cardSourceParams.cvc = cardParams.cvc + cardSourceParams.expMonth = UInt(truncating: cardParams.expMonth ?? 0) + cardSourceParams.expYear = UInt(truncating: cardParams.expYear ?? 0) + cardSourceParams.address = Mappers.mapToAddress(address: address) + cardSourceParams.name = params["name"] as? String + + STPAPIClient.shared.createToken(withCard: cardSourceParams) { token, error in + if let token = token { + resolve(Mappers.mapFromToken(token: token)) + } else { + resolve(Errors.createError(CreateTokenErrorType.Failed.rawValue, error?.localizedDescription)) } } } @@ -460,25 +526,29 @@ public class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSele paymentHandler.handleNextAction(forPayment: paymentIntentClientSecret, with: self, returnURL: nil) { status, paymentIntent, handleActionError in switch (status) { case .failed: - reject(NextPaymentActionErrorType.Failed.rawValue, handleActionError?.localizedDescription ?? "", nil) + resolve(Errors.createError(NextPaymentActionErrorType.Failed.rawValue, handleActionError)) break case .canceled: - reject(NextPaymentActionErrorType.Canceled.rawValue, handleActionError?.localizedDescription ?? "", nil) + if let lastError = paymentIntent?.lastPaymentError { + resolve(Errors.createError(NextPaymentActionErrorType.Canceled.rawValue, lastError)) + } else { + resolve(Errors.createError(NextPaymentActionErrorType.Canceled.rawValue, "The payment has been canceled")) + } break case .succeeded: if let paymentIntent = paymentIntent { - resolve(Mappers.mapFromPaymentIntent(paymentIntent: paymentIntent)) + resolve(Mappers.createResult("paymentIntent", Mappers.mapFromPaymentIntent(paymentIntent: paymentIntent))) } break @unknown default: - reject(NextPaymentActionErrorType.Unknown.rawValue, "Cannot complete payment", nil) + resolve(Errors.createError(NextPaymentActionErrorType.Unknown.rawValue, "Cannot complete payment")) break } } } - @objc(confirmPaymentMethod:data:options:resolver:rejecter:) - func confirmPaymentMethod( + @objc(confirmPayment:data:options:resolver:rejecter:) + func confirmPayment( paymentIntentClientSecret: String, params: NSDictionary, options: NSDictionary, @@ -486,7 +556,6 @@ public class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSele rejecter reject: @escaping RCTPromiseRejectBlock ) -> Void { self.confirmPaymentResolver = resolve - self.confirmPaymentRejecter = reject self.confirmPaymentClientSecret = paymentIntentClientSecret let cardFieldUIManager = bridge.module(forName: "CardFieldManager") as? CardFieldManager @@ -500,7 +569,7 @@ public class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSele let type = Mappers.mapToPaymentMethodType(type: params["type"] as? String) guard let paymentMethodType = type else { - reject(ConfirmPaymentErrorType.Failed.rawValue, "You must provide paymentMethodType", nil) + resolve(Errors.createError(ConfirmPaymentErrorType.Failed.rawValue, "You must provide paymentMethodType")) return } @@ -522,10 +591,10 @@ public class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSele paymentMethodParams = try factory.createParams(paymentMethodType: paymentMethodType) paymentMethodOptions = try factory.createOptions(paymentMethodType: paymentMethodType) } catch { - reject(ConfirmPaymentErrorType.Failed.rawValue, error.localizedDescription, nil) + resolve(Errors.createError(ConfirmPaymentErrorType.Failed.rawValue, error.localizedDescription)) } guard paymentMethodParams != nil else { - reject(ConfirmPaymentErrorType.Unknown.rawValue, "Unhandled error occured", nil) + resolve(Errors.createError(ConfirmPaymentErrorType.Unknown.rawValue, "Unhandled error occured")) return } paymentIntentParams.paymentMethodParams = paymentMethodParams @@ -549,20 +618,50 @@ public class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSele ) -> Void { STPAPIClient.shared.retrievePaymentIntent(withClientSecret: clientSecret) { (paymentIntent, error) in guard error == nil else { - reject(RetrievePaymentIntentErrorType.Unknown.rawValue, error?.localizedDescription, nil) + if let lastPaymentError = paymentIntent?.lastPaymentError { + resolve(Errors.createError(RetrievePaymentIntentErrorType.Unknown.rawValue, lastPaymentError)) + } else { + resolve(Errors.createError(RetrievePaymentIntentErrorType.Unknown.rawValue, error?.localizedDescription)) + } + return } if let paymentIntent = paymentIntent { - resolve(Mappers.mapFromPaymentIntent(paymentIntent: paymentIntent)) + resolve(Mappers.createResult("paymentIntent", Mappers.mapFromPaymentIntent(paymentIntent: paymentIntent))) } else { - reject(RetrievePaymentIntentErrorType.Unknown.rawValue, "Cannot retrieve PaymentIntent", nil) + resolve(Errors.createError(RetrievePaymentIntentErrorType.Unknown.rawValue, "Failed to retrieve the PaymentIntent")) + } + } + } + + @objc(retrieveSetupIntent:resolver:rejecter:) + func retrieveSetupIntent( + clientSecret: String, + resolver resolve: @escaping RCTPromiseResolveBlock, + rejecter reject: @escaping RCTPromiseRejectBlock + ) -> Void { + STPAPIClient.shared.retrieveSetupIntent(withClientSecret: clientSecret) { (setupIntent, error) in + guard error == nil else { + if let lastSetupError = setupIntent?.lastSetupError { + resolve(Errors.createError(RetrieveSetupIntentErrorType.Unknown.rawValue, lastSetupError)) + } else { + resolve(Errors.createError(RetrieveSetupIntentErrorType.Unknown.rawValue, error?.localizedDescription)) + } + + return + } + + if let setupIntent = setupIntent { + resolve(Mappers.createResult("setupIntent", Mappers.mapFromSetupIntent(setupIntent: setupIntent))) + } else { + resolve(Errors.createError(RetrieveSetupIntentErrorType.Unknown.rawValue, "Failed to retrieve the SetupIntent")) } } } public func presentationControllerDidDismiss(_ presentationController: UIPresentationController) { - confirmPaymentRejecter?(ConfirmPaymentErrorType.Canceled.rawValue, "FPX Payment has been canceled", nil) + confirmPaymentResolver?(Errors.createError(ConfirmPaymentErrorType.Canceled.rawValue, "FPX Payment has been canceled")) } func payWithFPX(_ paymentIntentClientSecret: String) { @@ -580,7 +679,7 @@ public class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSele public func bankSelectionViewController(_ bankViewController: STPBankSelectionViewController, didCreatePaymentMethodParams paymentMethodParams: STPPaymentMethodParams) { guard let clientSecret = confirmPaymentClientSecret else { - confirmPaymentRejecter?(ConfirmPaymentErrorType.Failed.rawValue, "Missing paymentIntentClientSecret", nil) + confirmPaymentResolver?(Errors.createError(ConfirmPaymentErrorType.Failed.rawValue, "Missing paymentIntentClientSecret")) return } let paymentIntentParams = STPPaymentIntentParams(clientSecret: clientSecret) @@ -598,7 +697,7 @@ public class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSele self.confirmPaymentClientSecret = nil switch (status) { case .failed: - confirmPaymentRejecter?(ConfirmPaymentErrorType.Failed.rawValue, paymentIntent?.lastPaymentError?.message ?? error?.localizedDescription ?? "", nil) + confirmPaymentResolver?(Errors.createError(ConfirmPaymentErrorType.Failed.rawValue, error)) break case .canceled: let statusCode: String @@ -607,16 +706,20 @@ public class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSele } else { statusCode = ConfirmPaymentErrorType.Canceled.rawValue } - confirmPaymentRejecter?(statusCode, paymentIntent?.lastPaymentError?.message ?? error?.localizedDescription ?? "", nil) + if let lastPaymentError = paymentIntent?.lastPaymentError { + confirmPaymentResolver?(Errors.createError(statusCode, lastPaymentError)) + } else { + confirmPaymentResolver?(Errors.createError(statusCode, "The payment has been canceled")) + } break case .succeeded: if let paymentIntent = paymentIntent { let intent = Mappers.mapFromPaymentIntent(paymentIntent: paymentIntent) - confirmPaymentResolver?(intent) + confirmPaymentResolver?(Mappers.createResult("paymentIntent", intent)) } break @unknown default: - confirmPaymentRejecter?(ConfirmPaymentErrorType.Unknown.rawValue, "Cannot complete payment", nil) + confirmPaymentResolver?(Errors.createError(ConfirmPaymentErrorType.Unknown.rawValue, "Cannot complete the payment")) break } } diff --git a/packages/stripe_ios/pubspec.yaml b/packages/stripe_ios/pubspec.yaml index 85fc3db..bc847b1 100644 --- a/packages/stripe_ios/pubspec.yaml +++ b/packages/stripe_ios/pubspec.yaml @@ -15,7 +15,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - pedantic: ^1.11.0 + flutter_lints: ^1.0.3 flutter: plugin: diff --git a/packages/stripe_platform_interface/lib/src/method_channel_stripe.dart b/packages/stripe_platform_interface/lib/src/method_channel_stripe.dart index c9fb1b4..37f397f 100644 --- a/packages/stripe_platform_interface/lib/src/method_channel_stripe.dart +++ b/packages/stripe_platform_interface/lib/src/method_channel_stripe.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'package:flutter/services.dart'; +import 'package:stripe_platform_interface/src/models/create_token_data.dart'; import 'models/app_info.dart'; import 'models/apple_pay.dart'; @@ -42,6 +43,7 @@ class MethodChannelStripe extends StripePlatform { 'merchantIdentifier': merchantIdentifier, 'appInfo': _appInfo.toJson(), 'threeDSecureParams': threeDSecureParams, + 'urlScheme': urlScheme, }); } @@ -55,8 +57,11 @@ class MethodChannelStripe extends StripePlatform { 'data': data.toJson(), 'options': options, }); + + final tmp = result?['paymentMethod'] as Map; + return PaymentMethod.fromJson( - result.unfoldToNonNull(), + tmp.unfoldToNonNull(), ); } @@ -80,7 +85,10 @@ class MethodChannelStripe extends StripePlatform { 'params': params.toJson(), 'options': options, }); - return PaymentIntent.fromJson(result.unfoldToNonNull()); + + final tmp = result?['paymentIntent'] as Map; + + return PaymentIntent.fromJson(tmp.unfoldToNonNull()); } on Exception catch (_) { throw const StripeError( code: PaymentIntentError.unknown, @@ -101,8 +109,9 @@ class MethodChannelStripe extends StripePlatform { 'params': data.toJson(), 'options': options, }); + final tmp = result.unfoldToNonNull(); - return SetupIntent.fromJson(result.unfoldToNonNull()); + return SetupIntent.fromJson(tmp['setupIntent']); } @override @@ -124,7 +133,9 @@ class MethodChannelStripe extends StripePlatform { 'paymentIntentClientSecret': paymentIntentClientSecret, }); - return PaymentIntent.fromJson(result.unfoldToNonNull()); + final tmp = result?['paymentIntent'] as Map; + + return PaymentIntent.fromJson(tmp.unfoldToNonNull()); } on Exception catch (_) { throw const StripeError( code: PaymentIntentError.unknown, @@ -159,7 +170,9 @@ class MethodChannelStripe extends StripePlatform { 'clientSecret': clientSecret, }); - return PaymentIntent.fromJson(result.unfoldToNonNull()); + final tmp = result?['paymentIntent'] as Map; + + return PaymentIntent.fromJson(tmp.unfoldToNonNull()); } on Exception catch (_) { throw const StripeError( code: PaymentIntentError.unknown, @@ -170,7 +183,7 @@ class MethodChannelStripe extends StripePlatform { @override Future initPaymentSheet(SetupPaymentSheetParameters params) async { - await _methodChannel.invokeMapMethod( + await _methodChannel.invokeMethod( 'initPaymentSheet', {'params': params.toJson()}, ); @@ -188,6 +201,21 @@ class MethodChannelStripe extends StripePlatform { Future confirmPaymentSheetPayment() async { await _methodChannel.invokeMethod('confirmPaymentSheetPayment'); } + + @override + Future createToken(CreateTokenParams params) async { + try { + final result = await _methodChannel.invokeMapMethod( + 'createToken', {'params': params.toJson()}); + + return TokenData.fromJson(result.unfoldToNonNull()); + } on Exception catch (e) { + throw StripeError( + code: CreateTokenError.unknown, + message: 'Create token failed with exception: $e', + ); + } + } } class MethodChannelStripeFactory { diff --git a/packages/stripe_platform_interface/lib/src/models/address.freezed.dart b/packages/stripe_platform_interface/lib/src/models/address.freezed.dart index 5e60fb6..81669a0 100644 --- a/packages/stripe_platform_interface/lib/src/models/address.freezed.dart +++ b/packages/stripe_platform_interface/lib/src/models/address.freezed.dart @@ -190,9 +190,9 @@ class __$AddressCopyWithImpl<$Res> extends _$AddressCopyWithImpl<$Res> } } -@JsonSerializable(explicitToJson: true) - /// @nodoc + +@JsonSerializable(explicitToJson: true) class _$_Address implements _Address { const _$_Address( {required this.city, diff --git a/packages/stripe_platform_interface/lib/src/models/app_info.freezed.dart b/packages/stripe_platform_interface/lib/src/models/app_info.freezed.dart index e1e6352..6c2da84 100644 --- a/packages/stripe_platform_interface/lib/src/models/app_info.freezed.dart +++ b/packages/stripe_platform_interface/lib/src/models/app_info.freezed.dart @@ -138,9 +138,9 @@ class __$AppInfoCopyWithImpl<$Res> extends _$AppInfoCopyWithImpl<$Res> } } -@JsonSerializable(explicitToJson: true) - /// @nodoc + +@JsonSerializable(explicitToJson: true) class _$_AppInfo implements _AppInfo { const _$_AppInfo({this.name, this.partnerId, this.url, this.version}); diff --git a/packages/stripe_platform_interface/lib/src/models/apple_pay.freezed.dart b/packages/stripe_platform_interface/lib/src/models/apple_pay.freezed.dart index b5211d3..333c71a 100644 --- a/packages/stripe_platform_interface/lib/src/models/apple_pay.freezed.dart +++ b/packages/stripe_platform_interface/lib/src/models/apple_pay.freezed.dart @@ -172,9 +172,9 @@ class __$ApplePayShippingMethodCopyWithImpl<$Res> } } -@JsonSerializable(explicitToJson: true) - /// @nodoc + +@JsonSerializable(explicitToJson: true) class _$_ApplePayShippingMethod implements _ApplePayShippingMethod { const _$_ApplePayShippingMethod( {required this.label, @@ -381,9 +381,8 @@ class __$ApplePayCartSummaryItemCopyWithImpl<$Res> } } -@JsonSerializable() - /// @nodoc +@JsonSerializable() class _$_ApplePayCartSummaryItem implements _ApplePayCartSummaryItem { const _$_ApplePayCartSummaryItem({required this.label, required this.amount}); @@ -646,9 +645,9 @@ class __$ApplePayPresentParamsCopyWithImpl<$Res> } } -@JsonSerializable(explicitToJson: true) - /// @nodoc + +@JsonSerializable(explicitToJson: true) class _$_ApplePayPresentParams implements _ApplePayPresentParams { const _$_ApplePayPresentParams( {required this.cartItems, diff --git a/packages/stripe_platform_interface/lib/src/models/card_field_input.dart b/packages/stripe_platform_interface/lib/src/models/card_field_input.dart index 86e10bd..4f1ed85 100644 --- a/packages/stripe_platform_interface/lib/src/models/card_field_input.dart +++ b/packages/stripe_platform_interface/lib/src/models/card_field_input.dart @@ -38,6 +38,9 @@ class CardStyle with _$CardStyle { /// Font size. double? fontSize, + /// Font family + String? fontFamily, + /// Color of the input in case incorrect data is entered. @JsonKey(toJson: ColorKey.toJson, fromJson: ColorKey.fromJson) Color? textErrorColor, @@ -62,6 +65,7 @@ class CardStyle with _$CardStyle { fontSize: style?.fontSize ?? fontSize, textErrorColor: style?.textErrorColor ?? textErrorColor, placeholderColor: style?.placeholderColor ?? placeholderColor, + fontFamily: style?.fontFamily ?? fontFamily, ); } @@ -131,10 +135,10 @@ class CardFieldInputDetails with _$CardFieldInputDetails { String? last4, /// Month of the entered expiry date of the card. - String? expiryMonth, + int? expiryMonth, /// Year of the entered expiry date of the card. - String? expiryYear, + int? expiryYear, /// Entered postcal code. String? postalCode, @@ -161,15 +165,19 @@ class CardFieldFocusName with _$CardFieldFocusName { /// Enum representing the different fiels on the card field. enum CardFieldName { @JsonValue('CardNumber') + /// Card number field. cardNumber, @JsonValue('Cvc') + /// Cvc field. cvc, @JsonValue('ExpiryDate') + /// Expiry date field. expiryDate, @JsonValue('PostalCode') + /// Postal code field. postalCode, } diff --git a/packages/stripe_platform_interface/lib/src/models/card_field_input.freezed.dart b/packages/stripe_platform_interface/lib/src/models/card_field_input.freezed.dart index 01c5a58..a4869a3 100644 --- a/packages/stripe_platform_interface/lib/src/models/card_field_input.freezed.dart +++ b/packages/stripe_platform_interface/lib/src/models/card_field_input.freezed.dart @@ -32,6 +32,7 @@ class _$CardStyleTearOff { @JsonKey(toJson: ColorKey.toJson, fromJson: ColorKey.fromJson) Color? textColor, double? fontSize, + String? fontFamily, @JsonKey(toJson: ColorKey.toJson, fromJson: ColorKey.fromJson) Color? textErrorColor, @JsonKey(toJson: ColorKey.toJson, fromJson: ColorKey.fromJson) @@ -44,6 +45,7 @@ class _$CardStyleTearOff { cursorColor: cursorColor, textColor: textColor, fontSize: fontSize, + fontFamily: fontFamily, textErrorColor: textErrorColor, placeholderColor: placeholderColor, ); @@ -76,6 +78,9 @@ mixin _$CardStyle { /// Font size. double? get fontSize => throw _privateConstructorUsedError; + /// Font family + String? get fontFamily => throw _privateConstructorUsedError; + /// Color of the input in case incorrect data is entered. @JsonKey(toJson: ColorKey.toJson, fromJson: ColorKey.fromJson) Color? get textErrorColor => throw _privateConstructorUsedError; @@ -104,6 +109,7 @@ abstract class $CardStyleCopyWith<$Res> { @JsonKey(toJson: ColorKey.toJson, fromJson: ColorKey.fromJson) Color? textColor, double? fontSize, + String? fontFamily, @JsonKey(toJson: ColorKey.toJson, fromJson: ColorKey.fromJson) Color? textErrorColor, @JsonKey(toJson: ColorKey.toJson, fromJson: ColorKey.fromJson) @@ -127,6 +133,7 @@ class _$CardStyleCopyWithImpl<$Res> implements $CardStyleCopyWith<$Res> { Object? cursorColor = freezed, Object? textColor = freezed, Object? fontSize = freezed, + Object? fontFamily = freezed, Object? textErrorColor = freezed, Object? placeholderColor = freezed, }) { @@ -159,6 +166,10 @@ class _$CardStyleCopyWithImpl<$Res> implements $CardStyleCopyWith<$Res> { ? _value.fontSize : fontSize // ignore: cast_nullable_to_non_nullable as double?, + fontFamily: fontFamily == freezed + ? _value.fontFamily + : fontFamily // ignore: cast_nullable_to_non_nullable + as String?, textErrorColor: textErrorColor == freezed ? _value.textErrorColor : textErrorColor // ignore: cast_nullable_to_non_nullable @@ -190,6 +201,7 @@ abstract class _$CardStyleConstructorCopyWith<$Res> @JsonKey(toJson: ColorKey.toJson, fromJson: ColorKey.fromJson) Color? textColor, double? fontSize, + String? fontFamily, @JsonKey(toJson: ColorKey.toJson, fromJson: ColorKey.fromJson) Color? textErrorColor, @JsonKey(toJson: ColorKey.toJson, fromJson: ColorKey.fromJson) @@ -216,6 +228,7 @@ class __$CardStyleConstructorCopyWithImpl<$Res> Object? cursorColor = freezed, Object? textColor = freezed, Object? fontSize = freezed, + Object? fontFamily = freezed, Object? textErrorColor = freezed, Object? placeholderColor = freezed, }) { @@ -248,6 +261,10 @@ class __$CardStyleConstructorCopyWithImpl<$Res> ? _value.fontSize : fontSize // ignore: cast_nullable_to_non_nullable as double?, + fontFamily: fontFamily == freezed + ? _value.fontFamily + : fontFamily // ignore: cast_nullable_to_non_nullable + as String?, textErrorColor: textErrorColor == freezed ? _value.textErrorColor : textErrorColor // ignore: cast_nullable_to_non_nullable @@ -260,9 +277,9 @@ class __$CardStyleConstructorCopyWithImpl<$Res> } } -@JsonSerializable(explicitToJson: true) - /// @nodoc + +@JsonSerializable(explicitToJson: true) class _$_CardStyleConstructor extends _CardStyleConstructor { _$_CardStyleConstructor( {this.borderWidth, @@ -276,6 +293,7 @@ class _$_CardStyleConstructor extends _CardStyleConstructor { @JsonKey(toJson: ColorKey.toJson, fromJson: ColorKey.fromJson) this.textColor, this.fontSize, + this.fontFamily, @JsonKey(toJson: ColorKey.toJson, fromJson: ColorKey.fromJson) this.textErrorColor, @JsonKey(toJson: ColorKey.toJson, fromJson: ColorKey.fromJson) @@ -311,6 +329,10 @@ class _$_CardStyleConstructor extends _CardStyleConstructor { final double? fontSize; @override + /// Font family + final String? fontFamily; + @override + /// Color of the input in case incorrect data is entered. @JsonKey(toJson: ColorKey.toJson, fromJson: ColorKey.fromJson) final Color? textErrorColor; @@ -320,7 +342,7 @@ class _$_CardStyleConstructor extends _CardStyleConstructor { @override String toString() { - return 'CardStyle(borderWidth: $borderWidth, backgroundColor: $backgroundColor, borderColor: $borderColor, borderRadius: $borderRadius, cursorColor: $cursorColor, textColor: $textColor, fontSize: $fontSize, textErrorColor: $textErrorColor, placeholderColor: $placeholderColor)'; + return 'CardStyle(borderWidth: $borderWidth, backgroundColor: $backgroundColor, borderColor: $borderColor, borderRadius: $borderRadius, cursorColor: $cursorColor, textColor: $textColor, fontSize: $fontSize, fontFamily: $fontFamily, textErrorColor: $textErrorColor, placeholderColor: $placeholderColor)'; } @override @@ -348,6 +370,9 @@ class _$_CardStyleConstructor extends _CardStyleConstructor { (identical(other.fontSize, fontSize) || const DeepCollectionEquality() .equals(other.fontSize, fontSize)) && + (identical(other.fontFamily, fontFamily) || + const DeepCollectionEquality() + .equals(other.fontFamily, fontFamily)) && (identical(other.textErrorColor, textErrorColor) || const DeepCollectionEquality() .equals(other.textErrorColor, textErrorColor)) && @@ -366,6 +391,7 @@ class _$_CardStyleConstructor extends _CardStyleConstructor { const DeepCollectionEquality().hash(cursorColor) ^ const DeepCollectionEquality().hash(textColor) ^ const DeepCollectionEquality().hash(fontSize) ^ + const DeepCollectionEquality().hash(fontFamily) ^ const DeepCollectionEquality().hash(textErrorColor) ^ const DeepCollectionEquality().hash(placeholderColor); @@ -394,6 +420,7 @@ abstract class _CardStyleConstructor extends CardStyle { @JsonKey(toJson: ColorKey.toJson, fromJson: ColorKey.fromJson) Color? textColor, double? fontSize, + String? fontFamily, @JsonKey(toJson: ColorKey.toJson, fromJson: ColorKey.fromJson) Color? textErrorColor, @JsonKey(toJson: ColorKey.toJson, fromJson: ColorKey.fromJson) @@ -429,6 +456,10 @@ abstract class _CardStyleConstructor extends CardStyle { double? get fontSize => throw _privateConstructorUsedError; @override + /// Font family + String? get fontFamily => throw _privateConstructorUsedError; + @override + /// Color of the input in case incorrect data is entered. @JsonKey(toJson: ColorKey.toJson, fromJson: ColorKey.fromJson) Color? get textErrorColor => throw _privateConstructorUsedError; @@ -585,9 +616,9 @@ class __$CardPlaceholderConstructorCopyWithImpl<$Res> } } -@JsonSerializable(explicitToJson: true) - /// @nodoc + +@JsonSerializable(explicitToJson: true) class _$_CardPlaceholderConstructor extends _CardPlaceholderConstructor { _$_CardPlaceholderConstructor( {this.number, this.expiration, this.cvc, this.postalCode}) @@ -699,8 +730,8 @@ class _$CardFieldInputDetailsTearOff { _CardFieldInputDetails call( {required bool complete, String? last4, - String? expiryMonth, - String? expiryYear, + int? expiryMonth, + int? expiryYear, String? postalCode, String? brand}) { return _CardFieldInputDetails( @@ -730,10 +761,10 @@ mixin _$CardFieldInputDetails { String? get last4 => throw _privateConstructorUsedError; /// Month of the entered expiry date of the card. - String? get expiryMonth => throw _privateConstructorUsedError; + int? get expiryMonth => throw _privateConstructorUsedError; /// Year of the entered expiry date of the card. - String? get expiryYear => throw _privateConstructorUsedError; + int? get expiryYear => throw _privateConstructorUsedError; /// Entered postcal code. String? get postalCode => throw _privateConstructorUsedError; @@ -755,8 +786,8 @@ abstract class $CardFieldInputDetailsCopyWith<$Res> { $Res call( {bool complete, String? last4, - String? expiryMonth, - String? expiryYear, + int? expiryMonth, + int? expiryYear, String? postalCode, String? brand}); } @@ -791,11 +822,11 @@ class _$CardFieldInputDetailsCopyWithImpl<$Res> expiryMonth: expiryMonth == freezed ? _value.expiryMonth : expiryMonth // ignore: cast_nullable_to_non_nullable - as String?, + as int?, expiryYear: expiryYear == freezed ? _value.expiryYear : expiryYear // ignore: cast_nullable_to_non_nullable - as String?, + as int?, postalCode: postalCode == freezed ? _value.postalCode : postalCode // ignore: cast_nullable_to_non_nullable @@ -818,8 +849,8 @@ abstract class _$CardFieldInputDetailsCopyWith<$Res> $Res call( {bool complete, String? last4, - String? expiryMonth, - String? expiryYear, + int? expiryMonth, + int? expiryYear, String? postalCode, String? brand}); } @@ -856,11 +887,11 @@ class __$CardFieldInputDetailsCopyWithImpl<$Res> expiryMonth: expiryMonth == freezed ? _value.expiryMonth : expiryMonth // ignore: cast_nullable_to_non_nullable - as String?, + as int?, expiryYear: expiryYear == freezed ? _value.expiryYear : expiryYear // ignore: cast_nullable_to_non_nullable - as String?, + as int?, postalCode: postalCode == freezed ? _value.postalCode : postalCode // ignore: cast_nullable_to_non_nullable @@ -873,9 +904,9 @@ class __$CardFieldInputDetailsCopyWithImpl<$Res> } } -@JsonSerializable(explicitToJson: true) - /// @nodoc + +@JsonSerializable(explicitToJson: true) class _$_CardFieldInputDetails implements _CardFieldInputDetails { const _$_CardFieldInputDetails( {required this.complete, @@ -899,11 +930,11 @@ class _$_CardFieldInputDetails implements _CardFieldInputDetails { @override /// Month of the entered expiry date of the card. - final String? expiryMonth; + final int? expiryMonth; @override /// Year of the entered expiry date of the card. - final String? expiryYear; + final int? expiryYear; @override /// Entered postcal code. @@ -966,8 +997,8 @@ abstract class _CardFieldInputDetails implements CardFieldInputDetails { const factory _CardFieldInputDetails( {required bool complete, String? last4, - String? expiryMonth, - String? expiryYear, + int? expiryMonth, + int? expiryYear, String? postalCode, String? brand}) = _$_CardFieldInputDetails; @@ -985,11 +1016,11 @@ abstract class _CardFieldInputDetails implements CardFieldInputDetails { @override /// Month of the entered expiry date of the card. - String? get expiryMonth => throw _privateConstructorUsedError; + int? get expiryMonth => throw _privateConstructorUsedError; @override /// Year of the entered expiry date of the card. - String? get expiryYear => throw _privateConstructorUsedError; + int? get expiryYear => throw _privateConstructorUsedError; @override /// Entered postcal code. @@ -1100,9 +1131,9 @@ class __$CardFieldFocusNameCopyWithImpl<$Res> } } -@JsonSerializable(explicitToJson: true) - /// @nodoc + +@JsonSerializable(explicitToJson: true) class _$_CardFieldFocusName implements _CardFieldFocusName { _$_CardFieldFocusName({this.focusedField}); diff --git a/packages/stripe_platform_interface/lib/src/models/card_field_input.g.dart b/packages/stripe_platform_interface/lib/src/models/card_field_input.g.dart index 489a16f..bb0506e 100644 --- a/packages/stripe_platform_interface/lib/src/models/card_field_input.g.dart +++ b/packages/stripe_platform_interface/lib/src/models/card_field_input.g.dart @@ -16,6 +16,7 @@ _$_CardStyleConstructor _$_$_CardStyleConstructorFromJson( cursorColor: ColorKey.fromJson(json['cursorColor']), textColor: ColorKey.fromJson(json['textColor']), fontSize: (json['fontSize'] as num?)?.toDouble(), + fontFamily: json['fontFamily'] as String?, textErrorColor: ColorKey.fromJson(json['textErrorColor']), placeholderColor: ColorKey.fromJson(json['placeholderColor']), ); @@ -31,6 +32,7 @@ Map _$_$_CardStyleConstructorToJson( 'cursorColor': ColorKey.toJson(instance.cursorColor), 'textColor': ColorKey.toJson(instance.textColor), 'fontSize': instance.fontSize, + 'fontFamily': instance.fontFamily, 'textErrorColor': ColorKey.toJson(instance.textErrorColor), 'placeholderColor': ColorKey.toJson(instance.placeholderColor), }; @@ -59,8 +61,8 @@ _$_CardFieldInputDetails _$_$_CardFieldInputDetailsFromJson( return _$_CardFieldInputDetails( complete: json['complete'] as bool, last4: json['last4'] as String?, - expiryMonth: json['expiryMonth'] as String?, - expiryYear: json['expiryYear'] as String?, + expiryMonth: json['expiryMonth'] as int?, + expiryYear: json['expiryYear'] as int?, postalCode: json['postalCode'] as String?, brand: json['brand'] as String?, ); diff --git a/packages/stripe_platform_interface/lib/src/models/create_token_data.dart b/packages/stripe_platform_interface/lib/src/models/create_token_data.dart new file mode 100644 index 0000000..d3eeb77 --- /dev/null +++ b/packages/stripe_platform_interface/lib/src/models/create_token_data.dart @@ -0,0 +1,158 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; + +import 'address.dart'; + +part 'create_token_data.freezed.dart'; +part 'create_token_data.g.dart'; +//ignore_for_file: constant_identifier_names + +@freezed + +/// parameters that are used to create a token. +/// +/// At this moment only card tokens are supported. +class CreateTokenParams with _$CreateTokenParams { + const factory CreateTokenParams({ + /// Type of token. + @Default(TokenType.Card) TokenType type, + + /// Additional address details + Address? address, + }) = _CreateTokenParams; + + factory CreateTokenParams.fromJson(Map json) => + _$CreateTokenParamsFromJson(json); +} + +@freezed + +/// Data that provides information about the token +class TokenData with _$TokenData { + const factory TokenData({ + /// Unique identifier of the token + required String id, + + /// Timestamp when token was created + @JsonKey(name: 'created') required String createdDateTime, + + /// Type of the token + required TokenType type, + + /// Whether or not the object exists in livemode + required bool livemode, + + /// Bank account data + BankAccount? bankAccount, + + /// Card data + CardData? card, + }) = _TokenData; + + factory TokenData.fromJson(Map json) => + _$TokenDataFromJson(json); +} + +@freezed + +/// Card data associated with the token +class CardData with _$CardData { + @JsonSerializable(explicitToJson: true) + const factory CardData({ + /// The brand associated to the card e.g. (visa, amex). + required String brand, + + /// Two letter iso code. + String? country, + + /// The three letter ISO 4217 code for the currency. + String? currency, + + /// four digit number representing the year of expiry of the card. + int? expYear, + + /// two digit number representing the month of expire of the card. + int? expMonth, + + /// Fullname of the cardholder + String? name, + + /// card funding type e.g. (credit, debit). + String? funding, + + /// last four digits of the card. + String? last4, + + /// Address of the cardholder + Address? address, + }) = _CardData; + + factory CardData.fromJson(Map json) => + _$CardDataFromJson(json); +} + +@freezed + +/// Bank account data related to the token +class BankAccount with _$BankAccount { + const factory BankAccount({ + /// Entity that is holder of the account. + required BankAccountHolderType accountHolderType, + + /// Status of the bank account. + required BankAccountStatus status, + + /// Name of the bank where the account is registered. + String? bankName, + + /// Full name of the account holder + String? accountHolderName, + + /// 2 letter code of the country where the account is located + String? country, + + /// The three letter ISO 4217 code for the currency. + String? currency, + + /// The routing number of the bank account (e.g. needer for US accounts). + String? routingNumber, + }) = _BankAccount; + + factory BankAccount.fromJson(Map json) => + _$BankAccountFromJson(json); +} + +/// Entity that is holder of the account +enum BankAccountHolderType { + /// Company. + Company, + + /// Individual. + Individual, + + /// Entity cannot be determined. + Unknown, +} + +/// Verfication status of the bankaccount. +enum BankAccountStatus { + /// Validation has some errors + Errored, + + /// Seen as a new bankaccount + New, + + /// Bankaccount is validated + Validated, + + /// Failed to verify bankaccount + VerificationFailed, + + /// Bankaccount is verified + Verified, + + /// Status cannot be determined + Unknown +} + +/// Type of token +enum TokenType { Card } diff --git a/packages/stripe_platform_interface/lib/src/models/create_token_data.freezed.dart b/packages/stripe_platform_interface/lib/src/models/create_token_data.freezed.dart new file mode 100644 index 0000000..7889363 --- /dev/null +++ b/packages/stripe_platform_interface/lib/src/models/create_token_data.freezed.dart @@ -0,0 +1,1313 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides + +part of 'create_token_data.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); + +CreateTokenParams _$CreateTokenParamsFromJson(Map json) { + return _CreateTokenParams.fromJson(json); +} + +/// @nodoc +class _$CreateTokenParamsTearOff { + const _$CreateTokenParamsTearOff(); + + _CreateTokenParams call({TokenType type = TokenType.Card, Address? address}) { + return _CreateTokenParams( + type: type, + address: address, + ); + } + + CreateTokenParams fromJson(Map json) { + return CreateTokenParams.fromJson(json); + } +} + +/// @nodoc +const $CreateTokenParams = _$CreateTokenParamsTearOff(); + +/// @nodoc +mixin _$CreateTokenParams { + /// Type of token. + TokenType get type => throw _privateConstructorUsedError; + + /// Additional address details + Address? get address => throw _privateConstructorUsedError; + + Map toJson() => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + $CreateTokenParamsCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $CreateTokenParamsCopyWith<$Res> { + factory $CreateTokenParamsCopyWith( + CreateTokenParams value, $Res Function(CreateTokenParams) then) = + _$CreateTokenParamsCopyWithImpl<$Res>; + $Res call({TokenType type, Address? address}); + + $AddressCopyWith<$Res>? get address; +} + +/// @nodoc +class _$CreateTokenParamsCopyWithImpl<$Res> + implements $CreateTokenParamsCopyWith<$Res> { + _$CreateTokenParamsCopyWithImpl(this._value, this._then); + + final CreateTokenParams _value; + // ignore: unused_field + final $Res Function(CreateTokenParams) _then; + + @override + $Res call({ + Object? type = freezed, + Object? address = freezed, + }) { + return _then(_value.copyWith( + type: type == freezed + ? _value.type + : type // ignore: cast_nullable_to_non_nullable + as TokenType, + address: address == freezed + ? _value.address + : address // ignore: cast_nullable_to_non_nullable + as Address?, + )); + } + + @override + $AddressCopyWith<$Res>? get address { + if (_value.address == null) { + return null; + } + + return $AddressCopyWith<$Res>(_value.address!, (value) { + return _then(_value.copyWith(address: value)); + }); + } +} + +/// @nodoc +abstract class _$CreateTokenParamsCopyWith<$Res> + implements $CreateTokenParamsCopyWith<$Res> { + factory _$CreateTokenParamsCopyWith( + _CreateTokenParams value, $Res Function(_CreateTokenParams) then) = + __$CreateTokenParamsCopyWithImpl<$Res>; + @override + $Res call({TokenType type, Address? address}); + + @override + $AddressCopyWith<$Res>? get address; +} + +/// @nodoc +class __$CreateTokenParamsCopyWithImpl<$Res> + extends _$CreateTokenParamsCopyWithImpl<$Res> + implements _$CreateTokenParamsCopyWith<$Res> { + __$CreateTokenParamsCopyWithImpl( + _CreateTokenParams _value, $Res Function(_CreateTokenParams) _then) + : super(_value, (v) => _then(v as _CreateTokenParams)); + + @override + _CreateTokenParams get _value => super._value as _CreateTokenParams; + + @override + $Res call({ + Object? type = freezed, + Object? address = freezed, + }) { + return _then(_CreateTokenParams( + type: type == freezed + ? _value.type + : type // ignore: cast_nullable_to_non_nullable + as TokenType, + address: address == freezed + ? _value.address + : address // ignore: cast_nullable_to_non_nullable + as Address?, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$_CreateTokenParams implements _CreateTokenParams { + const _$_CreateTokenParams({this.type = TokenType.Card, this.address}); + + factory _$_CreateTokenParams.fromJson(Map json) => + _$_$_CreateTokenParamsFromJson(json); + + @JsonKey(defaultValue: TokenType.Card) + @override + + /// Type of token. + final TokenType type; + @override + + /// Additional address details + final Address? address; + + @override + String toString() { + return 'CreateTokenParams(type: $type, address: $address)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other is _CreateTokenParams && + (identical(other.type, type) || + const DeepCollectionEquality().equals(other.type, type)) && + (identical(other.address, address) || + const DeepCollectionEquality().equals(other.address, address))); + } + + @override + int get hashCode => + runtimeType.hashCode ^ + const DeepCollectionEquality().hash(type) ^ + const DeepCollectionEquality().hash(address); + + @JsonKey(ignore: true) + @override + _$CreateTokenParamsCopyWith<_CreateTokenParams> get copyWith => + __$CreateTokenParamsCopyWithImpl<_CreateTokenParams>(this, _$identity); + + @override + Map toJson() { + return _$_$_CreateTokenParamsToJson(this); + } +} + +abstract class _CreateTokenParams implements CreateTokenParams { + const factory _CreateTokenParams({TokenType type, Address? address}) = + _$_CreateTokenParams; + + factory _CreateTokenParams.fromJson(Map json) = + _$_CreateTokenParams.fromJson; + + @override + + /// Type of token. + TokenType get type => throw _privateConstructorUsedError; + @override + + /// Additional address details + Address? get address => throw _privateConstructorUsedError; + @override + @JsonKey(ignore: true) + _$CreateTokenParamsCopyWith<_CreateTokenParams> get copyWith => + throw _privateConstructorUsedError; +} + +TokenData _$TokenDataFromJson(Map json) { + return _TokenData.fromJson(json); +} + +/// @nodoc +class _$TokenDataTearOff { + const _$TokenDataTearOff(); + + _TokenData call( + {required String id, + @JsonKey(name: 'created') required String createdDateTime, + required TokenType type, + required bool livemode, + BankAccount? bankAccount, + CardData? card}) { + return _TokenData( + id: id, + createdDateTime: createdDateTime, + type: type, + livemode: livemode, + bankAccount: bankAccount, + card: card, + ); + } + + TokenData fromJson(Map json) { + return TokenData.fromJson(json); + } +} + +/// @nodoc +const $TokenData = _$TokenDataTearOff(); + +/// @nodoc +mixin _$TokenData { + /// Unique identifier of the token + String get id => throw _privateConstructorUsedError; + + /// Timestamp when token was created + @JsonKey(name: 'created') + String get createdDateTime => throw _privateConstructorUsedError; + + /// Type of the token + TokenType get type => throw _privateConstructorUsedError; + + /// Whether or not the object exists in livemode + bool get livemode => throw _privateConstructorUsedError; + + /// Bank account data + BankAccount? get bankAccount => throw _privateConstructorUsedError; + + /// Card data + CardData? get card => throw _privateConstructorUsedError; + + Map toJson() => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + $TokenDataCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $TokenDataCopyWith<$Res> { + factory $TokenDataCopyWith(TokenData value, $Res Function(TokenData) then) = + _$TokenDataCopyWithImpl<$Res>; + $Res call( + {String id, + @JsonKey(name: 'created') String createdDateTime, + TokenType type, + bool livemode, + BankAccount? bankAccount, + CardData? card}); + + $BankAccountCopyWith<$Res>? get bankAccount; + $CardDataCopyWith<$Res>? get card; +} + +/// @nodoc +class _$TokenDataCopyWithImpl<$Res> implements $TokenDataCopyWith<$Res> { + _$TokenDataCopyWithImpl(this._value, this._then); + + final TokenData _value; + // ignore: unused_field + final $Res Function(TokenData) _then; + + @override + $Res call({ + Object? id = freezed, + Object? createdDateTime = freezed, + Object? type = freezed, + Object? livemode = freezed, + Object? bankAccount = freezed, + Object? card = freezed, + }) { + return _then(_value.copyWith( + id: id == freezed + ? _value.id + : id // ignore: cast_nullable_to_non_nullable + as String, + createdDateTime: createdDateTime == freezed + ? _value.createdDateTime + : createdDateTime // ignore: cast_nullable_to_non_nullable + as String, + type: type == freezed + ? _value.type + : type // ignore: cast_nullable_to_non_nullable + as TokenType, + livemode: livemode == freezed + ? _value.livemode + : livemode // ignore: cast_nullable_to_non_nullable + as bool, + bankAccount: bankAccount == freezed + ? _value.bankAccount + : bankAccount // ignore: cast_nullable_to_non_nullable + as BankAccount?, + card: card == freezed + ? _value.card + : card // ignore: cast_nullable_to_non_nullable + as CardData?, + )); + } + + @override + $BankAccountCopyWith<$Res>? get bankAccount { + if (_value.bankAccount == null) { + return null; + } + + return $BankAccountCopyWith<$Res>(_value.bankAccount!, (value) { + return _then(_value.copyWith(bankAccount: value)); + }); + } + + @override + $CardDataCopyWith<$Res>? get card { + if (_value.card == null) { + return null; + } + + return $CardDataCopyWith<$Res>(_value.card!, (value) { + return _then(_value.copyWith(card: value)); + }); + } +} + +/// @nodoc +abstract class _$TokenDataCopyWith<$Res> implements $TokenDataCopyWith<$Res> { + factory _$TokenDataCopyWith( + _TokenData value, $Res Function(_TokenData) then) = + __$TokenDataCopyWithImpl<$Res>; + @override + $Res call( + {String id, + @JsonKey(name: 'created') String createdDateTime, + TokenType type, + bool livemode, + BankAccount? bankAccount, + CardData? card}); + + @override + $BankAccountCopyWith<$Res>? get bankAccount; + @override + $CardDataCopyWith<$Res>? get card; +} + +/// @nodoc +class __$TokenDataCopyWithImpl<$Res> extends _$TokenDataCopyWithImpl<$Res> + implements _$TokenDataCopyWith<$Res> { + __$TokenDataCopyWithImpl(_TokenData _value, $Res Function(_TokenData) _then) + : super(_value, (v) => _then(v as _TokenData)); + + @override + _TokenData get _value => super._value as _TokenData; + + @override + $Res call({ + Object? id = freezed, + Object? createdDateTime = freezed, + Object? type = freezed, + Object? livemode = freezed, + Object? bankAccount = freezed, + Object? card = freezed, + }) { + return _then(_TokenData( + id: id == freezed + ? _value.id + : id // ignore: cast_nullable_to_non_nullable + as String, + createdDateTime: createdDateTime == freezed + ? _value.createdDateTime + : createdDateTime // ignore: cast_nullable_to_non_nullable + as String, + type: type == freezed + ? _value.type + : type // ignore: cast_nullable_to_non_nullable + as TokenType, + livemode: livemode == freezed + ? _value.livemode + : livemode // ignore: cast_nullable_to_non_nullable + as bool, + bankAccount: bankAccount == freezed + ? _value.bankAccount + : bankAccount // ignore: cast_nullable_to_non_nullable + as BankAccount?, + card: card == freezed + ? _value.card + : card // ignore: cast_nullable_to_non_nullable + as CardData?, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$_TokenData implements _TokenData { + const _$_TokenData( + {required this.id, + @JsonKey(name: 'created') required this.createdDateTime, + required this.type, + required this.livemode, + this.bankAccount, + this.card}); + + factory _$_TokenData.fromJson(Map json) => + _$_$_TokenDataFromJson(json); + + @override + + /// Unique identifier of the token + final String id; + @override + + /// Timestamp when token was created + @JsonKey(name: 'created') + final String createdDateTime; + @override + + /// Type of the token + final TokenType type; + @override + + /// Whether or not the object exists in livemode + final bool livemode; + @override + + /// Bank account data + final BankAccount? bankAccount; + @override + + /// Card data + final CardData? card; + + @override + String toString() { + return 'TokenData(id: $id, createdDateTime: $createdDateTime, type: $type, livemode: $livemode, bankAccount: $bankAccount, card: $card)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other is _TokenData && + (identical(other.id, id) || + const DeepCollectionEquality().equals(other.id, id)) && + (identical(other.createdDateTime, createdDateTime) || + const DeepCollectionEquality() + .equals(other.createdDateTime, createdDateTime)) && + (identical(other.type, type) || + const DeepCollectionEquality().equals(other.type, type)) && + (identical(other.livemode, livemode) || + const DeepCollectionEquality() + .equals(other.livemode, livemode)) && + (identical(other.bankAccount, bankAccount) || + const DeepCollectionEquality() + .equals(other.bankAccount, bankAccount)) && + (identical(other.card, card) || + const DeepCollectionEquality().equals(other.card, card))); + } + + @override + int get hashCode => + runtimeType.hashCode ^ + const DeepCollectionEquality().hash(id) ^ + const DeepCollectionEquality().hash(createdDateTime) ^ + const DeepCollectionEquality().hash(type) ^ + const DeepCollectionEquality().hash(livemode) ^ + const DeepCollectionEquality().hash(bankAccount) ^ + const DeepCollectionEquality().hash(card); + + @JsonKey(ignore: true) + @override + _$TokenDataCopyWith<_TokenData> get copyWith => + __$TokenDataCopyWithImpl<_TokenData>(this, _$identity); + + @override + Map toJson() { + return _$_$_TokenDataToJson(this); + } +} + +abstract class _TokenData implements TokenData { + const factory _TokenData( + {required String id, + @JsonKey(name: 'created') required String createdDateTime, + required TokenType type, + required bool livemode, + BankAccount? bankAccount, + CardData? card}) = _$_TokenData; + + factory _TokenData.fromJson(Map json) = + _$_TokenData.fromJson; + + @override + + /// Unique identifier of the token + String get id => throw _privateConstructorUsedError; + @override + + /// Timestamp when token was created + @JsonKey(name: 'created') + String get createdDateTime => throw _privateConstructorUsedError; + @override + + /// Type of the token + TokenType get type => throw _privateConstructorUsedError; + @override + + /// Whether or not the object exists in livemode + bool get livemode => throw _privateConstructorUsedError; + @override + + /// Bank account data + BankAccount? get bankAccount => throw _privateConstructorUsedError; + @override + + /// Card data + CardData? get card => throw _privateConstructorUsedError; + @override + @JsonKey(ignore: true) + _$TokenDataCopyWith<_TokenData> get copyWith => + throw _privateConstructorUsedError; +} + +CardData _$CardDataFromJson(Map json) { + return _CardData.fromJson(json); +} + +/// @nodoc +class _$CardDataTearOff { + const _$CardDataTearOff(); + + _CardData call( + {required String brand, + String? country, + String? currency, + int? expYear, + int? expMonth, + String? name, + String? funding, + String? last4, + Address? address}) { + return _CardData( + brand: brand, + country: country, + currency: currency, + expYear: expYear, + expMonth: expMonth, + name: name, + funding: funding, + last4: last4, + address: address, + ); + } + + CardData fromJson(Map json) { + return CardData.fromJson(json); + } +} + +/// @nodoc +const $CardData = _$CardDataTearOff(); + +/// @nodoc +mixin _$CardData { + /// The brand associated to the card e.g. (visa, amex). + String get brand => throw _privateConstructorUsedError; + + /// Two letter iso code. + String? get country => throw _privateConstructorUsedError; + + /// The three letter ISO 4217 code for the currency. + String? get currency => throw _privateConstructorUsedError; + + /// four digit number representing the year of expiry of the card. + int? get expYear => throw _privateConstructorUsedError; + + /// two digit number representing the month of expire of the card. + int? get expMonth => throw _privateConstructorUsedError; + + /// Fullname of the cardholder + String? get name => throw _privateConstructorUsedError; + + /// card funding type e.g. (credit, debit). + String? get funding => throw _privateConstructorUsedError; + + /// last four digits of the card. + String? get last4 => throw _privateConstructorUsedError; + + /// Address of the cardholder + Address? get address => throw _privateConstructorUsedError; + + Map toJson() => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + $CardDataCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $CardDataCopyWith<$Res> { + factory $CardDataCopyWith(CardData value, $Res Function(CardData) then) = + _$CardDataCopyWithImpl<$Res>; + $Res call( + {String brand, + String? country, + String? currency, + int? expYear, + int? expMonth, + String? name, + String? funding, + String? last4, + Address? address}); + + $AddressCopyWith<$Res>? get address; +} + +/// @nodoc +class _$CardDataCopyWithImpl<$Res> implements $CardDataCopyWith<$Res> { + _$CardDataCopyWithImpl(this._value, this._then); + + final CardData _value; + // ignore: unused_field + final $Res Function(CardData) _then; + + @override + $Res call({ + Object? brand = freezed, + Object? country = freezed, + Object? currency = freezed, + Object? expYear = freezed, + Object? expMonth = freezed, + Object? name = freezed, + Object? funding = freezed, + Object? last4 = freezed, + Object? address = freezed, + }) { + return _then(_value.copyWith( + brand: brand == freezed + ? _value.brand + : brand // ignore: cast_nullable_to_non_nullable + as String, + country: country == freezed + ? _value.country + : country // ignore: cast_nullable_to_non_nullable + as String?, + currency: currency == freezed + ? _value.currency + : currency // ignore: cast_nullable_to_non_nullable + as String?, + expYear: expYear == freezed + ? _value.expYear + : expYear // ignore: cast_nullable_to_non_nullable + as int?, + expMonth: expMonth == freezed + ? _value.expMonth + : expMonth // ignore: cast_nullable_to_non_nullable + as int?, + name: name == freezed + ? _value.name + : name // ignore: cast_nullable_to_non_nullable + as String?, + funding: funding == freezed + ? _value.funding + : funding // ignore: cast_nullable_to_non_nullable + as String?, + last4: last4 == freezed + ? _value.last4 + : last4 // ignore: cast_nullable_to_non_nullable + as String?, + address: address == freezed + ? _value.address + : address // ignore: cast_nullable_to_non_nullable + as Address?, + )); + } + + @override + $AddressCopyWith<$Res>? get address { + if (_value.address == null) { + return null; + } + + return $AddressCopyWith<$Res>(_value.address!, (value) { + return _then(_value.copyWith(address: value)); + }); + } +} + +/// @nodoc +abstract class _$CardDataCopyWith<$Res> implements $CardDataCopyWith<$Res> { + factory _$CardDataCopyWith(_CardData value, $Res Function(_CardData) then) = + __$CardDataCopyWithImpl<$Res>; + @override + $Res call( + {String brand, + String? country, + String? currency, + int? expYear, + int? expMonth, + String? name, + String? funding, + String? last4, + Address? address}); + + @override + $AddressCopyWith<$Res>? get address; +} + +/// @nodoc +class __$CardDataCopyWithImpl<$Res> extends _$CardDataCopyWithImpl<$Res> + implements _$CardDataCopyWith<$Res> { + __$CardDataCopyWithImpl(_CardData _value, $Res Function(_CardData) _then) + : super(_value, (v) => _then(v as _CardData)); + + @override + _CardData get _value => super._value as _CardData; + + @override + $Res call({ + Object? brand = freezed, + Object? country = freezed, + Object? currency = freezed, + Object? expYear = freezed, + Object? expMonth = freezed, + Object? name = freezed, + Object? funding = freezed, + Object? last4 = freezed, + Object? address = freezed, + }) { + return _then(_CardData( + brand: brand == freezed + ? _value.brand + : brand // ignore: cast_nullable_to_non_nullable + as String, + country: country == freezed + ? _value.country + : country // ignore: cast_nullable_to_non_nullable + as String?, + currency: currency == freezed + ? _value.currency + : currency // ignore: cast_nullable_to_non_nullable + as String?, + expYear: expYear == freezed + ? _value.expYear + : expYear // ignore: cast_nullable_to_non_nullable + as int?, + expMonth: expMonth == freezed + ? _value.expMonth + : expMonth // ignore: cast_nullable_to_non_nullable + as int?, + name: name == freezed + ? _value.name + : name // ignore: cast_nullable_to_non_nullable + as String?, + funding: funding == freezed + ? _value.funding + : funding // ignore: cast_nullable_to_non_nullable + as String?, + last4: last4 == freezed + ? _value.last4 + : last4 // ignore: cast_nullable_to_non_nullable + as String?, + address: address == freezed + ? _value.address + : address // ignore: cast_nullable_to_non_nullable + as Address?, + )); + } +} + +/// @nodoc + +@JsonSerializable(explicitToJson: true) +class _$_CardData implements _CardData { + const _$_CardData( + {required this.brand, + this.country, + this.currency, + this.expYear, + this.expMonth, + this.name, + this.funding, + this.last4, + this.address}); + + factory _$_CardData.fromJson(Map json) => + _$_$_CardDataFromJson(json); + + @override + + /// The brand associated to the card e.g. (visa, amex). + final String brand; + @override + + /// Two letter iso code. + final String? country; + @override + + /// The three letter ISO 4217 code for the currency. + final String? currency; + @override + + /// four digit number representing the year of expiry of the card. + final int? expYear; + @override + + /// two digit number representing the month of expire of the card. + final int? expMonth; + @override + + /// Fullname of the cardholder + final String? name; + @override + + /// card funding type e.g. (credit, debit). + final String? funding; + @override + + /// last four digits of the card. + final String? last4; + @override + + /// Address of the cardholder + final Address? address; + + @override + String toString() { + return 'CardData(brand: $brand, country: $country, currency: $currency, expYear: $expYear, expMonth: $expMonth, name: $name, funding: $funding, last4: $last4, address: $address)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other is _CardData && + (identical(other.brand, brand) || + const DeepCollectionEquality().equals(other.brand, brand)) && + (identical(other.country, country) || + const DeepCollectionEquality() + .equals(other.country, country)) && + (identical(other.currency, currency) || + const DeepCollectionEquality() + .equals(other.currency, currency)) && + (identical(other.expYear, expYear) || + const DeepCollectionEquality() + .equals(other.expYear, expYear)) && + (identical(other.expMonth, expMonth) || + const DeepCollectionEquality() + .equals(other.expMonth, expMonth)) && + (identical(other.name, name) || + const DeepCollectionEquality().equals(other.name, name)) && + (identical(other.funding, funding) || + const DeepCollectionEquality() + .equals(other.funding, funding)) && + (identical(other.last4, last4) || + const DeepCollectionEquality().equals(other.last4, last4)) && + (identical(other.address, address) || + const DeepCollectionEquality().equals(other.address, address))); + } + + @override + int get hashCode => + runtimeType.hashCode ^ + const DeepCollectionEquality().hash(brand) ^ + const DeepCollectionEquality().hash(country) ^ + const DeepCollectionEquality().hash(currency) ^ + const DeepCollectionEquality().hash(expYear) ^ + const DeepCollectionEquality().hash(expMonth) ^ + const DeepCollectionEquality().hash(name) ^ + const DeepCollectionEquality().hash(funding) ^ + const DeepCollectionEquality().hash(last4) ^ + const DeepCollectionEquality().hash(address); + + @JsonKey(ignore: true) + @override + _$CardDataCopyWith<_CardData> get copyWith => + __$CardDataCopyWithImpl<_CardData>(this, _$identity); + + @override + Map toJson() { + return _$_$_CardDataToJson(this); + } +} + +abstract class _CardData implements CardData { + const factory _CardData( + {required String brand, + String? country, + String? currency, + int? expYear, + int? expMonth, + String? name, + String? funding, + String? last4, + Address? address}) = _$_CardData; + + factory _CardData.fromJson(Map json) = _$_CardData.fromJson; + + @override + + /// The brand associated to the card e.g. (visa, amex). + String get brand => throw _privateConstructorUsedError; + @override + + /// Two letter iso code. + String? get country => throw _privateConstructorUsedError; + @override + + /// The three letter ISO 4217 code for the currency. + String? get currency => throw _privateConstructorUsedError; + @override + + /// four digit number representing the year of expiry of the card. + int? get expYear => throw _privateConstructorUsedError; + @override + + /// two digit number representing the month of expire of the card. + int? get expMonth => throw _privateConstructorUsedError; + @override + + /// Fullname of the cardholder + String? get name => throw _privateConstructorUsedError; + @override + + /// card funding type e.g. (credit, debit). + String? get funding => throw _privateConstructorUsedError; + @override + + /// last four digits of the card. + String? get last4 => throw _privateConstructorUsedError; + @override + + /// Address of the cardholder + Address? get address => throw _privateConstructorUsedError; + @override + @JsonKey(ignore: true) + _$CardDataCopyWith<_CardData> get copyWith => + throw _privateConstructorUsedError; +} + +BankAccount _$BankAccountFromJson(Map json) { + return _BankAccount.fromJson(json); +} + +/// @nodoc +class _$BankAccountTearOff { + const _$BankAccountTearOff(); + + _BankAccount call( + {required BankAccountHolderType accountHolderType, + required BankAccountStatus status, + String? bankName, + String? accountHolderName, + String? country, + String? currency, + String? routingNumber}) { + return _BankAccount( + accountHolderType: accountHolderType, + status: status, + bankName: bankName, + accountHolderName: accountHolderName, + country: country, + currency: currency, + routingNumber: routingNumber, + ); + } + + BankAccount fromJson(Map json) { + return BankAccount.fromJson(json); + } +} + +/// @nodoc +const $BankAccount = _$BankAccountTearOff(); + +/// @nodoc +mixin _$BankAccount { + /// Entity that is holder of the account. + BankAccountHolderType get accountHolderType => + throw _privateConstructorUsedError; + + /// Status of the bank account. + BankAccountStatus get status => throw _privateConstructorUsedError; + + /// Name of the bank where the account is registered. + String? get bankName => throw _privateConstructorUsedError; + + /// Full name of the account holder + String? get accountHolderName => throw _privateConstructorUsedError; + + /// 2 letter code of the country where the account is located + String? get country => throw _privateConstructorUsedError; + + /// The three letter ISO 4217 code for the currency. + String? get currency => throw _privateConstructorUsedError; + + /// The routing number of the bank account (e.g. needer for US accounts). + String? get routingNumber => throw _privateConstructorUsedError; + + Map toJson() => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + $BankAccountCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $BankAccountCopyWith<$Res> { + factory $BankAccountCopyWith( + BankAccount value, $Res Function(BankAccount) then) = + _$BankAccountCopyWithImpl<$Res>; + $Res call( + {BankAccountHolderType accountHolderType, + BankAccountStatus status, + String? bankName, + String? accountHolderName, + String? country, + String? currency, + String? routingNumber}); +} + +/// @nodoc +class _$BankAccountCopyWithImpl<$Res> implements $BankAccountCopyWith<$Res> { + _$BankAccountCopyWithImpl(this._value, this._then); + + final BankAccount _value; + // ignore: unused_field + final $Res Function(BankAccount) _then; + + @override + $Res call({ + Object? accountHolderType = freezed, + Object? status = freezed, + Object? bankName = freezed, + Object? accountHolderName = freezed, + Object? country = freezed, + Object? currency = freezed, + Object? routingNumber = freezed, + }) { + return _then(_value.copyWith( + accountHolderType: accountHolderType == freezed + ? _value.accountHolderType + : accountHolderType // ignore: cast_nullable_to_non_nullable + as BankAccountHolderType, + status: status == freezed + ? _value.status + : status // ignore: cast_nullable_to_non_nullable + as BankAccountStatus, + bankName: bankName == freezed + ? _value.bankName + : bankName // ignore: cast_nullable_to_non_nullable + as String?, + accountHolderName: accountHolderName == freezed + ? _value.accountHolderName + : accountHolderName // ignore: cast_nullable_to_non_nullable + as String?, + country: country == freezed + ? _value.country + : country // ignore: cast_nullable_to_non_nullable + as String?, + currency: currency == freezed + ? _value.currency + : currency // ignore: cast_nullable_to_non_nullable + as String?, + routingNumber: routingNumber == freezed + ? _value.routingNumber + : routingNumber // ignore: cast_nullable_to_non_nullable + as String?, + )); + } +} + +/// @nodoc +abstract class _$BankAccountCopyWith<$Res> + implements $BankAccountCopyWith<$Res> { + factory _$BankAccountCopyWith( + _BankAccount value, $Res Function(_BankAccount) then) = + __$BankAccountCopyWithImpl<$Res>; + @override + $Res call( + {BankAccountHolderType accountHolderType, + BankAccountStatus status, + String? bankName, + String? accountHolderName, + String? country, + String? currency, + String? routingNumber}); +} + +/// @nodoc +class __$BankAccountCopyWithImpl<$Res> extends _$BankAccountCopyWithImpl<$Res> + implements _$BankAccountCopyWith<$Res> { + __$BankAccountCopyWithImpl( + _BankAccount _value, $Res Function(_BankAccount) _then) + : super(_value, (v) => _then(v as _BankAccount)); + + @override + _BankAccount get _value => super._value as _BankAccount; + + @override + $Res call({ + Object? accountHolderType = freezed, + Object? status = freezed, + Object? bankName = freezed, + Object? accountHolderName = freezed, + Object? country = freezed, + Object? currency = freezed, + Object? routingNumber = freezed, + }) { + return _then(_BankAccount( + accountHolderType: accountHolderType == freezed + ? _value.accountHolderType + : accountHolderType // ignore: cast_nullable_to_non_nullable + as BankAccountHolderType, + status: status == freezed + ? _value.status + : status // ignore: cast_nullable_to_non_nullable + as BankAccountStatus, + bankName: bankName == freezed + ? _value.bankName + : bankName // ignore: cast_nullable_to_non_nullable + as String?, + accountHolderName: accountHolderName == freezed + ? _value.accountHolderName + : accountHolderName // ignore: cast_nullable_to_non_nullable + as String?, + country: country == freezed + ? _value.country + : country // ignore: cast_nullable_to_non_nullable + as String?, + currency: currency == freezed + ? _value.currency + : currency // ignore: cast_nullable_to_non_nullable + as String?, + routingNumber: routingNumber == freezed + ? _value.routingNumber + : routingNumber // ignore: cast_nullable_to_non_nullable + as String?, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$_BankAccount implements _BankAccount { + const _$_BankAccount( + {required this.accountHolderType, + required this.status, + this.bankName, + this.accountHolderName, + this.country, + this.currency, + this.routingNumber}); + + factory _$_BankAccount.fromJson(Map json) => + _$_$_BankAccountFromJson(json); + + @override + + /// Entity that is holder of the account. + final BankAccountHolderType accountHolderType; + @override + + /// Status of the bank account. + final BankAccountStatus status; + @override + + /// Name of the bank where the account is registered. + final String? bankName; + @override + + /// Full name of the account holder + final String? accountHolderName; + @override + + /// 2 letter code of the country where the account is located + final String? country; + @override + + /// The three letter ISO 4217 code for the currency. + final String? currency; + @override + + /// The routing number of the bank account (e.g. needer for US accounts). + final String? routingNumber; + + @override + String toString() { + return 'BankAccount(accountHolderType: $accountHolderType, status: $status, bankName: $bankName, accountHolderName: $accountHolderName, country: $country, currency: $currency, routingNumber: $routingNumber)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other is _BankAccount && + (identical(other.accountHolderType, accountHolderType) || + const DeepCollectionEquality() + .equals(other.accountHolderType, accountHolderType)) && + (identical(other.status, status) || + const DeepCollectionEquality().equals(other.status, status)) && + (identical(other.bankName, bankName) || + const DeepCollectionEquality() + .equals(other.bankName, bankName)) && + (identical(other.accountHolderName, accountHolderName) || + const DeepCollectionEquality() + .equals(other.accountHolderName, accountHolderName)) && + (identical(other.country, country) || + const DeepCollectionEquality() + .equals(other.country, country)) && + (identical(other.currency, currency) || + const DeepCollectionEquality() + .equals(other.currency, currency)) && + (identical(other.routingNumber, routingNumber) || + const DeepCollectionEquality() + .equals(other.routingNumber, routingNumber))); + } + + @override + int get hashCode => + runtimeType.hashCode ^ + const DeepCollectionEquality().hash(accountHolderType) ^ + const DeepCollectionEquality().hash(status) ^ + const DeepCollectionEquality().hash(bankName) ^ + const DeepCollectionEquality().hash(accountHolderName) ^ + const DeepCollectionEquality().hash(country) ^ + const DeepCollectionEquality().hash(currency) ^ + const DeepCollectionEquality().hash(routingNumber); + + @JsonKey(ignore: true) + @override + _$BankAccountCopyWith<_BankAccount> get copyWith => + __$BankAccountCopyWithImpl<_BankAccount>(this, _$identity); + + @override + Map toJson() { + return _$_$_BankAccountToJson(this); + } +} + +abstract class _BankAccount implements BankAccount { + const factory _BankAccount( + {required BankAccountHolderType accountHolderType, + required BankAccountStatus status, + String? bankName, + String? accountHolderName, + String? country, + String? currency, + String? routingNumber}) = _$_BankAccount; + + factory _BankAccount.fromJson(Map json) = + _$_BankAccount.fromJson; + + @override + + /// Entity that is holder of the account. + BankAccountHolderType get accountHolderType => + throw _privateConstructorUsedError; + @override + + /// Status of the bank account. + BankAccountStatus get status => throw _privateConstructorUsedError; + @override + + /// Name of the bank where the account is registered. + String? get bankName => throw _privateConstructorUsedError; + @override + + /// Full name of the account holder + String? get accountHolderName => throw _privateConstructorUsedError; + @override + + /// 2 letter code of the country where the account is located + String? get country => throw _privateConstructorUsedError; + @override + + /// The three letter ISO 4217 code for the currency. + String? get currency => throw _privateConstructorUsedError; + @override + + /// The routing number of the bank account (e.g. needer for US accounts). + String? get routingNumber => throw _privateConstructorUsedError; + @override + @JsonKey(ignore: true) + _$BankAccountCopyWith<_BankAccount> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/packages/stripe_platform_interface/lib/src/models/create_token_data.g.dart b/packages/stripe_platform_interface/lib/src/models/create_token_data.g.dart new file mode 100644 index 0000000..e60dec4 --- /dev/null +++ b/packages/stripe_platform_interface/lib/src/models/create_token_data.g.dart @@ -0,0 +1,159 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'create_token_data.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_$_CreateTokenParams _$_$_CreateTokenParamsFromJson(Map json) { + return _$_CreateTokenParams( + type: _$enumDecodeNullable(_$TokenTypeEnumMap, json['type']) ?? + TokenType.Card, + address: json['address'] == null + ? null + : Address.fromJson(json['address'] as Map), + ); +} + +Map _$_$_CreateTokenParamsToJson( + _$_CreateTokenParams instance) => + { + 'type': _$TokenTypeEnumMap[instance.type], + 'address': instance.address, + }; + +K _$enumDecode( + Map enumValues, + Object? source, { + K? unknownValue, +}) { + if (source == null) { + throw ArgumentError( + 'A value must be provided. Supported values: ' + '${enumValues.values.join(', ')}', + ); + } + + return enumValues.entries.singleWhere( + (e) => e.value == source, + orElse: () { + if (unknownValue == null) { + throw ArgumentError( + '`$source` is not one of the supported values: ' + '${enumValues.values.join(', ')}', + ); + } + return MapEntry(unknownValue, enumValues.values.first); + }, + ).key; +} + +K? _$enumDecodeNullable( + Map enumValues, + dynamic source, { + K? unknownValue, +}) { + if (source == null) { + return null; + } + return _$enumDecode(enumValues, source, unknownValue: unknownValue); +} + +const _$TokenTypeEnumMap = { + TokenType.Card: 'Card', +}; + +_$_TokenData _$_$_TokenDataFromJson(Map json) { + return _$_TokenData( + id: json['id'] as String, + createdDateTime: json['created'] as String, + type: _$enumDecode(_$TokenTypeEnumMap, json['type']), + livemode: json['livemode'] as bool, + bankAccount: json['bankAccount'] == null + ? null + : BankAccount.fromJson(json['bankAccount'] as Map), + card: json['card'] == null + ? null + : CardData.fromJson(json['card'] as Map), + ); +} + +Map _$_$_TokenDataToJson(_$_TokenData instance) => + { + 'id': instance.id, + 'created': instance.createdDateTime, + 'type': _$TokenTypeEnumMap[instance.type], + 'livemode': instance.livemode, + 'bankAccount': instance.bankAccount, + 'card': instance.card, + }; + +_$_CardData _$_$_CardDataFromJson(Map json) { + return _$_CardData( + brand: json['brand'] as String, + country: json['country'] as String?, + currency: json['currency'] as String?, + expYear: json['expYear'] as int?, + expMonth: json['expMonth'] as int?, + name: json['name'] as String?, + funding: json['funding'] as String?, + last4: json['last4'] as String?, + address: json['address'] == null + ? null + : Address.fromJson(json['address'] as Map), + ); +} + +Map _$_$_CardDataToJson(_$_CardData instance) => + { + 'brand': instance.brand, + 'country': instance.country, + 'currency': instance.currency, + 'expYear': instance.expYear, + 'expMonth': instance.expMonth, + 'name': instance.name, + 'funding': instance.funding, + 'last4': instance.last4, + 'address': instance.address?.toJson(), + }; + +_$_BankAccount _$_$_BankAccountFromJson(Map json) { + return _$_BankAccount( + accountHolderType: + _$enumDecode(_$BankAccountHolderTypeEnumMap, json['accountHolderType']), + status: _$enumDecode(_$BankAccountStatusEnumMap, json['status']), + bankName: json['bankName'] as String?, + accountHolderName: json['accountHolderName'] as String?, + country: json['country'] as String?, + currency: json['currency'] as String?, + routingNumber: json['routingNumber'] as String?, + ); +} + +Map _$_$_BankAccountToJson(_$_BankAccount instance) => + { + 'accountHolderType': + _$BankAccountHolderTypeEnumMap[instance.accountHolderType], + 'status': _$BankAccountStatusEnumMap[instance.status], + 'bankName': instance.bankName, + 'accountHolderName': instance.accountHolderName, + 'country': instance.country, + 'currency': instance.currency, + 'routingNumber': instance.routingNumber, + }; + +const _$BankAccountHolderTypeEnumMap = { + BankAccountHolderType.Company: 'Company', + BankAccountHolderType.Individual: 'Individual', + BankAccountHolderType.Unknown: 'Unknown', +}; + +const _$BankAccountStatusEnumMap = { + BankAccountStatus.Errored: 'Errored', + BankAccountStatus.New: 'New', + BankAccountStatus.Validated: 'Validated', + BankAccountStatus.VerificationFailed: 'VerificationFailed', + BankAccountStatus.Verified: 'Verified', + BankAccountStatus.Unknown: 'Unknown', +}; diff --git a/packages/stripe_platform_interface/lib/src/models/errors.dart b/packages/stripe_platform_interface/lib/src/models/errors.dart index 743c7a1..b3cbf4f 100644 --- a/packages/stripe_platform_interface/lib/src/models/errors.dart +++ b/packages/stripe_platform_interface/lib/src/models/errors.dart @@ -6,6 +6,8 @@ part 'errors.g.dart'; // ignore_for_file: constant_identifier_names enum PaymentIntentError { unknown } +enum CreateTokenError { unknown } + @freezed /// Wrapper class that represents an error with the Stripe platform. diff --git a/packages/stripe_platform_interface/lib/src/models/errors.freezed.dart b/packages/stripe_platform_interface/lib/src/models/errors.freezed.dart index 0f837af..b62897d 100644 --- a/packages/stripe_platform_interface/lib/src/models/errors.freezed.dart +++ b/packages/stripe_platform_interface/lib/src/models/errors.freezed.dart @@ -127,9 +127,9 @@ class __$StripeErrorGenericCopyWithImpl } } -@JsonSerializable(explicitToJson: true) - /// @nodoc + +@JsonSerializable(explicitToJson: true) class _$_StripeErrorGeneric implements _StripeErrorGeneric { const _$_StripeErrorGeneric( {required this.message, diff --git a/packages/stripe_platform_interface/lib/src/models/payment_intents.dart b/packages/stripe_platform_interface/lib/src/models/payment_intents.dart index 4d949c5..5644283 100644 --- a/packages/stripe_platform_interface/lib/src/models/payment_intents.dart +++ b/packages/stripe_platform_interface/lib/src/models/payment_intents.dart @@ -23,7 +23,7 @@ class PaymentIntent with _$PaymentIntent { required num amount, /// Timestamp since epoch that represents the time the intent is created. - required int created, + required String created, /// The three letter ISO 4217 code for the currency. required String currency, @@ -37,14 +37,15 @@ class PaymentIntent with _$PaymentIntent { /// Determines whether the intent is in live mode or in test mode. required bool livemode, - /// Id of the payment method used in this intent. - required String paymentMethodId, - /// How the funds will be caputure from the customer's account. required CaptureMethod captureMethod, /// Method of how the payment will be confirmed. required ConfirmationMethod confirmationMethod, + + /// Id of the payment method used in this intent. + String? paymentMethodId, + /// Localized description that provides additional context to users. String? description, @@ -52,7 +53,7 @@ class PaymentIntent with _$PaymentIntent { String? receiptEmail, /// Timestamp since epoch when the intent is cancelled. - int? canceledAt, + String? canceledAt, /// Shipping information of the payment intent. ShippingDetails? shipping, @@ -123,6 +124,7 @@ enum PaymentIntentsFutureUsage { enum PaymentIntentsStatus { /// Completed. Succeeded, + /// No payment method is attached to the intent. RequiresPaymentMethod, diff --git a/packages/stripe_platform_interface/lib/src/models/payment_intents.freezed.dart b/packages/stripe_platform_interface/lib/src/models/payment_intents.freezed.dart index b5901a4..2782919 100644 --- a/packages/stripe_platform_interface/lib/src/models/payment_intents.freezed.dart +++ b/packages/stripe_platform_interface/lib/src/models/payment_intents.freezed.dart @@ -23,17 +23,17 @@ class _$PaymentIntentTearOff { _PaymentIntent call( {required String id, required num amount, - required int created, + required String created, required String currency, required PaymentIntentsStatus status, required String clientSecret, required bool livemode, - required String paymentMethodId, required CaptureMethod captureMethod, required ConfirmationMethod confirmationMethod, + String? paymentMethodId, String? description, String? receiptEmail, - int? canceledAt, + String? canceledAt, ShippingDetails? shipping}) { return _PaymentIntent( id: id, @@ -43,9 +43,9 @@ class _$PaymentIntentTearOff { status: status, clientSecret: clientSecret, livemode: livemode, - paymentMethodId: paymentMethodId, captureMethod: captureMethod, confirmationMethod: confirmationMethod, + paymentMethodId: paymentMethodId, description: description, receiptEmail: receiptEmail, canceledAt: canceledAt, @@ -70,7 +70,7 @@ mixin _$PaymentIntent { num get amount => throw _privateConstructorUsedError; /// Timestamp since epoch that represents the time the intent is created. - int get created => throw _privateConstructorUsedError; + String get created => throw _privateConstructorUsedError; /// The three letter ISO 4217 code for the currency. String get currency => throw _privateConstructorUsedError; @@ -84,9 +84,6 @@ mixin _$PaymentIntent { /// Determines whether the intent is in live mode or in test mode. bool get livemode => throw _privateConstructorUsedError; - /// Id of the payment method used in this intent. - String get paymentMethodId => throw _privateConstructorUsedError; - /// How the funds will be caputure from the customer's account. CaptureMethod get captureMethod => throw _privateConstructorUsedError; @@ -94,6 +91,9 @@ mixin _$PaymentIntent { ConfirmationMethod get confirmationMethod => throw _privateConstructorUsedError; + /// Id of the payment method used in this intent. + String? get paymentMethodId => throw _privateConstructorUsedError; + /// Localized description that provides additional context to users. String? get description => throw _privateConstructorUsedError; @@ -101,7 +101,7 @@ mixin _$PaymentIntent { String? get receiptEmail => throw _privateConstructorUsedError; /// Timestamp since epoch when the intent is cancelled. - int? get canceledAt => throw _privateConstructorUsedError; + String? get canceledAt => throw _privateConstructorUsedError; /// Shipping information of the payment intent. ShippingDetails? get shipping => throw _privateConstructorUsedError; @@ -120,17 +120,17 @@ abstract class $PaymentIntentCopyWith<$Res> { $Res call( {String id, num amount, - int created, + String created, String currency, PaymentIntentsStatus status, String clientSecret, bool livemode, - String paymentMethodId, CaptureMethod captureMethod, ConfirmationMethod confirmationMethod, + String? paymentMethodId, String? description, String? receiptEmail, - int? canceledAt, + String? canceledAt, ShippingDetails? shipping}); $ShippingDetailsCopyWith<$Res>? get shipping; @@ -154,9 +154,9 @@ class _$PaymentIntentCopyWithImpl<$Res> Object? status = freezed, Object? clientSecret = freezed, Object? livemode = freezed, - Object? paymentMethodId = freezed, Object? captureMethod = freezed, Object? confirmationMethod = freezed, + Object? paymentMethodId = freezed, Object? description = freezed, Object? receiptEmail = freezed, Object? canceledAt = freezed, @@ -174,7 +174,7 @@ class _$PaymentIntentCopyWithImpl<$Res> created: created == freezed ? _value.created : created // ignore: cast_nullable_to_non_nullable - as int, + as String, currency: currency == freezed ? _value.currency : currency // ignore: cast_nullable_to_non_nullable @@ -191,10 +191,6 @@ class _$PaymentIntentCopyWithImpl<$Res> ? _value.livemode : livemode // ignore: cast_nullable_to_non_nullable as bool, - paymentMethodId: paymentMethodId == freezed - ? _value.paymentMethodId - : paymentMethodId // ignore: cast_nullable_to_non_nullable - as String, captureMethod: captureMethod == freezed ? _value.captureMethod : captureMethod // ignore: cast_nullable_to_non_nullable @@ -203,6 +199,10 @@ class _$PaymentIntentCopyWithImpl<$Res> ? _value.confirmationMethod : confirmationMethod // ignore: cast_nullable_to_non_nullable as ConfirmationMethod, + paymentMethodId: paymentMethodId == freezed + ? _value.paymentMethodId + : paymentMethodId // ignore: cast_nullable_to_non_nullable + as String?, description: description == freezed ? _value.description : description // ignore: cast_nullable_to_non_nullable @@ -214,7 +214,7 @@ class _$PaymentIntentCopyWithImpl<$Res> canceledAt: canceledAt == freezed ? _value.canceledAt : canceledAt // ignore: cast_nullable_to_non_nullable - as int?, + as String?, shipping: shipping == freezed ? _value.shipping : shipping // ignore: cast_nullable_to_non_nullable @@ -244,17 +244,17 @@ abstract class _$PaymentIntentCopyWith<$Res> $Res call( {String id, num amount, - int created, + String created, String currency, PaymentIntentsStatus status, String clientSecret, bool livemode, - String paymentMethodId, CaptureMethod captureMethod, ConfirmationMethod confirmationMethod, + String? paymentMethodId, String? description, String? receiptEmail, - int? canceledAt, + String? canceledAt, ShippingDetails? shipping}); @override @@ -281,9 +281,9 @@ class __$PaymentIntentCopyWithImpl<$Res> Object? status = freezed, Object? clientSecret = freezed, Object? livemode = freezed, - Object? paymentMethodId = freezed, Object? captureMethod = freezed, Object? confirmationMethod = freezed, + Object? paymentMethodId = freezed, Object? description = freezed, Object? receiptEmail = freezed, Object? canceledAt = freezed, @@ -301,7 +301,7 @@ class __$PaymentIntentCopyWithImpl<$Res> created: created == freezed ? _value.created : created // ignore: cast_nullable_to_non_nullable - as int, + as String, currency: currency == freezed ? _value.currency : currency // ignore: cast_nullable_to_non_nullable @@ -318,10 +318,6 @@ class __$PaymentIntentCopyWithImpl<$Res> ? _value.livemode : livemode // ignore: cast_nullable_to_non_nullable as bool, - paymentMethodId: paymentMethodId == freezed - ? _value.paymentMethodId - : paymentMethodId // ignore: cast_nullable_to_non_nullable - as String, captureMethod: captureMethod == freezed ? _value.captureMethod : captureMethod // ignore: cast_nullable_to_non_nullable @@ -330,6 +326,10 @@ class __$PaymentIntentCopyWithImpl<$Res> ? _value.confirmationMethod : confirmationMethod // ignore: cast_nullable_to_non_nullable as ConfirmationMethod, + paymentMethodId: paymentMethodId == freezed + ? _value.paymentMethodId + : paymentMethodId // ignore: cast_nullable_to_non_nullable + as String?, description: description == freezed ? _value.description : description // ignore: cast_nullable_to_non_nullable @@ -341,7 +341,7 @@ class __$PaymentIntentCopyWithImpl<$Res> canceledAt: canceledAt == freezed ? _value.canceledAt : canceledAt // ignore: cast_nullable_to_non_nullable - as int?, + as String?, shipping: shipping == freezed ? _value.shipping : shipping // ignore: cast_nullable_to_non_nullable @@ -350,9 +350,9 @@ class __$PaymentIntentCopyWithImpl<$Res> } } -@JsonSerializable(explicitToJson: true) - /// @nodoc + +@JsonSerializable(explicitToJson: true) class _$_PaymentIntent implements _PaymentIntent { const _$_PaymentIntent( {required this.id, @@ -362,9 +362,9 @@ class _$_PaymentIntent implements _PaymentIntent { required this.status, required this.clientSecret, required this.livemode, - required this.paymentMethodId, required this.captureMethod, required this.confirmationMethod, + this.paymentMethodId, this.description, this.receiptEmail, this.canceledAt, @@ -384,7 +384,7 @@ class _$_PaymentIntent implements _PaymentIntent { @override /// Timestamp since epoch that represents the time the intent is created. - final int created; + final String created; @override /// The three letter ISO 4217 code for the currency. @@ -403,10 +403,6 @@ class _$_PaymentIntent implements _PaymentIntent { final bool livemode; @override - /// Id of the payment method used in this intent. - final String paymentMethodId; - @override - /// How the funds will be caputure from the customer's account. final CaptureMethod captureMethod; @override @@ -415,6 +411,10 @@ class _$_PaymentIntent implements _PaymentIntent { final ConfirmationMethod confirmationMethod; @override + /// Id of the payment method used in this intent. + final String? paymentMethodId; + @override + /// Localized description that provides additional context to users. final String? description; @override @@ -424,7 +424,7 @@ class _$_PaymentIntent implements _PaymentIntent { @override /// Timestamp since epoch when the intent is cancelled. - final int? canceledAt; + final String? canceledAt; @override /// Shipping information of the payment intent. @@ -432,7 +432,7 @@ class _$_PaymentIntent implements _PaymentIntent { @override String toString() { - return 'PaymentIntent(id: $id, amount: $amount, created: $created, currency: $currency, status: $status, clientSecret: $clientSecret, livemode: $livemode, paymentMethodId: $paymentMethodId, captureMethod: $captureMethod, confirmationMethod: $confirmationMethod, description: $description, receiptEmail: $receiptEmail, canceledAt: $canceledAt, shipping: $shipping)'; + return 'PaymentIntent(id: $id, amount: $amount, created: $created, currency: $currency, status: $status, clientSecret: $clientSecret, livemode: $livemode, captureMethod: $captureMethod, confirmationMethod: $confirmationMethod, paymentMethodId: $paymentMethodId, description: $description, receiptEmail: $receiptEmail, canceledAt: $canceledAt, shipping: $shipping)'; } @override @@ -457,15 +457,15 @@ class _$_PaymentIntent implements _PaymentIntent { (identical(other.livemode, livemode) || const DeepCollectionEquality() .equals(other.livemode, livemode)) && - (identical(other.paymentMethodId, paymentMethodId) || - const DeepCollectionEquality() - .equals(other.paymentMethodId, paymentMethodId)) && (identical(other.captureMethod, captureMethod) || const DeepCollectionEquality() .equals(other.captureMethod, captureMethod)) && (identical(other.confirmationMethod, confirmationMethod) || const DeepCollectionEquality() .equals(other.confirmationMethod, confirmationMethod)) && + (identical(other.paymentMethodId, paymentMethodId) || + const DeepCollectionEquality() + .equals(other.paymentMethodId, paymentMethodId)) && (identical(other.description, description) || const DeepCollectionEquality() .equals(other.description, description)) && @@ -490,9 +490,9 @@ class _$_PaymentIntent implements _PaymentIntent { const DeepCollectionEquality().hash(status) ^ const DeepCollectionEquality().hash(clientSecret) ^ const DeepCollectionEquality().hash(livemode) ^ - const DeepCollectionEquality().hash(paymentMethodId) ^ const DeepCollectionEquality().hash(captureMethod) ^ const DeepCollectionEquality().hash(confirmationMethod) ^ + const DeepCollectionEquality().hash(paymentMethodId) ^ const DeepCollectionEquality().hash(description) ^ const DeepCollectionEquality().hash(receiptEmail) ^ const DeepCollectionEquality().hash(canceledAt) ^ @@ -513,17 +513,17 @@ abstract class _PaymentIntent implements PaymentIntent { const factory _PaymentIntent( {required String id, required num amount, - required int created, + required String created, required String currency, required PaymentIntentsStatus status, required String clientSecret, required bool livemode, - required String paymentMethodId, required CaptureMethod captureMethod, required ConfirmationMethod confirmationMethod, + String? paymentMethodId, String? description, String? receiptEmail, - int? canceledAt, + String? canceledAt, ShippingDetails? shipping}) = _$_PaymentIntent; factory _PaymentIntent.fromJson(Map json) = @@ -540,7 +540,7 @@ abstract class _PaymentIntent implements PaymentIntent { @override /// Timestamp since epoch that represents the time the intent is created. - int get created => throw _privateConstructorUsedError; + String get created => throw _privateConstructorUsedError; @override /// The three letter ISO 4217 code for the currency. @@ -559,10 +559,6 @@ abstract class _PaymentIntent implements PaymentIntent { bool get livemode => throw _privateConstructorUsedError; @override - /// Id of the payment method used in this intent. - String get paymentMethodId => throw _privateConstructorUsedError; - @override - /// How the funds will be caputure from the customer's account. CaptureMethod get captureMethod => throw _privateConstructorUsedError; @override @@ -572,6 +568,10 @@ abstract class _PaymentIntent implements PaymentIntent { throw _privateConstructorUsedError; @override + /// Id of the payment method used in this intent. + String? get paymentMethodId => throw _privateConstructorUsedError; + @override + /// Localized description that provides additional context to users. String? get description => throw _privateConstructorUsedError; @override @@ -581,7 +581,7 @@ abstract class _PaymentIntent implements PaymentIntent { @override /// Timestamp since epoch when the intent is cancelled. - int? get canceledAt => throw _privateConstructorUsedError; + String? get canceledAt => throw _privateConstructorUsedError; @override /// Shipping information of the payment intent. @@ -773,9 +773,9 @@ class __$ShippingDetailsCopyWithImpl<$Res> } } -@JsonSerializable(explicitToJson: true) - /// @nodoc + +@JsonSerializable(explicitToJson: true) class _$_ShippingDetails implements _ShippingDetails { const _$_ShippingDetails( {required this.address, diff --git a/packages/stripe_platform_interface/lib/src/models/payment_intents.g.dart b/packages/stripe_platform_interface/lib/src/models/payment_intents.g.dart index fda36b1..2acdd66 100644 --- a/packages/stripe_platform_interface/lib/src/models/payment_intents.g.dart +++ b/packages/stripe_platform_interface/lib/src/models/payment_intents.g.dart @@ -10,18 +10,18 @@ _$_PaymentIntent _$_$_PaymentIntentFromJson(Map json) { return _$_PaymentIntent( id: json['id'] as String, amount: json['amount'] as num, - created: json['created'] as int, + created: json['created'] as String, currency: json['currency'] as String, status: _$enumDecode(_$PaymentIntentsStatusEnumMap, json['status']), clientSecret: json['clientSecret'] as String, livemode: json['livemode'] as bool, - paymentMethodId: json['paymentMethodId'] as String, captureMethod: _$enumDecode(_$CaptureMethodEnumMap, json['captureMethod']), confirmationMethod: _$enumDecode(_$ConfirmationMethodEnumMap, json['confirmationMethod']), + paymentMethodId: json['paymentMethodId'] as String?, description: json['description'] as String?, receiptEmail: json['receiptEmail'] as String?, - canceledAt: json['canceledAt'] as int?, + canceledAt: json['canceledAt'] as String?, shipping: json['shipping'] == null ? null : ShippingDetails.fromJson(json['shipping'] as Map), @@ -37,10 +37,10 @@ Map _$_$_PaymentIntentToJson(_$_PaymentIntent instance) => 'status': _$PaymentIntentsStatusEnumMap[instance.status], 'clientSecret': instance.clientSecret, 'livemode': instance.livemode, - 'paymentMethodId': instance.paymentMethodId, 'captureMethod': _$CaptureMethodEnumMap[instance.captureMethod], 'confirmationMethod': _$ConfirmationMethodEnumMap[instance.confirmationMethod], + 'paymentMethodId': instance.paymentMethodId, 'description': instance.description, 'receiptEmail': instance.receiptEmail, 'canceledAt': instance.canceledAt, diff --git a/packages/stripe_platform_interface/lib/src/models/payment_methods.freezed.dart b/packages/stripe_platform_interface/lib/src/models/payment_methods.freezed.dart index 544c8e7..63907db 100644 --- a/packages/stripe_platform_interface/lib/src/models/payment_methods.freezed.dart +++ b/packages/stripe_platform_interface/lib/src/models/payment_methods.freezed.dart @@ -416,9 +416,9 @@ class __$PaymentMethodCopyWithImpl<$Res> } } -@JsonSerializable(explicitToJson: true) - /// @nodoc + +@JsonSerializable(explicitToJson: true) class _$_PaymentMethod implements _PaymentMethod { const _$_PaymentMethod( {required this.id, @@ -811,9 +811,9 @@ class __$BillingDetailsCopyWithImpl<$Res> } } -@JsonSerializable(explicitToJson: true) - /// @nodoc + +@JsonSerializable(explicitToJson: true) class _$_BillingDetails implements _BillingDetails { const _$_BillingDetails({this.email, this.address, this.phone, this.name}); @@ -1031,9 +1031,9 @@ class __$AuBecsDebitCopyWithImpl<$Res> extends _$AuBecsDebitCopyWithImpl<$Res> } } -@JsonSerializable(explicitToJson: true) - /// @nodoc + +@JsonSerializable(explicitToJson: true) class _$_AuBecsDebit implements _AuBecsDebit { const _$_AuBecsDebit({this.fingerprint, this.last4, this.bsbNumber}); @@ -1235,9 +1235,9 @@ class __$BacsDebitCopyWithImpl<$Res> extends _$BacsDebitCopyWithImpl<$Res> } } -@JsonSerializable(explicitToJson: true) - /// @nodoc + +@JsonSerializable(explicitToJson: true) class _$_BacsDebit implements _BacsDebit { const _$_BacsDebit({this.sortCode, this.fingerprint, this.last4}); @@ -1497,9 +1497,9 @@ class __$CardCopyWithImpl<$Res> extends _$CardCopyWithImpl<$Res> } } -@JsonSerializable(explicitToJson: true) - /// @nodoc + +@JsonSerializable(explicitToJson: true) class _$_Card implements _Card { const _$_Card( {this.brand, @@ -1729,9 +1729,9 @@ class __$FpxCopyWithImpl<$Res> extends _$FpxCopyWithImpl<$Res> } } -@JsonSerializable(explicitToJson: true) - /// @nodoc + +@JsonSerializable(explicitToJson: true) class _$_Fpx implements _Fpx { const _$_Fpx({this.bank, this.accountHolderType}); @@ -1901,9 +1901,9 @@ class __$IdealCopyWithImpl<$Res> extends _$IdealCopyWithImpl<$Res> } } -@JsonSerializable(explicitToJson: true) - /// @nodoc + +@JsonSerializable(explicitToJson: true) class _$_Ideal implements _Ideal { const _$_Ideal({this.bankIdentifierCode, this.bank}); @@ -2107,9 +2107,9 @@ class __$SepaDebitCopyWithImpl<$Res> extends _$SepaDebitCopyWithImpl<$Res> } } -@JsonSerializable(explicitToJson: true) - /// @nodoc + +@JsonSerializable(explicitToJson: true) class _$_SepaDebit implements _SepaDebit { const _$_SepaDebit( {this.country, this.bankCode, this.fingerprint, this.last4}); @@ -2297,9 +2297,9 @@ class __$SofortCopyWithImpl<$Res> extends _$SofortCopyWithImpl<$Res> } } -@JsonSerializable(explicitToJson: true) - /// @nodoc + +@JsonSerializable(explicitToJson: true) class _$_Sofort implements _Sofort { const _$_Sofort({this.country}); @@ -2443,9 +2443,9 @@ class __$UpiCopyWithImpl<$Res> extends _$UpiCopyWithImpl<$Res> } } -@JsonSerializable(explicitToJson: true) - /// @nodoc + +@JsonSerializable(explicitToJson: true) class _$_Upi implements _Upi { const _$_Upi({this.vpa}); @@ -2843,10 +2843,10 @@ class __$PaymentMethodParamsCardCopyWithImpl<$Res> } } +/// @nodoc + @JsonSerializable(explicitToJson: true) @FreezedUnionValue('Card') - -/// @nodoc class _$_PaymentMethodParamsCard implements _PaymentMethodParamsCard { const _$_PaymentMethodParamsCard( {this.setupFutureUsage, this.billingDetails}); @@ -3085,10 +3085,10 @@ class __$PaymentMethodParamsCardWithTokenCopyWithImpl<$Res> } } +/// @nodoc + @JsonSerializable(explicitToJson: true) @FreezedUnionValue('Card') - -/// @nodoc class _$_PaymentMethodParamsCardWithToken implements _PaymentMethodParamsCardWithToken { const _$_PaymentMethodParamsCardWithToken( @@ -3330,10 +3330,10 @@ class __$PaymentMethodParamsCardWithMethodIdCopyWithImpl<$Res> } } +/// @nodoc + @JsonSerializable(explicitToJson: true) @FreezedUnionValue('Card') - -/// @nodoc class _$_PaymentMethodParamsCardWithMethodId implements _PaymentMethodParamsCardWithMethodId { const _$_PaymentMethodParamsCardWithMethodId( @@ -3554,10 +3554,10 @@ class __$PaymentMethodParamsAlipayCopyWithImpl<$Res> super._value as _PaymentMethodParamsAlipay; } +/// @nodoc + @JsonSerializable(explicitToJson: true) @FreezedUnionValue('Alipay') - -/// @nodoc class _$_PaymentMethodParamsAlipay implements _PaymentMethodParamsAlipay { const _$_PaymentMethodParamsAlipay(); @@ -3769,10 +3769,10 @@ class __$PaymentMethodParamsIdealCopyWithImpl<$Res> } } +/// @nodoc + @JsonSerializable(explicitToJson: true) @FreezedUnionValue('Ideal') - -/// @nodoc class _$_PaymentMethodParamsIdeal implements _PaymentMethodParamsIdeal { const _$_PaymentMethodParamsIdeal({this.billingDetails, this.bankName}); @@ -4017,10 +4017,10 @@ class __$PaymentMethodParamsBankContactCopyWithImpl<$Res> } } +/// @nodoc + @JsonSerializable(explicitToJson: true) @FreezedUnionValue('Bancontact') - -/// @nodoc class _$_PaymentMethodParamsBankContact implements _PaymentMethodParamsBankContact { const _$_PaymentMethodParamsBankContact({this.billingDetails}); @@ -4255,10 +4255,10 @@ class __$PaymentMethodParamsGiroPayCopyWithImpl<$Res> } } +/// @nodoc + @JsonSerializable(explicitToJson: true) @FreezedUnionValue('Giropay') - -/// @nodoc class _$_PaymentMethodParamsGiroPay implements _PaymentMethodParamsGiroPay { const _$_PaymentMethodParamsGiroPay({this.billingDetails}); @@ -4488,10 +4488,10 @@ class __$PaymentMethodParamsEpsCopyWithImpl<$Res> } } +/// @nodoc + @JsonSerializable(explicitToJson: true) @FreezedUnionValue('Eps') - -/// @nodoc class _$_PaymentMethodParamsEps implements _PaymentMethodParamsEps { const _$_PaymentMethodParamsEps({this.billingDetails}); @@ -4721,10 +4721,10 @@ class __$PaymentMethodParamsPayCopyWithImpl<$Res> } } +/// @nodoc + @JsonSerializable(explicitToJson: true) @FreezedUnionValue('GrabPay') - -/// @nodoc class _$_PaymentMethodParamsPay implements _PaymentMethodParamsPay { const _$_PaymentMethodParamsPay({this.billingDetails}); @@ -4954,10 +4954,10 @@ class __$PaymentMethodParamsP24CopyWithImpl<$Res> } } +/// @nodoc + @JsonSerializable(explicitToJson: true) @FreezedUnionValue('P24') - -/// @nodoc class _$_PaymentMethodParamsP24 implements _PaymentMethodParamsP24 { const _$_PaymentMethodParamsP24({this.billingDetails}); @@ -5174,10 +5174,10 @@ class __$PaymentMethodParamsFpxCopyWithImpl<$Res> } } +/// @nodoc + @JsonSerializable(explicitToJson: true) @FreezedUnionValue('Fpx') - -/// @nodoc class _$_PaymentMethodParamsFpx implements _PaymentMethodParamsFpx { const _$_PaymentMethodParamsFpx({required this.testOfflineBank}); @@ -5420,10 +5420,10 @@ class __$PaymentMethodParamsSepaDebitCopyWithImpl<$Res> } } +/// @nodoc + @JsonSerializable(explicitToJson: true) @FreezedUnionValue('SepaDebit') - -/// @nodoc class _$_PaymentMethodParamsSepaDebit implements _PaymentMethodParamsSepaDebit { const _$_PaymentMethodParamsSepaDebit( {required this.iban, this.setupFutureUsage, this.billingDetails}); @@ -5686,10 +5686,10 @@ class __$PaymentMethodParamsSofortCopyWithImpl<$Res> } } +/// @nodoc + @JsonSerializable(explicitToJson: true) @FreezedUnionValue('Sofort') - -/// @nodoc class _$_PaymentMethodParamsSofort implements _PaymentMethodParamsSofort { const _$_PaymentMethodParamsSofort( {required this.country, this.setupFutureUsage, this.billingDetails}); @@ -5955,10 +5955,10 @@ class __$PaymentMethodParamsAfterpayClearpayCopyWithImpl<$Res> } } +/// @nodoc + @JsonSerializable(explicitToJson: true) @FreezedUnionValue('AfterpayClearpay') - -/// @nodoc class _$_PaymentMethodParamsAfterpayClearpay implements _PaymentMethodParamsAfterpayClearpay { const _$_PaymentMethodParamsAfterpayClearpay( @@ -6206,10 +6206,10 @@ class __$PaymentMethodParamsOxxoCopyWithImpl<$Res> } } +/// @nodoc + @JsonSerializable(explicitToJson: true) @FreezedUnionValue('Oxxo') - -/// @nodoc class _$_PaymentMethodParamsOxxo implements _PaymentMethodParamsOxxo { const _$_PaymentMethodParamsOxxo({this.billingDetails}); diff --git a/packages/stripe_platform_interface/lib/src/models/payment_sheet.dart b/packages/stripe_platform_interface/lib/src/models/payment_sheet.dart index 21fa192..d41f52b 100644 --- a/packages/stripe_platform_interface/lib/src/models/payment_sheet.dart +++ b/packages/stripe_platform_interface/lib/src/models/payment_sheet.dart @@ -25,7 +25,15 @@ class SetupPaymentSheetParameters with _$SetupPaymentSheetParameters { String? customerEphemeralKeySecret, /// Secret used for client-side retrieval using a publishable key. - required String paymentIntentClientSecret, + /// + /// If this value is null make sure to add a [setupIntentClientSecret] + String? paymentIntentClientSecret, + + /// The client secret of this SetupIntent + /// + /// If this value is null make sure to add a [paymentIntentClientSecret] + + String? setupIntentClientSecret, /// Display name of the merchant String? merchantDisplayName, diff --git a/packages/stripe_platform_interface/lib/src/models/payment_sheet.freezed.dart b/packages/stripe_platform_interface/lib/src/models/payment_sheet.freezed.dart index 70f744c..a6cefe1 100644 --- a/packages/stripe_platform_interface/lib/src/models/payment_sheet.freezed.dart +++ b/packages/stripe_platform_interface/lib/src/models/payment_sheet.freezed.dart @@ -25,7 +25,8 @@ class _$SetupPaymentSheetParametersTearOff { {bool customFlow = false, String? customerId, String? customerEphemeralKeySecret, - required String paymentIntentClientSecret, + String? paymentIntentClientSecret, + String? setupIntentClientSecret, String? merchantDisplayName, String? merchantCountryCode, bool? applePay, @@ -37,6 +38,7 @@ class _$SetupPaymentSheetParametersTearOff { customerId: customerId, customerEphemeralKeySecret: customerEphemeralKeySecret, paymentIntentClientSecret: paymentIntentClientSecret, + setupIntentClientSecret: setupIntentClientSecret, merchantDisplayName: merchantDisplayName, merchantCountryCode: merchantCountryCode, applePay: applePay, @@ -71,7 +73,14 @@ mixin _$SetupPaymentSheetParameters { String? get customerEphemeralKeySecret => throw _privateConstructorUsedError; /// Secret used for client-side retrieval using a publishable key. - String get paymentIntentClientSecret => throw _privateConstructorUsedError; + /// + /// If this value is null make sure to add a [setupIntentClientSecret] + String? get paymentIntentClientSecret => throw _privateConstructorUsedError; + + /// The client secret of this SetupIntent + /// + /// If this value is null make sure to add a [paymentIntentClientSecret] + String? get setupIntentClientSecret => throw _privateConstructorUsedError; /// Display name of the merchant String? get merchantDisplayName => throw _privateConstructorUsedError; @@ -112,7 +121,8 @@ abstract class $SetupPaymentSheetParametersCopyWith<$Res> { {bool customFlow, String? customerId, String? customerEphemeralKeySecret, - String paymentIntentClientSecret, + String? paymentIntentClientSecret, + String? setupIntentClientSecret, String? merchantDisplayName, String? merchantCountryCode, bool? applePay, @@ -136,6 +146,7 @@ class _$SetupPaymentSheetParametersCopyWithImpl<$Res> Object? customerId = freezed, Object? customerEphemeralKeySecret = freezed, Object? paymentIntentClientSecret = freezed, + Object? setupIntentClientSecret = freezed, Object? merchantDisplayName = freezed, Object? merchantCountryCode = freezed, Object? applePay = freezed, @@ -159,7 +170,11 @@ class _$SetupPaymentSheetParametersCopyWithImpl<$Res> paymentIntentClientSecret: paymentIntentClientSecret == freezed ? _value.paymentIntentClientSecret : paymentIntentClientSecret // ignore: cast_nullable_to_non_nullable - as String, + as String?, + setupIntentClientSecret: setupIntentClientSecret == freezed + ? _value.setupIntentClientSecret + : setupIntentClientSecret // ignore: cast_nullable_to_non_nullable + as String?, merchantDisplayName: merchantDisplayName == freezed ? _value.merchantDisplayName : merchantDisplayName // ignore: cast_nullable_to_non_nullable @@ -199,7 +214,8 @@ abstract class _$SetupParametersCopyWith<$Res> {bool customFlow, String? customerId, String? customerEphemeralKeySecret, - String paymentIntentClientSecret, + String? paymentIntentClientSecret, + String? setupIntentClientSecret, String? merchantDisplayName, String? merchantCountryCode, bool? applePay, @@ -225,6 +241,7 @@ class __$SetupParametersCopyWithImpl<$Res> Object? customerId = freezed, Object? customerEphemeralKeySecret = freezed, Object? paymentIntentClientSecret = freezed, + Object? setupIntentClientSecret = freezed, Object? merchantDisplayName = freezed, Object? merchantCountryCode = freezed, Object? applePay = freezed, @@ -248,7 +265,11 @@ class __$SetupParametersCopyWithImpl<$Res> paymentIntentClientSecret: paymentIntentClientSecret == freezed ? _value.paymentIntentClientSecret : paymentIntentClientSecret // ignore: cast_nullable_to_non_nullable - as String, + as String?, + setupIntentClientSecret: setupIntentClientSecret == freezed + ? _value.setupIntentClientSecret + : setupIntentClientSecret // ignore: cast_nullable_to_non_nullable + as String?, merchantDisplayName: merchantDisplayName == freezed ? _value.merchantDisplayName : merchantDisplayName // ignore: cast_nullable_to_non_nullable @@ -277,15 +298,15 @@ class __$SetupParametersCopyWithImpl<$Res> } } -@JsonSerializable() - /// @nodoc +@JsonSerializable() class _$_SetupParameters implements _SetupParameters { const _$_SetupParameters( {this.customFlow = false, this.customerId, this.customerEphemeralKeySecret, - required this.paymentIntentClientSecret, + this.paymentIntentClientSecret, + this.setupIntentClientSecret, this.merchantDisplayName, this.merchantCountryCode, this.applePay, @@ -317,7 +338,15 @@ class _$_SetupParameters implements _SetupParameters { @override /// Secret used for client-side retrieval using a publishable key. - final String paymentIntentClientSecret; + /// + /// If this value is null make sure to add a [setupIntentClientSecret] + final String? paymentIntentClientSecret; + @override + + /// The client secret of this SetupIntent + /// + /// If this value is null make sure to add a [paymentIntentClientSecret] + final String? setupIntentClientSecret; @override /// Display name of the merchant @@ -351,7 +380,7 @@ class _$_SetupParameters implements _SetupParameters { @override String toString() { - return 'SetupPaymentSheetParameters(customFlow: $customFlow, customerId: $customerId, customerEphemeralKeySecret: $customerEphemeralKeySecret, paymentIntentClientSecret: $paymentIntentClientSecret, merchantDisplayName: $merchantDisplayName, merchantCountryCode: $merchantCountryCode, applePay: $applePay, style: $style, googlePay: $googlePay, testEnv: $testEnv)'; + return 'SetupPaymentSheetParameters(customFlow: $customFlow, customerId: $customerId, customerEphemeralKeySecret: $customerEphemeralKeySecret, paymentIntentClientSecret: $paymentIntentClientSecret, setupIntentClientSecret: $setupIntentClientSecret, merchantDisplayName: $merchantDisplayName, merchantCountryCode: $merchantCountryCode, applePay: $applePay, style: $style, googlePay: $googlePay, testEnv: $testEnv)'; } @override @@ -369,11 +398,13 @@ class _$_SetupParameters implements _SetupParameters { const DeepCollectionEquality().equals( other.customerEphemeralKeySecret, customerEphemeralKeySecret)) && - (identical(other.paymentIntentClientSecret, - paymentIntentClientSecret) || + (identical(other.paymentIntentClientSecret, paymentIntentClientSecret) || const DeepCollectionEquality().equals( other.paymentIntentClientSecret, paymentIntentClientSecret)) && + (identical(other.setupIntentClientSecret, setupIntentClientSecret) || + const DeepCollectionEquality().equals( + other.setupIntentClientSecret, setupIntentClientSecret)) && (identical(other.merchantDisplayName, merchantDisplayName) || const DeepCollectionEquality() .equals(other.merchantDisplayName, merchantDisplayName)) && @@ -399,6 +430,7 @@ class _$_SetupParameters implements _SetupParameters { const DeepCollectionEquality().hash(customerId) ^ const DeepCollectionEquality().hash(customerEphemeralKeySecret) ^ const DeepCollectionEquality().hash(paymentIntentClientSecret) ^ + const DeepCollectionEquality().hash(setupIntentClientSecret) ^ const DeepCollectionEquality().hash(merchantDisplayName) ^ const DeepCollectionEquality().hash(merchantCountryCode) ^ const DeepCollectionEquality().hash(applePay) ^ @@ -422,7 +454,8 @@ abstract class _SetupParameters implements SetupPaymentSheetParameters { {bool customFlow, String? customerId, String? customerEphemeralKeySecret, - required String paymentIntentClientSecret, + String? paymentIntentClientSecret, + String? setupIntentClientSecret, String? merchantDisplayName, String? merchantCountryCode, bool? applePay, @@ -453,7 +486,15 @@ abstract class _SetupParameters implements SetupPaymentSheetParameters { @override /// Secret used for client-side retrieval using a publishable key. - String get paymentIntentClientSecret => throw _privateConstructorUsedError; + /// + /// If this value is null make sure to add a [setupIntentClientSecret] + String? get paymentIntentClientSecret => throw _privateConstructorUsedError; + @override + + /// The client secret of this SetupIntent + /// + /// If this value is null make sure to add a [paymentIntentClientSecret] + String? get setupIntentClientSecret => throw _privateConstructorUsedError; @override /// Display name of the merchant @@ -609,9 +650,8 @@ class __$PresentParametersCopyWithImpl<$Res> } } -@JsonSerializable() - /// @nodoc +@JsonSerializable() class _$_PresentParameters implements _PresentParameters { const _$_PresentParameters( {required this.clientSecret, this.confirmPayment = false}); diff --git a/packages/stripe_platform_interface/lib/src/models/payment_sheet.g.dart b/packages/stripe_platform_interface/lib/src/models/payment_sheet.g.dart index 514c5e1..f0c41e8 100644 --- a/packages/stripe_platform_interface/lib/src/models/payment_sheet.g.dart +++ b/packages/stripe_platform_interface/lib/src/models/payment_sheet.g.dart @@ -11,7 +11,8 @@ _$_SetupParameters _$_$_SetupParametersFromJson(Map json) { customFlow: json['customFlow'] as bool? ?? false, customerId: json['customerId'] as String?, customerEphemeralKeySecret: json['customerEphemeralKeySecret'] as String?, - paymentIntentClientSecret: json['paymentIntentClientSecret'] as String, + paymentIntentClientSecret: json['paymentIntentClientSecret'] as String?, + setupIntentClientSecret: json['setupIntentClientSecret'] as String?, merchantDisplayName: json['merchantDisplayName'] as String?, merchantCountryCode: json['merchantCountryCode'] as String?, applePay: json['applePay'] as bool?, @@ -27,6 +28,7 @@ Map _$_$_SetupParametersToJson(_$_SetupParameters instance) => 'customerId': instance.customerId, 'customerEphemeralKeySecret': instance.customerEphemeralKeySecret, 'paymentIntentClientSecret': instance.paymentIntentClientSecret, + 'setupIntentClientSecret': instance.setupIntentClientSecret, 'merchantDisplayName': instance.merchantDisplayName, 'merchantCountryCode': instance.merchantCountryCode, 'applePay': instance.applePay, diff --git a/packages/stripe_platform_interface/lib/src/models/setup_intent.dart b/packages/stripe_platform_interface/lib/src/models/setup_intent.dart index 8f7e6b7..b06e3ee 100644 --- a/packages/stripe_platform_interface/lib/src/models/setup_intent.dart +++ b/packages/stripe_platform_interface/lib/src/models/setup_intent.dart @@ -47,8 +47,7 @@ class SetupIntent with _$SetupIntent { String? description, /// Timestamp since epoch that represents the time the intent is created. - - int? created, + String? created, /// Error encountered since last configmration. LastSetupError? lastSetupError, diff --git a/packages/stripe_platform_interface/lib/src/models/setup_intent.freezed.dart b/packages/stripe_platform_interface/lib/src/models/setup_intent.freezed.dart index f03e8ca..21b6ec8 100644 --- a/packages/stripe_platform_interface/lib/src/models/setup_intent.freezed.dart +++ b/packages/stripe_platform_interface/lib/src/models/setup_intent.freezed.dart @@ -29,7 +29,7 @@ class _$SetupIntentTearOff { required String usage, required List paymentMethodTypes, String? description, - int? created, + String? created, LastSetupError? lastSetupError}) { return _SetupIntent( id: id, @@ -83,7 +83,7 @@ mixin _$SetupIntent { String? get description => throw _privateConstructorUsedError; /// Timestamp since epoch that represents the time the intent is created. - int? get created => throw _privateConstructorUsedError; + String? get created => throw _privateConstructorUsedError; /// Error encountered since last configmration. LastSetupError? get lastSetupError => throw _privateConstructorUsedError; @@ -108,7 +108,7 @@ abstract class $SetupIntentCopyWith<$Res> { String usage, List paymentMethodTypes, String? description, - int? created, + String? created, LastSetupError? lastSetupError}); $LastSetupErrorCopyWith<$Res>? get lastSetupError; @@ -171,7 +171,7 @@ class _$SetupIntentCopyWithImpl<$Res> implements $SetupIntentCopyWith<$Res> { created: created == freezed ? _value.created : created // ignore: cast_nullable_to_non_nullable - as int?, + as String?, lastSetupError: lastSetupError == freezed ? _value.lastSetupError : lastSetupError // ignore: cast_nullable_to_non_nullable @@ -207,7 +207,7 @@ abstract class _$SetupIntentCopyWith<$Res> String usage, List paymentMethodTypes, String? description, - int? created, + String? created, LastSetupError? lastSetupError}); @override @@ -273,7 +273,7 @@ class __$SetupIntentCopyWithImpl<$Res> extends _$SetupIntentCopyWithImpl<$Res> created: created == freezed ? _value.created : created // ignore: cast_nullable_to_non_nullable - as int?, + as String?, lastSetupError: lastSetupError == freezed ? _value.lastSetupError : lastSetupError // ignore: cast_nullable_to_non_nullable @@ -282,9 +282,9 @@ class __$SetupIntentCopyWithImpl<$Res> extends _$SetupIntentCopyWithImpl<$Res> } } -@JsonSerializable(explicitToJson: true) - /// @nodoc + +@JsonSerializable(explicitToJson: true) class _$_SetupIntent implements _SetupIntent { const _$_SetupIntent( {required this.id, @@ -338,7 +338,7 @@ class _$_SetupIntent implements _SetupIntent { @override /// Timestamp since epoch that represents the time the intent is created. - final int? created; + final String? created; @override /// Error encountered since last configmration. @@ -417,7 +417,7 @@ abstract class _SetupIntent implements SetupIntent { required String usage, required List paymentMethodTypes, String? description, - int? created, + String? created, LastSetupError? lastSetupError}) = _$_SetupIntent; factory _SetupIntent.fromJson(Map json) = @@ -461,7 +461,7 @@ abstract class _SetupIntent implements SetupIntent { @override /// Timestamp since epoch that represents the time the intent is created. - int? get created => throw _privateConstructorUsedError; + String? get created => throw _privateConstructorUsedError; @override /// Error encountered since last configmration. @@ -583,9 +583,9 @@ class __$LastSetupErrorCopyWithImpl<$Res> } } -@JsonSerializable(explicitToJson: true) - /// @nodoc + +@JsonSerializable(explicitToJson: true) class _$_LastSetupError implements _LastSetupError { const _$_LastSetupError({required this.code, required this.message}); diff --git a/packages/stripe_platform_interface/lib/src/models/setup_intent.g.dart b/packages/stripe_platform_interface/lib/src/models/setup_intent.g.dart index 9d6ab12..79b6221 100644 --- a/packages/stripe_platform_interface/lib/src/models/setup_intent.g.dart +++ b/packages/stripe_platform_interface/lib/src/models/setup_intent.g.dart @@ -18,7 +18,7 @@ _$_SetupIntent _$_$_SetupIntentFromJson(Map json) { .map((e) => _$enumDecode(_$PaymentMethodTypeEnumMap, e)) .toList(), description: json['description'] as String?, - created: json['created'] as int?, + created: json['created'] as String?, lastSetupError: json['lastSetupError'] == null ? null : LastSetupError.fromJson( diff --git a/packages/stripe_platform_interface/lib/src/models/three_d_secure.dart b/packages/stripe_platform_interface/lib/src/models/three_d_secure.dart index f487619..adf12ef 100644 --- a/packages/stripe_platform_interface/lib/src/models/three_d_secure.dart +++ b/packages/stripe_platform_interface/lib/src/models/three_d_secure.dart @@ -23,7 +23,19 @@ class ThreeDSecureConfigurationParams with _$ThreeDSecureConfigurationParams { /// Styling for the 3d secure confirmation button. - ThreeDSecureSubmitButtonThemeData? submitButton, + ThreeDSecureButtonThemeData? submitButton, + + /// Styling for the 3d secure cancel button. + ThreeDSecureButtonThemeData? cancelButton, + + /// Styling for the 3d secure next button. + ThreeDSecureButtonThemeData? nextButton, + + /// Styling for the 3d secure continue button. + ThreeDSecureButtonThemeData? continueButton, + + /// Styling for the 3d secure resend button. + ThreeDSecureButtonThemeData? resendButton, }) = _ThreeDSecureConfigurationParams; factory ThreeDSecureConfigurationParams.fromJson(Map json) => @@ -119,12 +131,11 @@ class ThreeDSecureTextFieldThemeData with _$ThreeDSecureTextFieldThemeData { @freezed -/// Styling info related to the 3d secure confirmation button. +/// Styling info related to the 3d secure button. -class ThreeDSecureSubmitButtonThemeData - with _$ThreeDSecureSubmitButtonThemeData { +class ThreeDSecureButtonThemeData with _$ThreeDSecureButtonThemeData { @JsonSerializable(explicitToJson: true) - const factory ThreeDSecureSubmitButtonThemeData({ + const factory ThreeDSecureButtonThemeData({ /// Color in hex for button background String? backgroundColor, @@ -136,9 +147,8 @@ class ThreeDSecureSubmitButtonThemeData /// Font size for the button text. double? textFontSize, - }) = _ThreeDSecureSubmitButtonThemeData; + }) = _ThreeDSecureButtonThemeData; - factory ThreeDSecureSubmitButtonThemeData.fromJson( - Map json) => - _$ThreeDSecureSubmitButtonThemeDataFromJson(json); + factory ThreeDSecureButtonThemeData.fromJson(Map json) => + _$ThreeDSecureButtonThemeDataFromJson(json); } diff --git a/packages/stripe_platform_interface/lib/src/models/three_d_secure.freezed.dart b/packages/stripe_platform_interface/lib/src/models/three_d_secure.freezed.dart index 501c5f3..0fc53db 100644 --- a/packages/stripe_platform_interface/lib/src/models/three_d_secure.freezed.dart +++ b/packages/stripe_platform_interface/lib/src/models/three_d_secure.freezed.dart @@ -26,13 +26,21 @@ class _$ThreeDSecureConfigurationParamsTearOff { int? timeout, ThreeDSecureLabelThemeData? label, ThreeDSecureTextFieldThemeData? textField, - ThreeDSecureSubmitButtonThemeData? submitButton}) { + ThreeDSecureButtonThemeData? submitButton, + ThreeDSecureButtonThemeData? cancelButton, + ThreeDSecureButtonThemeData? nextButton, + ThreeDSecureButtonThemeData? continueButton, + ThreeDSecureButtonThemeData? resendButton}) { return _ThreeDSecureConfigurationParams( navigationBar: navigationBar, timeout: timeout, label: label, textField: textField, submitButton: submitButton, + cancelButton: cancelButton, + nextButton: nextButton, + continueButton: continueButton, + resendButton: resendButton, ); } @@ -62,7 +70,23 @@ mixin _$ThreeDSecureConfigurationParams { throw _privateConstructorUsedError; /// Styling for the 3d secure confirmation button. - ThreeDSecureSubmitButtonThemeData? get submitButton => + ThreeDSecureButtonThemeData? get submitButton => + throw _privateConstructorUsedError; + + /// Styling for the 3d secure cancel button. + ThreeDSecureButtonThemeData? get cancelButton => + throw _privateConstructorUsedError; + + /// Styling for the 3d secure next button. + ThreeDSecureButtonThemeData? get nextButton => + throw _privateConstructorUsedError; + + /// Styling for the 3d secure continue button. + ThreeDSecureButtonThemeData? get continueButton => + throw _privateConstructorUsedError; + + /// Styling for the 3d secure resend button. + ThreeDSecureButtonThemeData? get resendButton => throw _privateConstructorUsedError; Map toJson() => throw _privateConstructorUsedError; @@ -82,12 +106,20 @@ abstract class $ThreeDSecureConfigurationParamsCopyWith<$Res> { int? timeout, ThreeDSecureLabelThemeData? label, ThreeDSecureTextFieldThemeData? textField, - ThreeDSecureSubmitButtonThemeData? submitButton}); + ThreeDSecureButtonThemeData? submitButton, + ThreeDSecureButtonThemeData? cancelButton, + ThreeDSecureButtonThemeData? nextButton, + ThreeDSecureButtonThemeData? continueButton, + ThreeDSecureButtonThemeData? resendButton}); $ThreeDSecureNavigationBarThemeDataCopyWith<$Res> get navigationBar; $ThreeDSecureLabelThemeDataCopyWith<$Res>? get label; $ThreeDSecureTextFieldThemeDataCopyWith<$Res>? get textField; - $ThreeDSecureSubmitButtonThemeDataCopyWith<$Res>? get submitButton; + $ThreeDSecureButtonThemeDataCopyWith<$Res>? get submitButton; + $ThreeDSecureButtonThemeDataCopyWith<$Res>? get cancelButton; + $ThreeDSecureButtonThemeDataCopyWith<$Res>? get nextButton; + $ThreeDSecureButtonThemeDataCopyWith<$Res>? get continueButton; + $ThreeDSecureButtonThemeDataCopyWith<$Res>? get resendButton; } /// @nodoc @@ -106,6 +138,10 @@ class _$ThreeDSecureConfigurationParamsCopyWithImpl<$Res> Object? label = freezed, Object? textField = freezed, Object? submitButton = freezed, + Object? cancelButton = freezed, + Object? nextButton = freezed, + Object? continueButton = freezed, + Object? resendButton = freezed, }) { return _then(_value.copyWith( navigationBar: navigationBar == freezed @@ -127,7 +163,23 @@ class _$ThreeDSecureConfigurationParamsCopyWithImpl<$Res> submitButton: submitButton == freezed ? _value.submitButton : submitButton // ignore: cast_nullable_to_non_nullable - as ThreeDSecureSubmitButtonThemeData?, + as ThreeDSecureButtonThemeData?, + cancelButton: cancelButton == freezed + ? _value.cancelButton + : cancelButton // ignore: cast_nullable_to_non_nullable + as ThreeDSecureButtonThemeData?, + nextButton: nextButton == freezed + ? _value.nextButton + : nextButton // ignore: cast_nullable_to_non_nullable + as ThreeDSecureButtonThemeData?, + continueButton: continueButton == freezed + ? _value.continueButton + : continueButton // ignore: cast_nullable_to_non_nullable + as ThreeDSecureButtonThemeData?, + resendButton: resendButton == freezed + ? _value.resendButton + : resendButton // ignore: cast_nullable_to_non_nullable + as ThreeDSecureButtonThemeData?, )); } @@ -163,16 +215,64 @@ class _$ThreeDSecureConfigurationParamsCopyWithImpl<$Res> } @override - $ThreeDSecureSubmitButtonThemeDataCopyWith<$Res>? get submitButton { + $ThreeDSecureButtonThemeDataCopyWith<$Res>? get submitButton { if (_value.submitButton == null) { return null; } - return $ThreeDSecureSubmitButtonThemeDataCopyWith<$Res>( - _value.submitButton!, (value) { + return $ThreeDSecureButtonThemeDataCopyWith<$Res>(_value.submitButton!, + (value) { return _then(_value.copyWith(submitButton: value)); }); } + + @override + $ThreeDSecureButtonThemeDataCopyWith<$Res>? get cancelButton { + if (_value.cancelButton == null) { + return null; + } + + return $ThreeDSecureButtonThemeDataCopyWith<$Res>(_value.cancelButton!, + (value) { + return _then(_value.copyWith(cancelButton: value)); + }); + } + + @override + $ThreeDSecureButtonThemeDataCopyWith<$Res>? get nextButton { + if (_value.nextButton == null) { + return null; + } + + return $ThreeDSecureButtonThemeDataCopyWith<$Res>(_value.nextButton!, + (value) { + return _then(_value.copyWith(nextButton: value)); + }); + } + + @override + $ThreeDSecureButtonThemeDataCopyWith<$Res>? get continueButton { + if (_value.continueButton == null) { + return null; + } + + return $ThreeDSecureButtonThemeDataCopyWith<$Res>(_value.continueButton!, + (value) { + return _then(_value.copyWith(continueButton: value)); + }); + } + + @override + $ThreeDSecureButtonThemeDataCopyWith<$Res>? get resendButton { + if (_value.resendButton == null) { + return null; + } + + return $ThreeDSecureButtonThemeDataCopyWith<$Res>(_value.resendButton!, + (value) { + return _then(_value.copyWith(resendButton: value)); + }); + } } /// @nodoc @@ -188,7 +288,11 @@ abstract class _$ThreeDSecureConfigurationParamsCopyWith<$Res> int? timeout, ThreeDSecureLabelThemeData? label, ThreeDSecureTextFieldThemeData? textField, - ThreeDSecureSubmitButtonThemeData? submitButton}); + ThreeDSecureButtonThemeData? submitButton, + ThreeDSecureButtonThemeData? cancelButton, + ThreeDSecureButtonThemeData? nextButton, + ThreeDSecureButtonThemeData? continueButton, + ThreeDSecureButtonThemeData? resendButton}); @override $ThreeDSecureNavigationBarThemeDataCopyWith<$Res> get navigationBar; @@ -197,7 +301,15 @@ abstract class _$ThreeDSecureConfigurationParamsCopyWith<$Res> @override $ThreeDSecureTextFieldThemeDataCopyWith<$Res>? get textField; @override - $ThreeDSecureSubmitButtonThemeDataCopyWith<$Res>? get submitButton; + $ThreeDSecureButtonThemeDataCopyWith<$Res>? get submitButton; + @override + $ThreeDSecureButtonThemeDataCopyWith<$Res>? get cancelButton; + @override + $ThreeDSecureButtonThemeDataCopyWith<$Res>? get nextButton; + @override + $ThreeDSecureButtonThemeDataCopyWith<$Res>? get continueButton; + @override + $ThreeDSecureButtonThemeDataCopyWith<$Res>? get resendButton; } /// @nodoc @@ -220,6 +332,10 @@ class __$ThreeDSecureConfigurationParamsCopyWithImpl<$Res> Object? label = freezed, Object? textField = freezed, Object? submitButton = freezed, + Object? cancelButton = freezed, + Object? nextButton = freezed, + Object? continueButton = freezed, + Object? resendButton = freezed, }) { return _then(_ThreeDSecureConfigurationParams( navigationBar: navigationBar == freezed @@ -241,14 +357,30 @@ class __$ThreeDSecureConfigurationParamsCopyWithImpl<$Res> submitButton: submitButton == freezed ? _value.submitButton : submitButton // ignore: cast_nullable_to_non_nullable - as ThreeDSecureSubmitButtonThemeData?, + as ThreeDSecureButtonThemeData?, + cancelButton: cancelButton == freezed + ? _value.cancelButton + : cancelButton // ignore: cast_nullable_to_non_nullable + as ThreeDSecureButtonThemeData?, + nextButton: nextButton == freezed + ? _value.nextButton + : nextButton // ignore: cast_nullable_to_non_nullable + as ThreeDSecureButtonThemeData?, + continueButton: continueButton == freezed + ? _value.continueButton + : continueButton // ignore: cast_nullable_to_non_nullable + as ThreeDSecureButtonThemeData?, + resendButton: resendButton == freezed + ? _value.resendButton + : resendButton // ignore: cast_nullable_to_non_nullable + as ThreeDSecureButtonThemeData?, )); } } -@JsonSerializable(explicitToJson: true) - /// @nodoc + +@JsonSerializable(explicitToJson: true) class _$_ThreeDSecureConfigurationParams implements _ThreeDSecureConfigurationParams { const _$_ThreeDSecureConfigurationParams( @@ -256,7 +388,11 @@ class _$_ThreeDSecureConfigurationParams this.timeout, this.label, this.textField, - this.submitButton}); + this.submitButton, + this.cancelButton, + this.nextButton, + this.continueButton, + this.resendButton}); factory _$_ThreeDSecureConfigurationParams.fromJson( Map json) => @@ -281,11 +417,27 @@ class _$_ThreeDSecureConfigurationParams @override /// Styling for the 3d secure confirmation button. - final ThreeDSecureSubmitButtonThemeData? submitButton; + final ThreeDSecureButtonThemeData? submitButton; + @override + + /// Styling for the 3d secure cancel button. + final ThreeDSecureButtonThemeData? cancelButton; + @override + + /// Styling for the 3d secure next button. + final ThreeDSecureButtonThemeData? nextButton; + @override + + /// Styling for the 3d secure continue button. + final ThreeDSecureButtonThemeData? continueButton; + @override + + /// Styling for the 3d secure resend button. + final ThreeDSecureButtonThemeData? resendButton; @override String toString() { - return 'ThreeDSecureConfigurationParams(navigationBar: $navigationBar, timeout: $timeout, label: $label, textField: $textField, submitButton: $submitButton)'; + return 'ThreeDSecureConfigurationParams(navigationBar: $navigationBar, timeout: $timeout, label: $label, textField: $textField, submitButton: $submitButton, cancelButton: $cancelButton, nextButton: $nextButton, continueButton: $continueButton, resendButton: $resendButton)'; } @override @@ -305,7 +457,19 @@ class _$_ThreeDSecureConfigurationParams .equals(other.textField, textField)) && (identical(other.submitButton, submitButton) || const DeepCollectionEquality() - .equals(other.submitButton, submitButton))); + .equals(other.submitButton, submitButton)) && + (identical(other.cancelButton, cancelButton) || + const DeepCollectionEquality() + .equals(other.cancelButton, cancelButton)) && + (identical(other.nextButton, nextButton) || + const DeepCollectionEquality() + .equals(other.nextButton, nextButton)) && + (identical(other.continueButton, continueButton) || + const DeepCollectionEquality() + .equals(other.continueButton, continueButton)) && + (identical(other.resendButton, resendButton) || + const DeepCollectionEquality() + .equals(other.resendButton, resendButton))); } @override @@ -315,7 +479,11 @@ class _$_ThreeDSecureConfigurationParams const DeepCollectionEquality().hash(timeout) ^ const DeepCollectionEquality().hash(label) ^ const DeepCollectionEquality().hash(textField) ^ - const DeepCollectionEquality().hash(submitButton); + const DeepCollectionEquality().hash(submitButton) ^ + const DeepCollectionEquality().hash(cancelButton) ^ + const DeepCollectionEquality().hash(nextButton) ^ + const DeepCollectionEquality().hash(continueButton) ^ + const DeepCollectionEquality().hash(resendButton); @JsonKey(ignore: true) @override @@ -336,7 +504,11 @@ abstract class _ThreeDSecureConfigurationParams int? timeout, ThreeDSecureLabelThemeData? label, ThreeDSecureTextFieldThemeData? textField, - ThreeDSecureSubmitButtonThemeData? submitButton}) = + ThreeDSecureButtonThemeData? submitButton, + ThreeDSecureButtonThemeData? cancelButton, + ThreeDSecureButtonThemeData? nextButton, + ThreeDSecureButtonThemeData? continueButton, + ThreeDSecureButtonThemeData? resendButton}) = _$_ThreeDSecureConfigurationParams; factory _ThreeDSecureConfigurationParams.fromJson(Map json) = @@ -363,7 +535,27 @@ abstract class _ThreeDSecureConfigurationParams @override /// Styling for the 3d secure confirmation button. - ThreeDSecureSubmitButtonThemeData? get submitButton => + ThreeDSecureButtonThemeData? get submitButton => + throw _privateConstructorUsedError; + @override + + /// Styling for the 3d secure cancel button. + ThreeDSecureButtonThemeData? get cancelButton => + throw _privateConstructorUsedError; + @override + + /// Styling for the 3d secure next button. + ThreeDSecureButtonThemeData? get nextButton => + throw _privateConstructorUsedError; + @override + + /// Styling for the 3d secure continue button. + ThreeDSecureButtonThemeData? get continueButton => + throw _privateConstructorUsedError; + @override + + /// Styling for the 3d secure resend button. + ThreeDSecureButtonThemeData? get resendButton => throw _privateConstructorUsedError; @override @JsonKey(ignore: true) @@ -563,9 +755,9 @@ class __$ThreeDSecureNavigationBarThemeDataCopyWithImpl<$Res> } } -@JsonSerializable(explicitToJson: true) - /// @nodoc + +@JsonSerializable(explicitToJson: true) class _$_ThreeDSecureNavigationBarThemeData implements _ThreeDSecureNavigationBarThemeData { const _$_ThreeDSecureNavigationBarThemeData( @@ -855,9 +1047,9 @@ class __$ThreeDSecureLabelThemeDataCopyWithImpl<$Res> } } -@JsonSerializable(explicitToJson: true) - /// @nodoc + +@JsonSerializable(explicitToJson: true) class _$_ThreeDSecureLabelThemeData implements _ThreeDSecureLabelThemeData { const _$_ThreeDSecureLabelThemeData( {this.headingTextColor, @@ -1131,9 +1323,9 @@ class __$ThreeDSecureTextFieldThemeDataCopyWithImpl<$Res> } } -@JsonSerializable(explicitToJson: true) - /// @nodoc + +@JsonSerializable(explicitToJson: true) class _$_ThreeDSecureTextFieldThemeData implements _ThreeDSecureTextFieldThemeData { const _$_ThreeDSecureTextFieldThemeData( @@ -1253,21 +1445,21 @@ abstract class _ThreeDSecureTextFieldThemeData get copyWith => throw _privateConstructorUsedError; } -ThreeDSecureSubmitButtonThemeData _$ThreeDSecureSubmitButtonThemeDataFromJson( +ThreeDSecureButtonThemeData _$ThreeDSecureButtonThemeDataFromJson( Map json) { - return _ThreeDSecureSubmitButtonThemeData.fromJson(json); + return _ThreeDSecureButtonThemeData.fromJson(json); } /// @nodoc -class _$ThreeDSecureSubmitButtonThemeDataTearOff { - const _$ThreeDSecureSubmitButtonThemeDataTearOff(); +class _$ThreeDSecureButtonThemeDataTearOff { + const _$ThreeDSecureButtonThemeDataTearOff(); - _ThreeDSecureSubmitButtonThemeData call( + _ThreeDSecureButtonThemeData call( {String? backgroundColor, double? cornerRadius, String? textColor, double? textFontSize}) { - return _ThreeDSecureSubmitButtonThemeData( + return _ThreeDSecureButtonThemeData( backgroundColor: backgroundColor, cornerRadius: cornerRadius, textColor: textColor, @@ -1275,17 +1467,16 @@ class _$ThreeDSecureSubmitButtonThemeDataTearOff { ); } - ThreeDSecureSubmitButtonThemeData fromJson(Map json) { - return ThreeDSecureSubmitButtonThemeData.fromJson(json); + ThreeDSecureButtonThemeData fromJson(Map json) { + return ThreeDSecureButtonThemeData.fromJson(json); } } /// @nodoc -const $ThreeDSecureSubmitButtonThemeData = - _$ThreeDSecureSubmitButtonThemeDataTearOff(); +const $ThreeDSecureButtonThemeData = _$ThreeDSecureButtonThemeDataTearOff(); /// @nodoc -mixin _$ThreeDSecureSubmitButtonThemeData { +mixin _$ThreeDSecureButtonThemeData { /// Color in hex for button background String? get backgroundColor => throw _privateConstructorUsedError; @@ -1300,16 +1491,16 @@ mixin _$ThreeDSecureSubmitButtonThemeData { Map toJson() => throw _privateConstructorUsedError; @JsonKey(ignore: true) - $ThreeDSecureSubmitButtonThemeDataCopyWith + $ThreeDSecureButtonThemeDataCopyWith get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class $ThreeDSecureSubmitButtonThemeDataCopyWith<$Res> { - factory $ThreeDSecureSubmitButtonThemeDataCopyWith( - ThreeDSecureSubmitButtonThemeData value, - $Res Function(ThreeDSecureSubmitButtonThemeData) then) = - _$ThreeDSecureSubmitButtonThemeDataCopyWithImpl<$Res>; +abstract class $ThreeDSecureButtonThemeDataCopyWith<$Res> { + factory $ThreeDSecureButtonThemeDataCopyWith( + ThreeDSecureButtonThemeData value, + $Res Function(ThreeDSecureButtonThemeData) then) = + _$ThreeDSecureButtonThemeDataCopyWithImpl<$Res>; $Res call( {String? backgroundColor, double? cornerRadius, @@ -1318,13 +1509,13 @@ abstract class $ThreeDSecureSubmitButtonThemeDataCopyWith<$Res> { } /// @nodoc -class _$ThreeDSecureSubmitButtonThemeDataCopyWithImpl<$Res> - implements $ThreeDSecureSubmitButtonThemeDataCopyWith<$Res> { - _$ThreeDSecureSubmitButtonThemeDataCopyWithImpl(this._value, this._then); +class _$ThreeDSecureButtonThemeDataCopyWithImpl<$Res> + implements $ThreeDSecureButtonThemeDataCopyWith<$Res> { + _$ThreeDSecureButtonThemeDataCopyWithImpl(this._value, this._then); - final ThreeDSecureSubmitButtonThemeData _value; + final ThreeDSecureButtonThemeData _value; // ignore: unused_field - final $Res Function(ThreeDSecureSubmitButtonThemeData) _then; + final $Res Function(ThreeDSecureButtonThemeData) _then; @override $Res call({ @@ -1355,12 +1546,12 @@ class _$ThreeDSecureSubmitButtonThemeDataCopyWithImpl<$Res> } /// @nodoc -abstract class _$ThreeDSecureSubmitButtonThemeDataCopyWith<$Res> - implements $ThreeDSecureSubmitButtonThemeDataCopyWith<$Res> { - factory _$ThreeDSecureSubmitButtonThemeDataCopyWith( - _ThreeDSecureSubmitButtonThemeData value, - $Res Function(_ThreeDSecureSubmitButtonThemeData) then) = - __$ThreeDSecureSubmitButtonThemeDataCopyWithImpl<$Res>; +abstract class _$ThreeDSecureButtonThemeDataCopyWith<$Res> + implements $ThreeDSecureButtonThemeDataCopyWith<$Res> { + factory _$ThreeDSecureButtonThemeDataCopyWith( + _ThreeDSecureButtonThemeData value, + $Res Function(_ThreeDSecureButtonThemeData) then) = + __$ThreeDSecureButtonThemeDataCopyWithImpl<$Res>; @override $Res call( {String? backgroundColor, @@ -1370,17 +1561,17 @@ abstract class _$ThreeDSecureSubmitButtonThemeDataCopyWith<$Res> } /// @nodoc -class __$ThreeDSecureSubmitButtonThemeDataCopyWithImpl<$Res> - extends _$ThreeDSecureSubmitButtonThemeDataCopyWithImpl<$Res> - implements _$ThreeDSecureSubmitButtonThemeDataCopyWith<$Res> { - __$ThreeDSecureSubmitButtonThemeDataCopyWithImpl( - _ThreeDSecureSubmitButtonThemeData _value, - $Res Function(_ThreeDSecureSubmitButtonThemeData) _then) - : super(_value, (v) => _then(v as _ThreeDSecureSubmitButtonThemeData)); +class __$ThreeDSecureButtonThemeDataCopyWithImpl<$Res> + extends _$ThreeDSecureButtonThemeDataCopyWithImpl<$Res> + implements _$ThreeDSecureButtonThemeDataCopyWith<$Res> { + __$ThreeDSecureButtonThemeDataCopyWithImpl( + _ThreeDSecureButtonThemeData _value, + $Res Function(_ThreeDSecureButtonThemeData) _then) + : super(_value, (v) => _then(v as _ThreeDSecureButtonThemeData)); @override - _ThreeDSecureSubmitButtonThemeData get _value => - super._value as _ThreeDSecureSubmitButtonThemeData; + _ThreeDSecureButtonThemeData get _value => + super._value as _ThreeDSecureButtonThemeData; @override $Res call({ @@ -1389,7 +1580,7 @@ class __$ThreeDSecureSubmitButtonThemeDataCopyWithImpl<$Res> Object? textColor = freezed, Object? textFontSize = freezed, }) { - return _then(_ThreeDSecureSubmitButtonThemeData( + return _then(_ThreeDSecureButtonThemeData( backgroundColor: backgroundColor == freezed ? _value.backgroundColor : backgroundColor // ignore: cast_nullable_to_non_nullable @@ -1410,20 +1601,18 @@ class __$ThreeDSecureSubmitButtonThemeDataCopyWithImpl<$Res> } } -@JsonSerializable(explicitToJson: true) - /// @nodoc -class _$_ThreeDSecureSubmitButtonThemeData - implements _ThreeDSecureSubmitButtonThemeData { - const _$_ThreeDSecureSubmitButtonThemeData( + +@JsonSerializable(explicitToJson: true) +class _$_ThreeDSecureButtonThemeData implements _ThreeDSecureButtonThemeData { + const _$_ThreeDSecureButtonThemeData( {this.backgroundColor, this.cornerRadius, this.textColor, this.textFontSize}); - factory _$_ThreeDSecureSubmitButtonThemeData.fromJson( - Map json) => - _$_$_ThreeDSecureSubmitButtonThemeDataFromJson(json); + factory _$_ThreeDSecureButtonThemeData.fromJson(Map json) => + _$_$_ThreeDSecureButtonThemeDataFromJson(json); @override @@ -1444,13 +1633,13 @@ class _$_ThreeDSecureSubmitButtonThemeData @override String toString() { - return 'ThreeDSecureSubmitButtonThemeData(backgroundColor: $backgroundColor, cornerRadius: $cornerRadius, textColor: $textColor, textFontSize: $textFontSize)'; + return 'ThreeDSecureButtonThemeData(backgroundColor: $backgroundColor, cornerRadius: $cornerRadius, textColor: $textColor, textFontSize: $textFontSize)'; } @override bool operator ==(dynamic other) { return identical(this, other) || - (other is _ThreeDSecureSubmitButtonThemeData && + (other is _ThreeDSecureButtonThemeData && (identical(other.backgroundColor, backgroundColor) || const DeepCollectionEquality() .equals(other.backgroundColor, backgroundColor)) && @@ -1475,28 +1664,26 @@ class _$_ThreeDSecureSubmitButtonThemeData @JsonKey(ignore: true) @override - _$ThreeDSecureSubmitButtonThemeDataCopyWith< - _ThreeDSecureSubmitButtonThemeData> - get copyWith => __$ThreeDSecureSubmitButtonThemeDataCopyWithImpl< - _ThreeDSecureSubmitButtonThemeData>(this, _$identity); + _$ThreeDSecureButtonThemeDataCopyWith<_ThreeDSecureButtonThemeData> + get copyWith => __$ThreeDSecureButtonThemeDataCopyWithImpl< + _ThreeDSecureButtonThemeData>(this, _$identity); @override Map toJson() { - return _$_$_ThreeDSecureSubmitButtonThemeDataToJson(this); + return _$_$_ThreeDSecureButtonThemeDataToJson(this); } } -abstract class _ThreeDSecureSubmitButtonThemeData - implements ThreeDSecureSubmitButtonThemeData { - const factory _ThreeDSecureSubmitButtonThemeData( +abstract class _ThreeDSecureButtonThemeData + implements ThreeDSecureButtonThemeData { + const factory _ThreeDSecureButtonThemeData( {String? backgroundColor, double? cornerRadius, String? textColor, - double? textFontSize}) = _$_ThreeDSecureSubmitButtonThemeData; + double? textFontSize}) = _$_ThreeDSecureButtonThemeData; - factory _ThreeDSecureSubmitButtonThemeData.fromJson( - Map json) = - _$_ThreeDSecureSubmitButtonThemeData.fromJson; + factory _ThreeDSecureButtonThemeData.fromJson(Map json) = + _$_ThreeDSecureButtonThemeData.fromJson; @override @@ -1516,7 +1703,6 @@ abstract class _ThreeDSecureSubmitButtonThemeData double? get textFontSize => throw _privateConstructorUsedError; @override @JsonKey(ignore: true) - _$ThreeDSecureSubmitButtonThemeDataCopyWith< - _ThreeDSecureSubmitButtonThemeData> + _$ThreeDSecureButtonThemeDataCopyWith<_ThreeDSecureButtonThemeData> get copyWith => throw _privateConstructorUsedError; } diff --git a/packages/stripe_platform_interface/lib/src/models/three_d_secure.g.dart b/packages/stripe_platform_interface/lib/src/models/three_d_secure.g.dart index 7ea5f72..0586a13 100644 --- a/packages/stripe_platform_interface/lib/src/models/three_d_secure.g.dart +++ b/packages/stripe_platform_interface/lib/src/models/three_d_secure.g.dart @@ -22,8 +22,24 @@ _$_ThreeDSecureConfigurationParams _$_$_ThreeDSecureConfigurationParamsFromJson( json['textField'] as Map), submitButton: json['submitButton'] == null ? null - : ThreeDSecureSubmitButtonThemeData.fromJson( + : ThreeDSecureButtonThemeData.fromJson( json['submitButton'] as Map), + cancelButton: json['cancelButton'] == null + ? null + : ThreeDSecureButtonThemeData.fromJson( + json['cancelButton'] as Map), + nextButton: json['nextButton'] == null + ? null + : ThreeDSecureButtonThemeData.fromJson( + json['nextButton'] as Map), + continueButton: json['continueButton'] == null + ? null + : ThreeDSecureButtonThemeData.fromJson( + json['continueButton'] as Map), + resendButton: json['resendButton'] == null + ? null + : ThreeDSecureButtonThemeData.fromJson( + json['resendButton'] as Map), ); } @@ -35,6 +51,10 @@ Map _$_$_ThreeDSecureConfigurationParamsToJson( 'label': instance.label?.toJson(), 'textField': instance.textField?.toJson(), 'submitButton': instance.submitButton?.toJson(), + 'cancelButton': instance.cancelButton?.toJson(), + 'nextButton': instance.nextButton?.toJson(), + 'continueButton': instance.continueButton?.toJson(), + 'resendButton': instance.resendButton?.toJson(), }; _$_ThreeDSecureNavigationBarThemeData @@ -100,9 +120,9 @@ Map _$_$_ThreeDSecureTextFieldThemeDataToJson( 'textFontSize': instance.textFontSize, }; -_$_ThreeDSecureSubmitButtonThemeData - _$_$_ThreeDSecureSubmitButtonThemeDataFromJson(Map json) { - return _$_ThreeDSecureSubmitButtonThemeData( +_$_ThreeDSecureButtonThemeData _$_$_ThreeDSecureButtonThemeDataFromJson( + Map json) { + return _$_ThreeDSecureButtonThemeData( backgroundColor: json['backgroundColor'] as String?, cornerRadius: (json['cornerRadius'] as num?)?.toDouble(), textColor: json['textColor'] as String?, @@ -110,8 +130,8 @@ _$_ThreeDSecureSubmitButtonThemeData ); } -Map _$_$_ThreeDSecureSubmitButtonThemeDataToJson( - _$_ThreeDSecureSubmitButtonThemeData instance) => +Map _$_$_ThreeDSecureButtonThemeDataToJson( + _$_ThreeDSecureButtonThemeData instance) => { 'backgroundColor': instance.backgroundColor, 'cornerRadius': instance.cornerRadius, diff --git a/packages/stripe_platform_interface/lib/src/stripe_platform_interface.dart b/packages/stripe_platform_interface/lib/src/stripe_platform_interface.dart index cdabd60..6bfd96a 100644 --- a/packages/stripe_platform_interface/lib/src/stripe_platform_interface.dart +++ b/packages/stripe_platform_interface/lib/src/stripe_platform_interface.dart @@ -2,6 +2,7 @@ import 'package:plugin_platform_interface/plugin_platform_interface.dart'; import 'method_channel_stripe.dart'; import 'models/apple_pay.dart'; +import 'models/create_token_data.dart'; import 'models/payment_intents.dart'; import 'models/payment_methods.dart'; import 'models/payment_sheet.dart'; @@ -57,6 +58,11 @@ abstract class StripePlatform extends PlatformInterface { Future presentApplePay(ApplePayPresentParams params); Future confirmApplePayPayment(String clientSecret); + + /// Creates a token for card details. + /// + /// Note this method is legacy and it is advised to use [PaymentIntent]. + Future createToken(CreateTokenParams params); Future confirmSetupIntent( String setupIntentClientSecret, PaymentMethodParams data, [Map options = const {}]); diff --git a/packages/stripe_platform_interface/lib/stripe_platform_interface.dart b/packages/stripe_platform_interface/lib/stripe_platform_interface.dart index bb902b7..8d8c842 100644 --- a/packages/stripe_platform_interface/lib/stripe_platform_interface.dart +++ b/packages/stripe_platform_interface/lib/stripe_platform_interface.dart @@ -4,6 +4,7 @@ export 'src/models/address.dart'; export 'src/models/app_info.dart'; export 'src/models/apple_pay.dart'; export 'src/models/card_field_input.dart'; +export 'src/models/create_token_data.dart'; export 'src/models/errors.dart'; export 'src/models/payment_intents.dart'; export 'src/models/payment_methods.dart'; diff --git a/packages/stripe_platform_interface/pubspec.yaml b/packages/stripe_platform_interface/pubspec.yaml index cd2da3d..28d3869 100644 --- a/packages/stripe_platform_interface/pubspec.yaml +++ b/packages/stripe_platform_interface/pubspec.yaml @@ -11,15 +11,15 @@ environment: dependencies: flutter: sdk: flutter - freezed_annotation: ^0.14.1 + freezed_annotation: ^0.14.2 json_annotation: ^4.0.1 meta: ^1.3.0 plugin_platform_interface: ^2.0.0 dev_dependencies: - build_runner: ^1.11.5 + build_runner: ^2.0.4 flutter_test: sdk: flutter freezed: ^0.14.1+2 - json_serializable: ^4.1.0 - pedantic: ^1.11.0 \ No newline at end of file + json_serializable: ^4.1.3 + flutter_lints: ^1.0.3 \ No newline at end of file diff --git a/packages/stripe_platform_interface/test/method_channel_mock.dart b/packages/stripe_platform_interface/test/method_channel_mock.dart index 53aec95..c0fb89b 100644 --- a/packages/stripe_platform_interface/test/method_channel_mock.dart +++ b/packages/stripe_platform_interface/test/method_channel_mock.dart @@ -10,7 +10,7 @@ class MethodChannelMock { required this.method, this.delay = Duration.zero, this.result, - }) : methodChannel = MethodChannel(channelName, JSONMethodCodec()) { + }) : methodChannel = MethodChannel(channelName, const JSONMethodCodec()) { methodChannel.setMockMethodCallHandler(_handler); } diff --git a/packages/stripe_platform_interface/test/method_channel_stripe_test.dart b/packages/stripe_platform_interface/test/method_channel_stripe_test.dart index 1ffceb0..041df88 100644 --- a/packages/stripe_platform_interface/test/method_channel_stripe_test.dart +++ b/packages/stripe_platform_interface/test/method_channel_stripe_test.dart @@ -43,10 +43,13 @@ void main() { methodChannel: MethodChannelMock( channelName: methodChannelName, method: 'createPaymentMethod', - result: PaymentMethodTestInstance.create('id1').jsonMap(), + result: { + "paymentMethod": PaymentMethodTestInstance.create('id1').jsonMap() + }, ).methodChannel, ); - result = await sut.createPaymentMethod(PaymentMethodParams.card()); + result = + await sut.createPaymentMethod(const PaymentMethodParams.card()); }); test('It returns payment method', () { @@ -85,11 +88,14 @@ void main() { methodChannel: MethodChannelMock( channelName: methodChannelName, method: 'confirmPaymentMethod', - result: PaymentIntentTestInstance.create('id1').toJsonMap(), + result: { + "paymentIntent": + PaymentIntentTestInstance.create('id1').toJsonMap() + }, ).methodChannel, ); result = await sut.confirmPaymentMethod( - 'secret', PaymentMethodParams.card()); + 'secret', const PaymentMethodParams.card()); }); test('It returns payment intent', () { @@ -113,7 +119,7 @@ void main() { expect( () async => await sut.confirmPaymentMethod( 'secret', - PaymentMethodParams.card(), + const PaymentMethodParams.card(), ), throwsA(const TypeMatcher>()), ); @@ -130,12 +136,15 @@ void main() { methodChannel: MethodChannelMock( channelName: methodChannelName, method: 'confirmSetupIntent', - result: SetupIntentTestInstance.create('id1').toJsonMap('id1'), + result: { + "setupIntent": + SetupIntentTestInstance.create('id1').toJsonMap('id1') + }, ).methodChannel, ); result = await sut.confirmSetupIntent( 'setupIntentClientSecret', - PaymentMethodParams.card(), + const PaymentMethodParams.card(), ); }); @@ -174,7 +183,10 @@ void main() { methodChannel: MethodChannelMock( channelName: methodChannelName, method: 'handleCardAction', - result: PaymentIntentTestInstance.create('id1').toJsonMap(), + result: { + "paymentIntent": + PaymentIntentTestInstance.create('id1').toJsonMap() + }, ).methodChannel, ); result = await sut.handleCardAction('paymentIntentId'); @@ -240,7 +252,7 @@ void main() { ); await sut .presentApplePay( - ApplePayPresentParams( + const ApplePayPresentParams( cartItems: [], country: 'country', currency: 'currency', @@ -269,7 +281,7 @@ void main() { test('It completes operation', () { expect( () => sut.presentApplePay( - ApplePayPresentParams( + const ApplePayPresentParams( cartItems: [], country: 'country', currency: 'currency', @@ -290,7 +302,10 @@ void main() { methodChannel: MethodChannelMock( channelName: methodChannelName, method: 'retrievePaymentIntent', - result: PaymentIntentTestInstance.create('id1').toJsonMap(), + result: { + "paymentIntent": + PaymentIntentTestInstance.create('id1').toJsonMap() + }, ).methodChannel, ); result = await sut.retrievePaymentIntent('clientSecret'); @@ -332,7 +347,7 @@ void main() { ); await sut .initPaymentSheet( - SetupPaymentSheetParameters( + const SetupPaymentSheetParameters( paymentIntentClientSecret: 'paymentIntentClientSecret'), ) .then((_) => completer.complete()); @@ -356,8 +371,8 @@ void main() { ).methodChannel, ); await sut - .presentPaymentSheet( - PresentPaymentSheetParameters(clientSecret: 'clientSecret')) + .presentPaymentSheet(const PresentPaymentSheetParameters( + clientSecret: 'clientSecret')) .then((_) => completer.complete()); }); @@ -386,5 +401,53 @@ void main() { expect(completer.isCompleted, true); }); }); + + group('create token', () { + late CreateTokenParams params; + late TokenData result; + + setUp(() { + params = const CreateTokenParams(); + }); + group('When create token succeeds', () { + setUp(() async { + sut = MethodChannelStripe( + platformIsIos: false, + methodChannel: MethodChannelMock( + channelName: methodChannelName, + method: 'createToken', + result: TokenDataTestInstance.create('tokenId').jsonMap()) + .methodChannel, + ); + + result = await sut.createToken(params); + }); + + test('It returns correct data', () { + expect(result, TokenDataTestInstance.create('tokenId')); + }); + }); + + group('When create token fails', () { + setUp(() async { + sut = MethodChannelStripe( + platformIsIos: false, + methodChannel: MethodChannelMock( + channelName: methodChannelName, + method: 'createToken', + result: Exception('whoops')) + .methodChannel, + ); + }); + + test('It returns correct data', () async { + expect( + () async => await sut.createToken(params), + throwsA( + const TypeMatcher>(), + )); + }); + }); + }); }); } diff --git a/packages/stripe_platform_interface/test/test_data.dart b/packages/stripe_platform_interface/test/test_data.dart index aef45e5..da53822 100644 --- a/packages/stripe_platform_interface/test/test_data.dart +++ b/packages/stripe_platform_interface/test/test_data.dart @@ -1,4 +1,5 @@ import 'package:flutter/foundation.dart'; +import 'package:stripe_platform_interface/src/models/create_token_data.dart'; import 'package:stripe_platform_interface/src/models/payment_intents.dart'; import 'package:stripe_platform_interface/src/models/payment_methods.dart'; import 'package:stripe_platform_interface/src/models/setup_intent.dart'; @@ -8,15 +9,15 @@ extension PaymentMethodTestInstance on PaymentMethod { id: id, livemode: false, type: 'paymentType', - billingDetails: BillingDetails(), - card: Card(), - sepaDebit: SepaDebit(), - bacsDebit: BacsDebit(), - auBecsDebit: AuBecsDebit(), - sofort: Sofort(), - ideal: Ideal(), - fpx: Fpx(), - upi: Upi(), + billingDetails: const BillingDetails(), + card: const Card(), + sepaDebit: const SepaDebit(), + bacsDebit: const BacsDebit(), + auBecsDebit: const AuBecsDebit(), + sofort: const Sofort(), + ideal: const Ideal(), + fpx: const Fpx(), + upi: const Upi(), ); Map jsonMap() => { @@ -68,7 +69,7 @@ extension PaymentIntentTestInstance on PaymentIntent { static PaymentIntent create(String id) => PaymentIntent( id: id, amount: 100, - created: 10, + created: '10', currency: 'Usd', status: PaymentIntentsStatus.Succeeded, clientSecret: 'clientSecret', @@ -120,3 +121,28 @@ extension SetupIntentTestInstance on SetupIntent { 'lastSetupError': lastSetupError, }; } + +extension TokenDataTestInstance on TokenData { + static TokenData create(String id) => TokenData( + id: id, + createdDateTime: 'createdDateTime', + type: TokenType.Card, + livemode: false, + card: const CardData(brand: 'Visa'), + ); + + Map jsonMap() => { + 'id': id, + 'livemode': livemode, + 'type': describeEnum(type), + 'created': createdDateTime, + 'card': { + 'brand': card?.brand, + 'country': card?.country, + 'expYear': card?.expYear, + 'expMonth': card?.expMonth, + 'funding': card?.funding, + 'last4': card?.last4, + }, + }; +}