diff --git a/packages/stripe/lib/src/stripe.dart b/packages/stripe/lib/src/stripe.dart index dea363011..a1670b5cd 100644 --- a/packages/stripe/lib/src/stripe.dart +++ b/packages/stripe/lib/src/stripe.dart @@ -619,6 +619,29 @@ class Stripe { } } + /// Initializes the customer sheet with the provided [parameters]. + Future initCustomerSheet( + CustomerSheetInitParams params) async { + await _awaitForSettings(); + return _platform.initCustomerSheet(params); + } + + /// Display the customersheet sheet. With the provided [options]. + Future presentCustomerSheet({ + CustomerSheetPresentParams? options, + }) async { + await _awaitForSettings(); + return _platform.presentCustomerSheet(options: options); + } + + /// Retrieve the customer sheet payment option selection. + Future + retrieveCustomerSheetPaymentOptionSelection() async { + await _awaitForSettings(); + + return _platform.retrieveCustomerSheetPaymentOptionSelection(); + } + FutureOr _awaitForSettings() { if (_needsSettings) { _settingsFuture = applySettings(); 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 42141813d..69c3789fe 100644 --- a/packages/stripe_platform_interface/lib/src/method_channel_stripe.dart +++ b/packages/stripe_platform_interface/lib/src/method_channel_stripe.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'package:flutter/services.dart'; import 'package:stripe_platform_interface/src/models/ach_params.dart'; import 'package:stripe_platform_interface/src/models/create_token_data.dart'; +import 'package:stripe_platform_interface/src/models/customer_sheet.dart'; import 'package:stripe_platform_interface/src/models/financial_connections.dart'; import 'package:stripe_platform_interface/src/models/google_pay.dart'; import 'package:stripe_platform_interface/src/models/intent_creation_callback_params.dart'; @@ -246,6 +247,44 @@ class MethodChannelStripe extends StripePlatform { } } + @override + Future initCustomerSheet( + CustomerSheetInitParams params) async { + final result = await _methodChannel.invokeMethod( + 'initCustomerSheet', + {'params': params.toJson()}, + ); + + if (result is List) { + return null; + } else { + return _parseCustomerSheetResult(result); + } + } + + @override + Future presentCustomerSheet({ + CustomerSheetPresentParams? options, + }) async { + final result = await _methodChannel.invokeMethod( + 'presentCustomerSheet', + {'params': {}, 'options': options?.toJson() ?? {}}, + ); + + return _parseCustomerSheetResult(result); + } + + @override + Future + retrieveCustomerSheetPaymentOptionSelection() async { + final result = await _methodChannel.invokeMethod( + 'retrieveCustomerSheetPaymentOptionSelection', + {}, + ); + + return _parseCustomerSheetResult(result); + } + @override Future createToken(CreateTokenParams params) async { final invokeParams = params.map( @@ -305,6 +344,33 @@ class MethodChannelStripe extends StripePlatform { } } + CustomerSheetResult? _parseCustomerSheetResult(Map? result) { + if (result != null) { + if (result.isEmpty) { + return null; + } else if (result['paymentOption'] != null) { + return CustomerSheetResult.fromJson(result['paymentOption']); + } else { + if (result['error'] != null) { + //workaround for tojson in sumtypes + result['runtimeType'] = 'failed'; + throw StripeException.fromJson(result); + } else { + throw StripeError( + message: + 'Unknown result this is likely a problem in the plugin $result', + code: CustomerSheetError.unknown, + ); + } + } + } else { + throw const StripeError( + message: 'Result should not be null', + code: CustomerSheetError.unknown, + ); + } + } + @override Future createGooglePayPaymentMethod( CreateGooglePayPaymentParams params) async { diff --git a/packages/stripe_platform_interface/lib/src/models/customer_sheet.dart b/packages/stripe_platform_interface/lib/src/models/customer_sheet.dart new file mode 100644 index 000000000..079240a45 --- /dev/null +++ b/packages/stripe_platform_interface/lib/src/models/customer_sheet.dart @@ -0,0 +1,116 @@ +import 'package:flutter/material.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:stripe_platform_interface/stripe_platform_interface.dart'; + +part 'customer_sheet.freezed.dart'; +part 'customer_sheet.g.dart'; + +/// Parameters to setup a Customer sheet +/// +/// For more info see https://stripe.com/docs/elements/customer-sheet?platform=react-native +@freezed +class CustomerSheetInitParams with _$CustomerSheetInitParams { + @JsonSerializable(explicitToJson: true) + const factory CustomerSheetInitParams({ + /// Color styling used for the Customersheet UI + @JsonKey(toJson: UserInterfaceStyleKey.toJson) ThemeMode? style, + + /// Appearance of the customersheet. + /// + /// When no appearance defined it will fallback to [style] or Stripe default. + PaymentSheetAppearance? appearance, + + /// Optional but recommended for cards, required for other payment methods. The SetupIntent client secret that will be used to confirm a new payment method. If this is missing, you will only be able to add cards without authentication steps. + String? setupIntentClientSecret, + + /// The identifier of the Stripe Customer object. See https://stripe.com/docs/api/customers/object#customer_object-id + required String customerId, + + /// A short-lived token that allows the SDK to access a Customer's payment methods. + required String customerEphemeralKeySecret, + + /// Your customer-facing business name. The default value is the name of your app. + String? merchantDisplayName, + + /// Optional configuration for setting the header text of the Payment Method selection screen + String? headerTextForSelectionScreen, + + /// CustomerSheet pre-populates fields with the values provided. If `billingDetailsCollectionConfiguration.attachDefaultsToPaymentMethod` is `true`, these values will be attached to the payment method even if they are not collected by the CustomerSheet UI. + BillingDetails? defaultBillingDetails, + + /// Describes how billing details should be collected. All values default to `AUTOMATIC`. If `NEVER` is used for a required field for the Payment Method, you must provide an appropriate value as part of `defaultBillingDetails`. + BillingDetailsCollectionConfiguration? + billingDetailsCollectionConfiguration, + + /// URL that redirects back to your app that CustomerSheet can use to auto-dismiss web views used for additional authentication, e.g. 3DS2 + String? returnURL, + + /// Optional configuration to display a custom message when a saved payment method is removed. iOS only. + String? removeSavedPaymentMethodMessage, + + /// Whether to show Apple Pay as an option. Defaults to `false`. + @Default(true) bool applePayEnabled, + + /// Whether to show Google Pay as an option. Defaults to `false`. + @Default(true) bool googlePayEnabled, + }) = _CustomerSheetInitParams; + + factory CustomerSheetInitParams.fromJson(Map json) => + _$CustomerSheetInitParamsFromJson(json); +} + +@freezed +class CustomerSheetPresentParams with _$CustomerSheetPresentParams { + @JsonSerializable(explicitToJson: true) + const factory CustomerSheetPresentParams({ + /// Controls how the modal is presented (after animation). iOS only. Defaults to `popover`. + CustomerSheetPresentationStyle? presentationStyle, + + /// Controls how the modal animates. iOS only. + CustomerSheetAnimationStyle? animationStyle, + + /// Time (in milliseconds) before the Customer Sheet will automatically dismiss. + int? timeout, + }) = _CustomerSheetPresentParams; + + factory CustomerSheetPresentParams.fromJson(Map json) => + _$CustomerSheetPresentParamsFromJson(json); +} + +@freezed +class CustomerSheetResult with _$CustomerSheetResult { + @JsonSerializable(explicitToJson: true) + const factory CustomerSheetResult({ + /// The users selected payment option, if one exists. + PaymentSheetPaymentOption? paymentOption, + + /// The Stripe PaymentMethod associated with the paymentOption, if it exists. + PaymentMethod? paymentMethod, + + /// The error that occurred + StripeError? error, + }) = _CustomerSheetResult; + + factory CustomerSheetResult.fromJson(Map json) => + _$CustomerSheetResultFromJson(json); +} + +enum CustomerSheetAnimationStyle { + flip, + curl, + slide, + dissolve, +} + +enum CustomerSheetPresentationStyle { + fullscreen, + popover, +} + +/* + /** Optional override. It is generally recommended to rely on the default behavior, but- provide a CustomerAdapter here if + * you would prefer retrieving and updating your Stripe customer object via your own backend instead. + * WARNING: When implementing your own CustomerAdapter, ensure your application complies with all applicable laws and regulations, including data privacy and consumer protection. + */ + customerAdapter?: CustomerAdapter; +*/ diff --git a/packages/stripe_platform_interface/lib/src/models/customer_sheet.freezed.dart b/packages/stripe_platform_interface/lib/src/models/customer_sheet.freezed.dart new file mode 100644 index 000000000..ff0bdc468 --- /dev/null +++ b/packages/stripe_platform_interface/lib/src/models/customer_sheet.freezed.dart @@ -0,0 +1,1044 @@ +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// 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, invalid_annotation_target, unnecessary_question_mark + +part of 'customer_sheet.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 information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); + +CustomerSheetInitParams _$CustomerSheetInitParamsFromJson( + Map json) { + return _CustomerSheetInitParams.fromJson(json); +} + +/// @nodoc +mixin _$CustomerSheetInitParams { + /// Color styling used for the Customersheet UI + @JsonKey(toJson: UserInterfaceStyleKey.toJson) + ThemeMode? get style => throw _privateConstructorUsedError; + + /// Appearance of the customersheet. + /// + /// When no appearance defined it will fallback to [style] or Stripe default. + PaymentSheetAppearance? get appearance => throw _privateConstructorUsedError; + + /// Optional but recommended for cards, required for other payment methods. The SetupIntent client secret that will be used to confirm a new payment method. If this is missing, you will only be able to add cards without authentication steps. + String? get setupIntentClientSecret => throw _privateConstructorUsedError; + + /// The identifier of the Stripe Customer object. See https://stripe.com/docs/api/customers/object#customer_object-id + String get customerId => throw _privateConstructorUsedError; + + /// A short-lived token that allows the SDK to access a Customer's payment methods. + String get customerEphemeralKeySecret => throw _privateConstructorUsedError; + + /// Your customer-facing business name. The default value is the name of your app. + String? get merchantDisplayName => throw _privateConstructorUsedError; + + /// Optional configuration for setting the header text of the Payment Method selection screen + String? get headerTextForSelectionScreen => + throw _privateConstructorUsedError; + + /// CustomerSheet pre-populates fields with the values provided. If `billingDetailsCollectionConfiguration.attachDefaultsToPaymentMethod` is `true`, these values will be attached to the payment method even if they are not collected by the CustomerSheet UI. + BillingDetails? get defaultBillingDetails => + throw _privateConstructorUsedError; + + /// Describes how billing details should be collected. All values default to `AUTOMATIC`. If `NEVER` is used for a required field for the Payment Method, you must provide an appropriate value as part of `defaultBillingDetails`. + BillingDetailsCollectionConfiguration? + get billingDetailsCollectionConfiguration => + throw _privateConstructorUsedError; + + /// URL that redirects back to your app that CustomerSheet can use to auto-dismiss web views used for additional authentication, e.g. 3DS2 + String? get returnURL => throw _privateConstructorUsedError; + + /// Optional configuration to display a custom message when a saved payment method is removed. iOS only. + String? get removeSavedPaymentMethodMessage => + throw _privateConstructorUsedError; + + /// Whether to show Apple Pay as an option. Defaults to `false`. + bool get applePayEnabled => throw _privateConstructorUsedError; + + /// Whether to show Google Pay as an option. Defaults to `false`. + bool get googlePayEnabled => throw _privateConstructorUsedError; + + Map toJson() => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + $CustomerSheetInitParamsCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $CustomerSheetInitParamsCopyWith<$Res> { + factory $CustomerSheetInitParamsCopyWith(CustomerSheetInitParams value, + $Res Function(CustomerSheetInitParams) then) = + _$CustomerSheetInitParamsCopyWithImpl<$Res, CustomerSheetInitParams>; + @useResult + $Res call( + {@JsonKey(toJson: UserInterfaceStyleKey.toJson) ThemeMode? style, + PaymentSheetAppearance? appearance, + String? setupIntentClientSecret, + String customerId, + String customerEphemeralKeySecret, + String? merchantDisplayName, + String? headerTextForSelectionScreen, + BillingDetails? defaultBillingDetails, + BillingDetailsCollectionConfiguration? + billingDetailsCollectionConfiguration, + String? returnURL, + String? removeSavedPaymentMethodMessage, + bool applePayEnabled, + bool googlePayEnabled}); + + $PaymentSheetAppearanceCopyWith<$Res>? get appearance; + $BillingDetailsCopyWith<$Res>? get defaultBillingDetails; + $BillingDetailsCollectionConfigurationCopyWith<$Res>? + get billingDetailsCollectionConfiguration; +} + +/// @nodoc +class _$CustomerSheetInitParamsCopyWithImpl<$Res, + $Val extends CustomerSheetInitParams> + implements $CustomerSheetInitParamsCopyWith<$Res> { + _$CustomerSheetInitParamsCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? style = freezed, + Object? appearance = freezed, + Object? setupIntentClientSecret = freezed, + Object? customerId = null, + Object? customerEphemeralKeySecret = null, + Object? merchantDisplayName = freezed, + Object? headerTextForSelectionScreen = freezed, + Object? defaultBillingDetails = freezed, + Object? billingDetailsCollectionConfiguration = freezed, + Object? returnURL = freezed, + Object? removeSavedPaymentMethodMessage = freezed, + Object? applePayEnabled = null, + Object? googlePayEnabled = null, + }) { + return _then(_value.copyWith( + style: freezed == style + ? _value.style + : style // ignore: cast_nullable_to_non_nullable + as ThemeMode?, + appearance: freezed == appearance + ? _value.appearance + : appearance // ignore: cast_nullable_to_non_nullable + as PaymentSheetAppearance?, + setupIntentClientSecret: freezed == setupIntentClientSecret + ? _value.setupIntentClientSecret + : setupIntentClientSecret // ignore: cast_nullable_to_non_nullable + as String?, + customerId: null == customerId + ? _value.customerId + : customerId // ignore: cast_nullable_to_non_nullable + as String, + customerEphemeralKeySecret: null == customerEphemeralKeySecret + ? _value.customerEphemeralKeySecret + : customerEphemeralKeySecret // ignore: cast_nullable_to_non_nullable + as String, + merchantDisplayName: freezed == merchantDisplayName + ? _value.merchantDisplayName + : merchantDisplayName // ignore: cast_nullable_to_non_nullable + as String?, + headerTextForSelectionScreen: freezed == headerTextForSelectionScreen + ? _value.headerTextForSelectionScreen + : headerTextForSelectionScreen // ignore: cast_nullable_to_non_nullable + as String?, + defaultBillingDetails: freezed == defaultBillingDetails + ? _value.defaultBillingDetails + : defaultBillingDetails // ignore: cast_nullable_to_non_nullable + as BillingDetails?, + billingDetailsCollectionConfiguration: freezed == + billingDetailsCollectionConfiguration + ? _value.billingDetailsCollectionConfiguration + : billingDetailsCollectionConfiguration // ignore: cast_nullable_to_non_nullable + as BillingDetailsCollectionConfiguration?, + returnURL: freezed == returnURL + ? _value.returnURL + : returnURL // ignore: cast_nullable_to_non_nullable + as String?, + removeSavedPaymentMethodMessage: freezed == + removeSavedPaymentMethodMessage + ? _value.removeSavedPaymentMethodMessage + : removeSavedPaymentMethodMessage // ignore: cast_nullable_to_non_nullable + as String?, + applePayEnabled: null == applePayEnabled + ? _value.applePayEnabled + : applePayEnabled // ignore: cast_nullable_to_non_nullable + as bool, + googlePayEnabled: null == googlePayEnabled + ? _value.googlePayEnabled + : googlePayEnabled // ignore: cast_nullable_to_non_nullable + as bool, + ) as $Val); + } + + @override + @pragma('vm:prefer-inline') + $PaymentSheetAppearanceCopyWith<$Res>? get appearance { + if (_value.appearance == null) { + return null; + } + + return $PaymentSheetAppearanceCopyWith<$Res>(_value.appearance!, (value) { + return _then(_value.copyWith(appearance: value) as $Val); + }); + } + + @override + @pragma('vm:prefer-inline') + $BillingDetailsCopyWith<$Res>? get defaultBillingDetails { + if (_value.defaultBillingDetails == null) { + return null; + } + + return $BillingDetailsCopyWith<$Res>(_value.defaultBillingDetails!, + (value) { + return _then(_value.copyWith(defaultBillingDetails: value) as $Val); + }); + } + + @override + @pragma('vm:prefer-inline') + $BillingDetailsCollectionConfigurationCopyWith<$Res>? + get billingDetailsCollectionConfiguration { + if (_value.billingDetailsCollectionConfiguration == null) { + return null; + } + + return $BillingDetailsCollectionConfigurationCopyWith<$Res>( + _value.billingDetailsCollectionConfiguration!, (value) { + return _then(_value.copyWith(billingDetailsCollectionConfiguration: value) + as $Val); + }); + } +} + +/// @nodoc +abstract class _$$_CustomerSheetInitParamsCopyWith<$Res> + implements $CustomerSheetInitParamsCopyWith<$Res> { + factory _$$_CustomerSheetInitParamsCopyWith(_$_CustomerSheetInitParams value, + $Res Function(_$_CustomerSheetInitParams) then) = + __$$_CustomerSheetInitParamsCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {@JsonKey(toJson: UserInterfaceStyleKey.toJson) ThemeMode? style, + PaymentSheetAppearance? appearance, + String? setupIntentClientSecret, + String customerId, + String customerEphemeralKeySecret, + String? merchantDisplayName, + String? headerTextForSelectionScreen, + BillingDetails? defaultBillingDetails, + BillingDetailsCollectionConfiguration? + billingDetailsCollectionConfiguration, + String? returnURL, + String? removeSavedPaymentMethodMessage, + bool applePayEnabled, + bool googlePayEnabled}); + + @override + $PaymentSheetAppearanceCopyWith<$Res>? get appearance; + @override + $BillingDetailsCopyWith<$Res>? get defaultBillingDetails; + @override + $BillingDetailsCollectionConfigurationCopyWith<$Res>? + get billingDetailsCollectionConfiguration; +} + +/// @nodoc +class __$$_CustomerSheetInitParamsCopyWithImpl<$Res> + extends _$CustomerSheetInitParamsCopyWithImpl<$Res, + _$_CustomerSheetInitParams> + implements _$$_CustomerSheetInitParamsCopyWith<$Res> { + __$$_CustomerSheetInitParamsCopyWithImpl(_$_CustomerSheetInitParams _value, + $Res Function(_$_CustomerSheetInitParams) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? style = freezed, + Object? appearance = freezed, + Object? setupIntentClientSecret = freezed, + Object? customerId = null, + Object? customerEphemeralKeySecret = null, + Object? merchantDisplayName = freezed, + Object? headerTextForSelectionScreen = freezed, + Object? defaultBillingDetails = freezed, + Object? billingDetailsCollectionConfiguration = freezed, + Object? returnURL = freezed, + Object? removeSavedPaymentMethodMessage = freezed, + Object? applePayEnabled = null, + Object? googlePayEnabled = null, + }) { + return _then(_$_CustomerSheetInitParams( + style: freezed == style + ? _value.style + : style // ignore: cast_nullable_to_non_nullable + as ThemeMode?, + appearance: freezed == appearance + ? _value.appearance + : appearance // ignore: cast_nullable_to_non_nullable + as PaymentSheetAppearance?, + setupIntentClientSecret: freezed == setupIntentClientSecret + ? _value.setupIntentClientSecret + : setupIntentClientSecret // ignore: cast_nullable_to_non_nullable + as String?, + customerId: null == customerId + ? _value.customerId + : customerId // ignore: cast_nullable_to_non_nullable + as String, + customerEphemeralKeySecret: null == customerEphemeralKeySecret + ? _value.customerEphemeralKeySecret + : customerEphemeralKeySecret // ignore: cast_nullable_to_non_nullable + as String, + merchantDisplayName: freezed == merchantDisplayName + ? _value.merchantDisplayName + : merchantDisplayName // ignore: cast_nullable_to_non_nullable + as String?, + headerTextForSelectionScreen: freezed == headerTextForSelectionScreen + ? _value.headerTextForSelectionScreen + : headerTextForSelectionScreen // ignore: cast_nullable_to_non_nullable + as String?, + defaultBillingDetails: freezed == defaultBillingDetails + ? _value.defaultBillingDetails + : defaultBillingDetails // ignore: cast_nullable_to_non_nullable + as BillingDetails?, + billingDetailsCollectionConfiguration: freezed == + billingDetailsCollectionConfiguration + ? _value.billingDetailsCollectionConfiguration + : billingDetailsCollectionConfiguration // ignore: cast_nullable_to_non_nullable + as BillingDetailsCollectionConfiguration?, + returnURL: freezed == returnURL + ? _value.returnURL + : returnURL // ignore: cast_nullable_to_non_nullable + as String?, + removeSavedPaymentMethodMessage: freezed == + removeSavedPaymentMethodMessage + ? _value.removeSavedPaymentMethodMessage + : removeSavedPaymentMethodMessage // ignore: cast_nullable_to_non_nullable + as String?, + applePayEnabled: null == applePayEnabled + ? _value.applePayEnabled + : applePayEnabled // ignore: cast_nullable_to_non_nullable + as bool, + googlePayEnabled: null == googlePayEnabled + ? _value.googlePayEnabled + : googlePayEnabled // ignore: cast_nullable_to_non_nullable + as bool, + )); + } +} + +/// @nodoc + +@JsonSerializable(explicitToJson: true) +class _$_CustomerSheetInitParams implements _CustomerSheetInitParams { + const _$_CustomerSheetInitParams( + {@JsonKey(toJson: UserInterfaceStyleKey.toJson) this.style, + this.appearance, + this.setupIntentClientSecret, + required this.customerId, + required this.customerEphemeralKeySecret, + this.merchantDisplayName, + this.headerTextForSelectionScreen, + this.defaultBillingDetails, + this.billingDetailsCollectionConfiguration, + this.returnURL, + this.removeSavedPaymentMethodMessage, + this.applePayEnabled = true, + this.googlePayEnabled = true}); + + factory _$_CustomerSheetInitParams.fromJson(Map json) => + _$$_CustomerSheetInitParamsFromJson(json); + + /// Color styling used for the Customersheet UI + @override + @JsonKey(toJson: UserInterfaceStyleKey.toJson) + final ThemeMode? style; + + /// Appearance of the customersheet. + /// + /// When no appearance defined it will fallback to [style] or Stripe default. + @override + final PaymentSheetAppearance? appearance; + + /// Optional but recommended for cards, required for other payment methods. The SetupIntent client secret that will be used to confirm a new payment method. If this is missing, you will only be able to add cards without authentication steps. + @override + final String? setupIntentClientSecret; + + /// The identifier of the Stripe Customer object. See https://stripe.com/docs/api/customers/object#customer_object-id + @override + final String customerId; + + /// A short-lived token that allows the SDK to access a Customer's payment methods. + @override + final String customerEphemeralKeySecret; + + /// Your customer-facing business name. The default value is the name of your app. + @override + final String? merchantDisplayName; + + /// Optional configuration for setting the header text of the Payment Method selection screen + @override + final String? headerTextForSelectionScreen; + + /// CustomerSheet pre-populates fields with the values provided. If `billingDetailsCollectionConfiguration.attachDefaultsToPaymentMethod` is `true`, these values will be attached to the payment method even if they are not collected by the CustomerSheet UI. + @override + final BillingDetails? defaultBillingDetails; + + /// Describes how billing details should be collected. All values default to `AUTOMATIC`. If `NEVER` is used for a required field for the Payment Method, you must provide an appropriate value as part of `defaultBillingDetails`. + @override + final BillingDetailsCollectionConfiguration? + billingDetailsCollectionConfiguration; + + /// URL that redirects back to your app that CustomerSheet can use to auto-dismiss web views used for additional authentication, e.g. 3DS2 + @override + final String? returnURL; + + /// Optional configuration to display a custom message when a saved payment method is removed. iOS only. + @override + final String? removeSavedPaymentMethodMessage; + + /// Whether to show Apple Pay as an option. Defaults to `false`. + @override + @JsonKey() + final bool applePayEnabled; + + /// Whether to show Google Pay as an option. Defaults to `false`. + @override + @JsonKey() + final bool googlePayEnabled; + + @override + String toString() { + return 'CustomerSheetInitParams(style: $style, appearance: $appearance, setupIntentClientSecret: $setupIntentClientSecret, customerId: $customerId, customerEphemeralKeySecret: $customerEphemeralKeySecret, merchantDisplayName: $merchantDisplayName, headerTextForSelectionScreen: $headerTextForSelectionScreen, defaultBillingDetails: $defaultBillingDetails, billingDetailsCollectionConfiguration: $billingDetailsCollectionConfiguration, returnURL: $returnURL, removeSavedPaymentMethodMessage: $removeSavedPaymentMethodMessage, applePayEnabled: $applePayEnabled, googlePayEnabled: $googlePayEnabled)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$_CustomerSheetInitParams && + (identical(other.style, style) || other.style == style) && + (identical(other.appearance, appearance) || + other.appearance == appearance) && + (identical(other.setupIntentClientSecret, setupIntentClientSecret) || + other.setupIntentClientSecret == setupIntentClientSecret) && + (identical(other.customerId, customerId) || + other.customerId == customerId) && + (identical(other.customerEphemeralKeySecret, customerEphemeralKeySecret) || + other.customerEphemeralKeySecret == + customerEphemeralKeySecret) && + (identical(other.merchantDisplayName, merchantDisplayName) || + other.merchantDisplayName == merchantDisplayName) && + (identical(other.headerTextForSelectionScreen, + headerTextForSelectionScreen) || + other.headerTextForSelectionScreen == + headerTextForSelectionScreen) && + (identical(other.defaultBillingDetails, defaultBillingDetails) || + other.defaultBillingDetails == defaultBillingDetails) && + (identical(other.billingDetailsCollectionConfiguration, + billingDetailsCollectionConfiguration) || + other.billingDetailsCollectionConfiguration == + billingDetailsCollectionConfiguration) && + (identical(other.returnURL, returnURL) || + other.returnURL == returnURL) && + (identical(other.removeSavedPaymentMethodMessage, + removeSavedPaymentMethodMessage) || + other.removeSavedPaymentMethodMessage == + removeSavedPaymentMethodMessage) && + (identical(other.applePayEnabled, applePayEnabled) || + other.applePayEnabled == applePayEnabled) && + (identical(other.googlePayEnabled, googlePayEnabled) || + other.googlePayEnabled == googlePayEnabled)); + } + + @JsonKey(ignore: true) + @override + int get hashCode => Object.hash( + runtimeType, + style, + appearance, + setupIntentClientSecret, + customerId, + customerEphemeralKeySecret, + merchantDisplayName, + headerTextForSelectionScreen, + defaultBillingDetails, + billingDetailsCollectionConfiguration, + returnURL, + removeSavedPaymentMethodMessage, + applePayEnabled, + googlePayEnabled); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$_CustomerSheetInitParamsCopyWith<_$_CustomerSheetInitParams> + get copyWith => + __$$_CustomerSheetInitParamsCopyWithImpl<_$_CustomerSheetInitParams>( + this, _$identity); + + @override + Map toJson() { + return _$$_CustomerSheetInitParamsToJson( + this, + ); + } +} + +abstract class _CustomerSheetInitParams implements CustomerSheetInitParams { + const factory _CustomerSheetInitParams( + {@JsonKey(toJson: UserInterfaceStyleKey.toJson) final ThemeMode? style, + final PaymentSheetAppearance? appearance, + final String? setupIntentClientSecret, + required final String customerId, + required final String customerEphemeralKeySecret, + final String? merchantDisplayName, + final String? headerTextForSelectionScreen, + final BillingDetails? defaultBillingDetails, + final BillingDetailsCollectionConfiguration? + billingDetailsCollectionConfiguration, + final String? returnURL, + final String? removeSavedPaymentMethodMessage, + final bool applePayEnabled, + final bool googlePayEnabled}) = _$_CustomerSheetInitParams; + + factory _CustomerSheetInitParams.fromJson(Map json) = + _$_CustomerSheetInitParams.fromJson; + + @override + + /// Color styling used for the Customersheet UI + @JsonKey(toJson: UserInterfaceStyleKey.toJson) + ThemeMode? get style; + @override + + /// Appearance of the customersheet. + /// + /// When no appearance defined it will fallback to [style] or Stripe default. + PaymentSheetAppearance? get appearance; + @override + + /// Optional but recommended for cards, required for other payment methods. The SetupIntent client secret that will be used to confirm a new payment method. If this is missing, you will only be able to add cards without authentication steps. + String? get setupIntentClientSecret; + @override + + /// The identifier of the Stripe Customer object. See https://stripe.com/docs/api/customers/object#customer_object-id + String get customerId; + @override + + /// A short-lived token that allows the SDK to access a Customer's payment methods. + String get customerEphemeralKeySecret; + @override + + /// Your customer-facing business name. The default value is the name of your app. + String? get merchantDisplayName; + @override + + /// Optional configuration for setting the header text of the Payment Method selection screen + String? get headerTextForSelectionScreen; + @override + + /// CustomerSheet pre-populates fields with the values provided. If `billingDetailsCollectionConfiguration.attachDefaultsToPaymentMethod` is `true`, these values will be attached to the payment method even if they are not collected by the CustomerSheet UI. + BillingDetails? get defaultBillingDetails; + @override + + /// Describes how billing details should be collected. All values default to `AUTOMATIC`. If `NEVER` is used for a required field for the Payment Method, you must provide an appropriate value as part of `defaultBillingDetails`. + BillingDetailsCollectionConfiguration? + get billingDetailsCollectionConfiguration; + @override + + /// URL that redirects back to your app that CustomerSheet can use to auto-dismiss web views used for additional authentication, e.g. 3DS2 + String? get returnURL; + @override + + /// Optional configuration to display a custom message when a saved payment method is removed. iOS only. + String? get removeSavedPaymentMethodMessage; + @override + + /// Whether to show Apple Pay as an option. Defaults to `false`. + bool get applePayEnabled; + @override + + /// Whether to show Google Pay as an option. Defaults to `false`. + bool get googlePayEnabled; + @override + @JsonKey(ignore: true) + _$$_CustomerSheetInitParamsCopyWith<_$_CustomerSheetInitParams> + get copyWith => throw _privateConstructorUsedError; +} + +CustomerSheetPresentParams _$CustomerSheetPresentParamsFromJson( + Map json) { + return _CustomerSheetPresentParams.fromJson(json); +} + +/// @nodoc +mixin _$CustomerSheetPresentParams { + /// Controls how the modal is presented (after animation). iOS only. Defaults to `popover`. + CustomerSheetPresentationStyle? get presentationStyle => + throw _privateConstructorUsedError; + + /// Controls how the modal animates. iOS only. + CustomerSheetAnimationStyle? get animationStyle => + throw _privateConstructorUsedError; + + /// Time (in milliseconds) before the Customer Sheet will automatically dismiss. + int? get timeout => throw _privateConstructorUsedError; + + Map toJson() => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + $CustomerSheetPresentParamsCopyWith + get copyWith => throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $CustomerSheetPresentParamsCopyWith<$Res> { + factory $CustomerSheetPresentParamsCopyWith(CustomerSheetPresentParams value, + $Res Function(CustomerSheetPresentParams) then) = + _$CustomerSheetPresentParamsCopyWithImpl<$Res, + CustomerSheetPresentParams>; + @useResult + $Res call( + {CustomerSheetPresentationStyle? presentationStyle, + CustomerSheetAnimationStyle? animationStyle, + int? timeout}); +} + +/// @nodoc +class _$CustomerSheetPresentParamsCopyWithImpl<$Res, + $Val extends CustomerSheetPresentParams> + implements $CustomerSheetPresentParamsCopyWith<$Res> { + _$CustomerSheetPresentParamsCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? presentationStyle = freezed, + Object? animationStyle = freezed, + Object? timeout = freezed, + }) { + return _then(_value.copyWith( + presentationStyle: freezed == presentationStyle + ? _value.presentationStyle + : presentationStyle // ignore: cast_nullable_to_non_nullable + as CustomerSheetPresentationStyle?, + animationStyle: freezed == animationStyle + ? _value.animationStyle + : animationStyle // ignore: cast_nullable_to_non_nullable + as CustomerSheetAnimationStyle?, + timeout: freezed == timeout + ? _value.timeout + : timeout // ignore: cast_nullable_to_non_nullable + as int?, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$_CustomerSheetPresentParamsCopyWith<$Res> + implements $CustomerSheetPresentParamsCopyWith<$Res> { + factory _$$_CustomerSheetPresentParamsCopyWith( + _$_CustomerSheetPresentParams value, + $Res Function(_$_CustomerSheetPresentParams) then) = + __$$_CustomerSheetPresentParamsCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {CustomerSheetPresentationStyle? presentationStyle, + CustomerSheetAnimationStyle? animationStyle, + int? timeout}); +} + +/// @nodoc +class __$$_CustomerSheetPresentParamsCopyWithImpl<$Res> + extends _$CustomerSheetPresentParamsCopyWithImpl<$Res, + _$_CustomerSheetPresentParams> + implements _$$_CustomerSheetPresentParamsCopyWith<$Res> { + __$$_CustomerSheetPresentParamsCopyWithImpl( + _$_CustomerSheetPresentParams _value, + $Res Function(_$_CustomerSheetPresentParams) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? presentationStyle = freezed, + Object? animationStyle = freezed, + Object? timeout = freezed, + }) { + return _then(_$_CustomerSheetPresentParams( + presentationStyle: freezed == presentationStyle + ? _value.presentationStyle + : presentationStyle // ignore: cast_nullable_to_non_nullable + as CustomerSheetPresentationStyle?, + animationStyle: freezed == animationStyle + ? _value.animationStyle + : animationStyle // ignore: cast_nullable_to_non_nullable + as CustomerSheetAnimationStyle?, + timeout: freezed == timeout + ? _value.timeout + : timeout // ignore: cast_nullable_to_non_nullable + as int?, + )); + } +} + +/// @nodoc + +@JsonSerializable(explicitToJson: true) +class _$_CustomerSheetPresentParams implements _CustomerSheetPresentParams { + const _$_CustomerSheetPresentParams( + {this.presentationStyle, this.animationStyle, this.timeout}); + + factory _$_CustomerSheetPresentParams.fromJson(Map json) => + _$$_CustomerSheetPresentParamsFromJson(json); + + /// Controls how the modal is presented (after animation). iOS only. Defaults to `popover`. + @override + final CustomerSheetPresentationStyle? presentationStyle; + + /// Controls how the modal animates. iOS only. + @override + final CustomerSheetAnimationStyle? animationStyle; + + /// Time (in milliseconds) before the Customer Sheet will automatically dismiss. + @override + final int? timeout; + + @override + String toString() { + return 'CustomerSheetPresentParams(presentationStyle: $presentationStyle, animationStyle: $animationStyle, timeout: $timeout)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$_CustomerSheetPresentParams && + (identical(other.presentationStyle, presentationStyle) || + other.presentationStyle == presentationStyle) && + (identical(other.animationStyle, animationStyle) || + other.animationStyle == animationStyle) && + (identical(other.timeout, timeout) || other.timeout == timeout)); + } + + @JsonKey(ignore: true) + @override + int get hashCode => + Object.hash(runtimeType, presentationStyle, animationStyle, timeout); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$_CustomerSheetPresentParamsCopyWith<_$_CustomerSheetPresentParams> + get copyWith => __$$_CustomerSheetPresentParamsCopyWithImpl< + _$_CustomerSheetPresentParams>(this, _$identity); + + @override + Map toJson() { + return _$$_CustomerSheetPresentParamsToJson( + this, + ); + } +} + +abstract class _CustomerSheetPresentParams + implements CustomerSheetPresentParams { + const factory _CustomerSheetPresentParams( + {final CustomerSheetPresentationStyle? presentationStyle, + final CustomerSheetAnimationStyle? animationStyle, + final int? timeout}) = _$_CustomerSheetPresentParams; + + factory _CustomerSheetPresentParams.fromJson(Map json) = + _$_CustomerSheetPresentParams.fromJson; + + @override + + /// Controls how the modal is presented (after animation). iOS only. Defaults to `popover`. + CustomerSheetPresentationStyle? get presentationStyle; + @override + + /// Controls how the modal animates. iOS only. + CustomerSheetAnimationStyle? get animationStyle; + @override + + /// Time (in milliseconds) before the Customer Sheet will automatically dismiss. + int? get timeout; + @override + @JsonKey(ignore: true) + _$$_CustomerSheetPresentParamsCopyWith<_$_CustomerSheetPresentParams> + get copyWith => throw _privateConstructorUsedError; +} + +CustomerSheetResult _$CustomerSheetResultFromJson(Map json) { + return _CustomerSheetResult.fromJson(json); +} + +/// @nodoc +mixin _$CustomerSheetResult { + /// The users selected payment option, if one exists. + PaymentSheetPaymentOption? get paymentOption => + throw _privateConstructorUsedError; + + /// The Stripe PaymentMethod associated with the paymentOption, if it exists. + PaymentMethod? get paymentMethod => throw _privateConstructorUsedError; + + /// The error that occurred + StripeError? get error => throw _privateConstructorUsedError; + + Map toJson() => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + $CustomerSheetResultCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $CustomerSheetResultCopyWith<$Res> { + factory $CustomerSheetResultCopyWith( + CustomerSheetResult value, $Res Function(CustomerSheetResult) then) = + _$CustomerSheetResultCopyWithImpl<$Res, CustomerSheetResult>; + @useResult + $Res call( + {PaymentSheetPaymentOption? paymentOption, + PaymentMethod? paymentMethod, + StripeError? error}); + + $PaymentSheetPaymentOptionCopyWith<$Res>? get paymentOption; + $PaymentMethodCopyWith<$Res>? get paymentMethod; + $StripeErrorCopyWith? get error; +} + +/// @nodoc +class _$CustomerSheetResultCopyWithImpl<$Res, $Val extends CustomerSheetResult> + implements $CustomerSheetResultCopyWith<$Res> { + _$CustomerSheetResultCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? paymentOption = freezed, + Object? paymentMethod = freezed, + Object? error = freezed, + }) { + return _then(_value.copyWith( + paymentOption: freezed == paymentOption + ? _value.paymentOption + : paymentOption // ignore: cast_nullable_to_non_nullable + as PaymentSheetPaymentOption?, + paymentMethod: freezed == paymentMethod + ? _value.paymentMethod + : paymentMethod // ignore: cast_nullable_to_non_nullable + as PaymentMethod?, + error: freezed == error + ? _value.error + : error // ignore: cast_nullable_to_non_nullable + as StripeError?, + ) as $Val); + } + + @override + @pragma('vm:prefer-inline') + $PaymentSheetPaymentOptionCopyWith<$Res>? get paymentOption { + if (_value.paymentOption == null) { + return null; + } + + return $PaymentSheetPaymentOptionCopyWith<$Res>(_value.paymentOption!, + (value) { + return _then(_value.copyWith(paymentOption: value) as $Val); + }); + } + + @override + @pragma('vm:prefer-inline') + $PaymentMethodCopyWith<$Res>? get paymentMethod { + if (_value.paymentMethod == null) { + return null; + } + + return $PaymentMethodCopyWith<$Res>(_value.paymentMethod!, (value) { + return _then(_value.copyWith(paymentMethod: value) as $Val); + }); + } + + @override + @pragma('vm:prefer-inline') + $StripeErrorCopyWith? get error { + if (_value.error == null) { + return null; + } + + return $StripeErrorCopyWith(_value.error!, (value) { + return _then(_value.copyWith(error: value) as $Val); + }); + } +} + +/// @nodoc +abstract class _$$_CustomerSheetResultCopyWith<$Res> + implements $CustomerSheetResultCopyWith<$Res> { + factory _$$_CustomerSheetResultCopyWith(_$_CustomerSheetResult value, + $Res Function(_$_CustomerSheetResult) then) = + __$$_CustomerSheetResultCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {PaymentSheetPaymentOption? paymentOption, + PaymentMethod? paymentMethod, + StripeError? error}); + + @override + $PaymentSheetPaymentOptionCopyWith<$Res>? get paymentOption; + @override + $PaymentMethodCopyWith<$Res>? get paymentMethod; + @override + $StripeErrorCopyWith? get error; +} + +/// @nodoc +class __$$_CustomerSheetResultCopyWithImpl<$Res> + extends _$CustomerSheetResultCopyWithImpl<$Res, _$_CustomerSheetResult> + implements _$$_CustomerSheetResultCopyWith<$Res> { + __$$_CustomerSheetResultCopyWithImpl(_$_CustomerSheetResult _value, + $Res Function(_$_CustomerSheetResult) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? paymentOption = freezed, + Object? paymentMethod = freezed, + Object? error = freezed, + }) { + return _then(_$_CustomerSheetResult( + paymentOption: freezed == paymentOption + ? _value.paymentOption + : paymentOption // ignore: cast_nullable_to_non_nullable + as PaymentSheetPaymentOption?, + paymentMethod: freezed == paymentMethod + ? _value.paymentMethod + : paymentMethod // ignore: cast_nullable_to_non_nullable + as PaymentMethod?, + error: freezed == error + ? _value.error + : error // ignore: cast_nullable_to_non_nullable + as StripeError?, + )); + } +} + +/// @nodoc + +@JsonSerializable(explicitToJson: true) +class _$_CustomerSheetResult implements _CustomerSheetResult { + const _$_CustomerSheetResult( + {this.paymentOption, this.paymentMethod, this.error}); + + factory _$_CustomerSheetResult.fromJson(Map json) => + _$$_CustomerSheetResultFromJson(json); + + /// The users selected payment option, if one exists. + @override + final PaymentSheetPaymentOption? paymentOption; + + /// The Stripe PaymentMethod associated with the paymentOption, if it exists. + @override + final PaymentMethod? paymentMethod; + + /// The error that occurred + @override + final StripeError? error; + + @override + String toString() { + return 'CustomerSheetResult(paymentOption: $paymentOption, paymentMethod: $paymentMethod, error: $error)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$_CustomerSheetResult && + (identical(other.paymentOption, paymentOption) || + other.paymentOption == paymentOption) && + (identical(other.paymentMethod, paymentMethod) || + other.paymentMethod == paymentMethod) && + (identical(other.error, error) || other.error == error)); + } + + @JsonKey(ignore: true) + @override + int get hashCode => + Object.hash(runtimeType, paymentOption, paymentMethod, error); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$_CustomerSheetResultCopyWith<_$_CustomerSheetResult> get copyWith => + __$$_CustomerSheetResultCopyWithImpl<_$_CustomerSheetResult>( + this, _$identity); + + @override + Map toJson() { + return _$$_CustomerSheetResultToJson( + this, + ); + } +} + +abstract class _CustomerSheetResult implements CustomerSheetResult { + const factory _CustomerSheetResult( + {final PaymentSheetPaymentOption? paymentOption, + final PaymentMethod? paymentMethod, + final StripeError? error}) = _$_CustomerSheetResult; + + factory _CustomerSheetResult.fromJson(Map json) = + _$_CustomerSheetResult.fromJson; + + @override + + /// The users selected payment option, if one exists. + PaymentSheetPaymentOption? get paymentOption; + @override + + /// The Stripe PaymentMethod associated with the paymentOption, if it exists. + PaymentMethod? get paymentMethod; + @override + + /// The error that occurred + StripeError? get error; + @override + @JsonKey(ignore: true) + _$$_CustomerSheetResultCopyWith<_$_CustomerSheetResult> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/packages/stripe_platform_interface/lib/src/models/customer_sheet.g.dart b/packages/stripe_platform_interface/lib/src/models/customer_sheet.g.dart new file mode 100644 index 000000000..5ce67f87f --- /dev/null +++ b/packages/stripe_platform_interface/lib/src/models/customer_sheet.g.dart @@ -0,0 +1,121 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'customer_sheet.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_$_CustomerSheetInitParams _$$_CustomerSheetInitParamsFromJson( + Map json) => + _$_CustomerSheetInitParams( + style: $enumDecodeNullable(_$ThemeModeEnumMap, json['style']), + appearance: json['appearance'] == null + ? null + : PaymentSheetAppearance.fromJson( + json['appearance'] as Map), + setupIntentClientSecret: json['setupIntentClientSecret'] as String?, + customerId: json['customerId'] as String, + customerEphemeralKeySecret: json['customerEphemeralKeySecret'] as String, + merchantDisplayName: json['merchantDisplayName'] as String?, + headerTextForSelectionScreen: + json['headerTextForSelectionScreen'] as String?, + defaultBillingDetails: json['defaultBillingDetails'] == null + ? null + : BillingDetails.fromJson( + json['defaultBillingDetails'] as Map), + billingDetailsCollectionConfiguration: + json['billingDetailsCollectionConfiguration'] == null + ? null + : BillingDetailsCollectionConfiguration.fromJson( + json['billingDetailsCollectionConfiguration'] + as Map), + returnURL: json['returnURL'] as String?, + removeSavedPaymentMethodMessage: + json['removeSavedPaymentMethodMessage'] as String?, + applePayEnabled: json['applePayEnabled'] as bool? ?? true, + googlePayEnabled: json['googlePayEnabled'] as bool? ?? true, + ); + +Map _$$_CustomerSheetInitParamsToJson( + _$_CustomerSheetInitParams instance) => + { + 'style': UserInterfaceStyleKey.toJson(instance.style), + 'appearance': instance.appearance?.toJson(), + 'setupIntentClientSecret': instance.setupIntentClientSecret, + 'customerId': instance.customerId, + 'customerEphemeralKeySecret': instance.customerEphemeralKeySecret, + 'merchantDisplayName': instance.merchantDisplayName, + 'headerTextForSelectionScreen': instance.headerTextForSelectionScreen, + 'defaultBillingDetails': instance.defaultBillingDetails?.toJson(), + 'billingDetailsCollectionConfiguration': + instance.billingDetailsCollectionConfiguration?.toJson(), + 'returnURL': instance.returnURL, + 'removeSavedPaymentMethodMessage': + instance.removeSavedPaymentMethodMessage, + 'applePayEnabled': instance.applePayEnabled, + 'googlePayEnabled': instance.googlePayEnabled, + }; + +const _$ThemeModeEnumMap = { + ThemeMode.system: 'system', + ThemeMode.light: 'light', + ThemeMode.dark: 'dark', +}; + +_$_CustomerSheetPresentParams _$$_CustomerSheetPresentParamsFromJson( + Map json) => + _$_CustomerSheetPresentParams( + presentationStyle: $enumDecodeNullable( + _$CustomerSheetPresentationStyleEnumMap, json['presentationStyle']), + animationStyle: $enumDecodeNullable( + _$CustomerSheetAnimationStyleEnumMap, json['animationStyle']), + timeout: json['timeout'] as int?, + ); + +Map _$$_CustomerSheetPresentParamsToJson( + _$_CustomerSheetPresentParams instance) => + { + 'presentationStyle': + _$CustomerSheetPresentationStyleEnumMap[instance.presentationStyle], + 'animationStyle': + _$CustomerSheetAnimationStyleEnumMap[instance.animationStyle], + 'timeout': instance.timeout, + }; + +const _$CustomerSheetPresentationStyleEnumMap = { + CustomerSheetPresentationStyle.fullscreen: 'fullscreen', + CustomerSheetPresentationStyle.popover: 'popover', +}; + +const _$CustomerSheetAnimationStyleEnumMap = { + CustomerSheetAnimationStyle.flip: 'flip', + CustomerSheetAnimationStyle.curl: 'curl', + CustomerSheetAnimationStyle.slide: 'slide', + CustomerSheetAnimationStyle.dissolve: 'dissolve', +}; + +_$_CustomerSheetResult _$$_CustomerSheetResultFromJson( + Map json) => + _$_CustomerSheetResult( + paymentOption: json['paymentOption'] == null + ? null + : PaymentSheetPaymentOption.fromJson( + json['paymentOption'] as Map), + paymentMethod: json['paymentMethod'] == null + ? null + : PaymentMethod.fromJson( + json['paymentMethod'] as Map), + error: json['error'] == null + ? null + : StripeError.fromJson( + json['error'] as Map), + ); + +Map _$$_CustomerSheetResultToJson( + _$_CustomerSheetResult instance) => + { + 'paymentOption': instance.paymentOption?.toJson(), + 'paymentMethod': instance.paymentMethod?.toJson(), + 'error': instance.error?.toJson(), + }; diff --git a/packages/stripe_platform_interface/lib/src/models/errors.dart b/packages/stripe_platform_interface/lib/src/models/errors.dart index 1589ef7a2..fdb1dccad 100644 --- a/packages/stripe_platform_interface/lib/src/models/errors.dart +++ b/packages/stripe_platform_interface/lib/src/models/errors.dart @@ -10,6 +10,8 @@ enum CreateTokenError { unknown } enum PaymentSheetError { unknown } +enum CustomerSheetError { unknown, failed, canceled } + @freezed /// Wrapper class that represents an error with the Stripe platform. 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 b707ee761..c274595ec 100644 --- a/packages/stripe_platform_interface/lib/src/models/payment_sheet.dart +++ b/packages/stripe_platform_interface/lib/src/models/payment_sheet.dart @@ -87,6 +87,9 @@ class SetupPaymentSheetParameters with _$SetupPaymentSheetParameters { /// Configuration for how billing details are collected during checkout. BillingDetailsCollectionConfiguration? billingDetailsCollectionConfiguration, + + /// Optional configuration to display a custom message when a saved payment method is removed. iOS only. + String? removeSavedPaymentMethodMessage, }) = _SetupParameters; factory SetupPaymentSheetParameters.fromJson(Map json) => 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 57d9efe05..8c6683022 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 @@ -97,6 +97,10 @@ mixin _$SetupPaymentSheetParameters { get billingDetailsCollectionConfiguration => throw _privateConstructorUsedError; + /// Optional configuration to display a custom message when a saved payment method is removed. iOS only. + String? get removeSavedPaymentMethodMessage => + throw _privateConstructorUsedError; + Map toJson() => throw _privateConstructorUsedError; @JsonKey(ignore: true) $SetupPaymentSheetParametersCopyWith @@ -128,7 +132,8 @@ abstract class $SetupPaymentSheetParametersCopyWith<$Res> { @JsonKey(name: 'defaultBillingDetails') BillingDetails? billingDetails, String? returnURL, BillingDetailsCollectionConfiguration? - billingDetailsCollectionConfiguration}); + billingDetailsCollectionConfiguration, + String? removeSavedPaymentMethodMessage}); $IntentConfigurationCopyWith<$Res>? get intentConfiguration; $PaymentSheetApplePayCopyWith<$Res>? get applePay; @@ -169,6 +174,7 @@ class _$SetupPaymentSheetParametersCopyWithImpl<$Res, Object? billingDetails = freezed, Object? returnURL = freezed, Object? billingDetailsCollectionConfiguration = freezed, + Object? removeSavedPaymentMethodMessage = freezed, }) { return _then(_value.copyWith( customFlow: null == customFlow @@ -236,6 +242,11 @@ class _$SetupPaymentSheetParametersCopyWithImpl<$Res, ? _value.billingDetailsCollectionConfiguration : billingDetailsCollectionConfiguration // ignore: cast_nullable_to_non_nullable as BillingDetailsCollectionConfiguration?, + removeSavedPaymentMethodMessage: freezed == + removeSavedPaymentMethodMessage + ? _value.removeSavedPaymentMethodMessage + : removeSavedPaymentMethodMessage // ignore: cast_nullable_to_non_nullable + as String?, ) as $Val); } @@ -341,7 +352,8 @@ abstract class _$$_SetupParametersCopyWith<$Res> @JsonKey(name: 'defaultBillingDetails') BillingDetails? billingDetails, String? returnURL, BillingDetailsCollectionConfiguration? - billingDetailsCollectionConfiguration}); + billingDetailsCollectionConfiguration, + String? removeSavedPaymentMethodMessage}); @override $IntentConfigurationCopyWith<$Res>? get intentConfiguration; @@ -385,6 +397,7 @@ class __$$_SetupParametersCopyWithImpl<$Res> Object? billingDetails = freezed, Object? returnURL = freezed, Object? billingDetailsCollectionConfiguration = freezed, + Object? removeSavedPaymentMethodMessage = freezed, }) { return _then(_$_SetupParameters( customFlow: null == customFlow @@ -452,6 +465,11 @@ class __$$_SetupParametersCopyWithImpl<$Res> ? _value.billingDetailsCollectionConfiguration : billingDetailsCollectionConfiguration // ignore: cast_nullable_to_non_nullable as BillingDetailsCollectionConfiguration?, + removeSavedPaymentMethodMessage: freezed == + removeSavedPaymentMethodMessage + ? _value.removeSavedPaymentMethodMessage + : removeSavedPaymentMethodMessage // ignore: cast_nullable_to_non_nullable + as String?, )); } } @@ -476,7 +494,8 @@ class _$_SetupParameters implements _SetupParameters { this.appearance, @JsonKey(name: 'defaultBillingDetails') this.billingDetails, this.returnURL, - this.billingDetailsCollectionConfiguration}); + this.billingDetailsCollectionConfiguration, + this.removeSavedPaymentMethodMessage}); factory _$_SetupParameters.fromJson(Map json) => _$$_SetupParametersFromJson(json); @@ -573,9 +592,13 @@ class _$_SetupParameters implements _SetupParameters { final BillingDetailsCollectionConfiguration? billingDetailsCollectionConfiguration; + /// Optional configuration to display a custom message when a saved payment method is removed. iOS only. + @override + final String? removeSavedPaymentMethodMessage; + @override String toString() { - return 'SetupPaymentSheetParameters(customFlow: $customFlow, customerId: $customerId, primaryButtonLabel: $primaryButtonLabel, customerEphemeralKeySecret: $customerEphemeralKeySecret, paymentIntentClientSecret: $paymentIntentClientSecret, setupIntentClientSecret: $setupIntentClientSecret, intentConfiguration: $intentConfiguration, merchantDisplayName: $merchantDisplayName, applePay: $applePay, style: $style, googlePay: $googlePay, allowsDelayedPaymentMethods: $allowsDelayedPaymentMethods, appearance: $appearance, billingDetails: $billingDetails, returnURL: $returnURL, billingDetailsCollectionConfiguration: $billingDetailsCollectionConfiguration)'; + return 'SetupPaymentSheetParameters(customFlow: $customFlow, customerId: $customerId, primaryButtonLabel: $primaryButtonLabel, customerEphemeralKeySecret: $customerEphemeralKeySecret, paymentIntentClientSecret: $paymentIntentClientSecret, setupIntentClientSecret: $setupIntentClientSecret, intentConfiguration: $intentConfiguration, merchantDisplayName: $merchantDisplayName, applePay: $applePay, style: $style, googlePay: $googlePay, allowsDelayedPaymentMethods: $allowsDelayedPaymentMethods, appearance: $appearance, billingDetails: $billingDetails, returnURL: $returnURL, billingDetailsCollectionConfiguration: $billingDetailsCollectionConfiguration, removeSavedPaymentMethodMessage: $removeSavedPaymentMethodMessage)'; } @override @@ -605,8 +628,7 @@ class _$_SetupParameters implements _SetupParameters { (identical(other.style, style) || other.style == style) && (identical(other.googlePay, googlePay) || other.googlePay == googlePay) && - (identical(other.allowsDelayedPaymentMethods, - allowsDelayedPaymentMethods) || + (identical(other.allowsDelayedPaymentMethods, allowsDelayedPaymentMethods) || other.allowsDelayedPaymentMethods == allowsDelayedPaymentMethods) && (identical(other.appearance, appearance) || @@ -618,7 +640,10 @@ class _$_SetupParameters implements _SetupParameters { (identical(other.billingDetailsCollectionConfiguration, billingDetailsCollectionConfiguration) || other.billingDetailsCollectionConfiguration == - billingDetailsCollectionConfiguration)); + billingDetailsCollectionConfiguration) && + (identical(other.removeSavedPaymentMethodMessage, removeSavedPaymentMethodMessage) || + other.removeSavedPaymentMethodMessage == + removeSavedPaymentMethodMessage)); } @JsonKey(ignore: true) @@ -640,7 +665,8 @@ class _$_SetupParameters implements _SetupParameters { appearance, billingDetails, returnURL, - billingDetailsCollectionConfiguration); + billingDetailsCollectionConfiguration, + removeSavedPaymentMethodMessage); @JsonKey(ignore: true) @override @@ -675,7 +701,8 @@ abstract class _SetupParameters implements SetupPaymentSheetParameters { final BillingDetails? billingDetails, final String? returnURL, final BillingDetailsCollectionConfiguration? - billingDetailsCollectionConfiguration}) = _$_SetupParameters; + billingDetailsCollectionConfiguration, + final String? removeSavedPaymentMethodMessage}) = _$_SetupParameters; factory _SetupParameters.fromJson(Map json) = _$_SetupParameters.fromJson; @@ -771,6 +798,10 @@ abstract class _SetupParameters implements SetupPaymentSheetParameters { BillingDetailsCollectionConfiguration? get billingDetailsCollectionConfiguration; @override + + /// Optional configuration to display a custom message when a saved payment method is removed. iOS only. + String? get removeSavedPaymentMethodMessage; + @override @JsonKey(ignore: true) _$$_SetupParametersCopyWith<_$_SetupParameters> get copyWith => throw _privateConstructorUsedError; 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 44ff694e2..88171e318 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 @@ -45,6 +45,8 @@ _$_SetupParameters _$$_SetupParametersFromJson(Map json) => : BillingDetailsCollectionConfiguration.fromJson( json['billingDetailsCollectionConfiguration'] as Map), + removeSavedPaymentMethodMessage: + json['removeSavedPaymentMethodMessage'] as String?, ); Map _$$_SetupParametersToJson(_$_SetupParameters instance) => @@ -66,6 +68,8 @@ Map _$$_SetupParametersToJson(_$_SetupParameters instance) => 'returnURL': instance.returnURL, 'billingDetailsCollectionConfiguration': instance.billingDetailsCollectionConfiguration?.toJson(), + 'removeSavedPaymentMethodMessage': + instance.removeSavedPaymentMethodMessage, }; const _$ThemeModeEnumMap = { 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 979e6fe59..1e3ffbf91 100644 --- a/packages/stripe_platform_interface/lib/src/stripe_platform_interface.dart +++ b/packages/stripe_platform_interface/lib/src/stripe_platform_interface.dart @@ -69,6 +69,17 @@ abstract class StripePlatform extends PlatformInterface { /// Confirm the payment on a payment sheet. Future confirmPaymentSheetPayment(); + /// Configure the payment sheet using [CustomerSheetInitParams] as config. + Future initCustomerSheet( + CustomerSheetInitParams params); + + /// Display the customersheet sheet. + Future presentCustomerSheet({ + CustomerSheetPresentParams? options, + }); + + Future retrieveCustomerSheetPaymentOptionSelection(); + Future openApplePaySetup(); Future createApplePayToken(Map payment); diff --git a/packages/stripe_platform_interface/lib/stripe_platform_interface.dart b/packages/stripe_platform_interface/lib/stripe_platform_interface.dart index 1c5d719c9..f0c4588f5 100644 --- a/packages/stripe_platform_interface/lib/stripe_platform_interface.dart +++ b/packages/stripe_platform_interface/lib/stripe_platform_interface.dart @@ -10,6 +10,7 @@ export 'src/models/capture_method.dart'; export 'src/models/card_details.dart'; export 'src/models/card_field_input.dart'; export 'src/models/create_token_data.dart'; +export 'src/models/customer_sheet.dart'; export 'src/models/errors.dart'; export 'src/models/financial_connections.dart'; export 'src/models/google_pay.dart'; 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 939622f43..3e357438d 100644 --- a/packages/stripe_platform_interface/test/method_channel_stripe_test.dart +++ b/packages/stripe_platform_interface/test/method_channel_stripe_test.dart @@ -101,7 +101,7 @@ void main() { 'id': 'cvcResultToken', 'type': 'Card', 'livemode': true, - 'created': 1630670419 + 'created': '1630670419' } }, ).methodChannel, @@ -574,5 +574,53 @@ void main() { ); }); }); + + group('init customer sheet', () { + late Completer completer; + setUp(() async { + completer = Completer(); + sut = MethodChannelStripe( + platformIsIos: false, + platformIsAndroid: true, + methodChannel: MethodChannelMock( + channelName: methodChannelName, + method: 'initCustomerSheet', + result: {}, + ).methodChannel, + ); + await sut + .initCustomerSheet( + const CustomerSheetInitParams( + customerId: 'customerId', + customerEphemeralKeySecret: 'customerEphemeralKeySecret'), + ) + .then((_) => completer.complete()); + }); + + test('It completes operation', () { + expect(completer.isCompleted, true); + }); + }); + + group('When customersheet is succesfull', () { + late Completer completer; + setUp(() async { + completer = Completer(); + sut = MethodChannelStripe( + platformIsIos: false, + platformIsAndroid: true, + methodChannel: MethodChannelMock( + channelName: methodChannelName, + method: 'presentCustomerSheet', + result: {}, + ).methodChannel, + ); + await sut.presentCustomerSheet().then((_) => completer.complete()); + }); + + test('It completes operation', () { + expect(completer.isCompleted, true); + }); + }); }); } diff --git a/packages/stripe_web/lib/src/web_stripe.dart b/packages/stripe_web/lib/src/web_stripe.dart index 4526b566c..f1b4c4d87 100644 --- a/packages/stripe_web/lib/src/web_stripe.dart +++ b/packages/stripe_web/lib/src/web_stripe.dart @@ -522,6 +522,24 @@ class WebStripe extends StripePlatform { {String? returnURL}) { throw WebUnsupportedError.method('handleNextActionForSetupIntent'); } + + @override + Future initCustomerSheet( + CustomerSheetInitParams params) { + throw WebUnsupportedError.method('initCustomerSheet'); + } + + @override + Future presentCustomerSheet( + {CustomerSheetPresentParams? options}) { + throw WebUnsupportedError.method('presentCustomerSheet'); + } + + @override + Future retrieveCustomerSheetPaymentOptionSelection() { + throw WebUnsupportedError.method( + 'retrieveCustomerSheetPaymentOptionSelection'); + } } class WebUnsupportedError extends Error implements UnsupportedError {