diff --git a/example/lib/screens/regional_payment_methods/revolutpay_screen.dart b/example/lib/screens/regional_payment_methods/revolutpay_screen.dart index 38b17b4b..09ee1eb8 100644 --- a/example/lib/screens/regional_payment_methods/revolutpay_screen.dart +++ b/example/lib/screens/regional_payment_methods/revolutpay_screen.dart @@ -35,7 +35,6 @@ class RevolutPayScreen extends StatelessWidget { // 1. on the backend create a payment intent for payment method and save the // client secret. final result = await _createPaymentIntent(); - print('blaat $result'); final clientSecret = await result['clientSecret']; // 2. use the client secret to confirm the payment and handle the result. diff --git a/example/lib/screens/regional_payment_methods/us_bank_account_direct_debit_screen.dart b/example/lib/screens/regional_payment_methods/us_bank_account_direct_debit_screen.dart index 6703242f..21b47e2e 100644 --- a/example/lib/screens/regional_payment_methods/us_bank_account_direct_debit_screen.dart +++ b/example/lib/screens/regional_payment_methods/us_bank_account_direct_debit_screen.dart @@ -18,10 +18,13 @@ class _UsBankAccountDirectDebitScreenState extends State { late TextEditingController _nameController; late TextEditingController _emailController; + bool canConfirm = false; + String clientSecretForConfirm = ''; @override void initState() { super.initState(); + _nameController = TextEditingController(); _emailController = TextEditingController(); } @@ -76,7 +79,13 @@ class _UsBankAccountDirectDebitScreenState SizedBox(height: 10), LoadingButton( onPressed: _handlePayPress, - text: 'Pay', + text: 'Collect account', + ), + SizedBox(height: 10), + LoadingButton( + onPressed: + canConfirm ? () => confirmPayment(clientSecretForConfirm) : null, + text: 'Confirm', ), ], ); @@ -87,8 +96,6 @@ class _UsBankAccountDirectDebitScreenState // 1. call API to create PaymentIntent final paymentIntentResult = await _createPaymentIntent(); - print('blaat $json'); - if (paymentIntentResult['error'] != null) { // Error during creating or confirming Intent ScaffoldMessenger.of(context).showSnackBar( @@ -97,29 +104,42 @@ class _UsBankAccountDirectDebitScreenState } // collect the bankaccount + final clientSecret = paymentIntentResult['clientSecret']; if (paymentIntentResult['clientSecret'] != null) { final result = await Stripe.instance.collectBankAccount( - clientSecret: paymentIntentResult['clientSecret'], + clientSecret: clientSecret, isPaymentIntent: true, params: CollectBankAccountParams( - billingDetails: BillingDetails( - email: _emailController.text, - name: _nameController.text, - phone: '+48888000888', - address: Address( - city: 'Houston', - country: 'US', - line1: '1459 Circle Drive', - line2: '', - state: 'Texas', - postalCode: '77063', + paymentMethodData: CollectBankAccountPaymentMethodData( + billingDetails: BillingDetails( + email: _emailController.text, + name: _nameController.text, + phone: '+48888000888', + address: Address( + city: 'Houston', + country: 'US', + line1: '1459 Circle Drive', + line2: '', + state: 'Texas', + postalCode: '77063', + ), ), ), ), ); - print('result'); + if (result.status == PaymentIntentsStatus.RequiresConfirmation) { + setState(() { + canConfirm = true; + clientSecretForConfirm = result.clientSecret; + }); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('You can now confirm the payment'), + ), + ); + } } } catch (e) { ScaffoldMessenger.of(context) @@ -128,6 +148,24 @@ class _UsBankAccountDirectDebitScreenState } } + Future confirmPayment(String clientSecret) async { + try { + await Stripe.instance.confirmPayment( + paymentIntentClientSecret: clientSecret, + ); + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Payment succesfully completed'), + ), + ); + } catch (e) { + ScaffoldMessenger.of(context) + .showSnackBar(SnackBar(content: Text('Error: $e'))); + rethrow; + } + } + Future> _createPaymentIntent() async { final url = Uri.parse('$kApiUrl/create-payment-intent'); final response = await http.post( 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 ce017789..32e1e86a 100644 --- a/packages/stripe_platform_interface/lib/src/method_channel_stripe.dart +++ b/packages/stripe_platform_interface/lib/src/method_channel_stripe.dart @@ -486,7 +486,7 @@ class MethodChannelStripe extends StripePlatform { }) async { final result = await _methodChannel .invokeMapMethod('collectBankAccount', { - 'isPaymentIntent': isPaymentIntent, + 'intentType': isPaymentIntent, 'params': params.toJson(), 'clientSecret': clientSecret, }); diff --git a/packages/stripe_platform_interface/lib/src/models/ach_params.dart b/packages/stripe_platform_interface/lib/src/models/ach_params.dart index fa210839..894cefe8 100644 --- a/packages/stripe_platform_interface/lib/src/models/ach_params.dart +++ b/packages/stripe_platform_interface/lib/src/models/ach_params.dart @@ -14,7 +14,7 @@ class CollectBankAccountParams with _$CollectBankAccountParams { /// Billingdetails of the account holder /// /// It is required to fill in the name in the billing details - required BillingDetails billingDetails, + required CollectBankAccountPaymentMethodData paymentMethodData, /// The paymentmethod type. At this point only method [PaymentMethodType.USBankAccount] /// is supported. @@ -26,6 +26,21 @@ class CollectBankAccountParams with _$CollectBankAccountParams { _$CollectBankAccountParamsFromJson(json); } +/// Specific payment method data needed for collecting the bank account of +/// an payment method +@freezed +class CollectBankAccountPaymentMethodData + with _$CollectBankAccountPaymentMethodData { + @JsonSerializable(explicitToJson: true) + const factory CollectBankAccountPaymentMethodData({ + required BillingDetails billingDetails, + }) = _CollectBankAccountPaymentMethodData; + + factory CollectBankAccountPaymentMethodData.fromJson( + Map json) => + _$CollectBankAccountPaymentMethodDataFromJson(json); +} + /// The type of payment intent used for collecting bank accoutn @freezed diff --git a/packages/stripe_platform_interface/lib/src/models/ach_params.freezed.dart b/packages/stripe_platform_interface/lib/src/models/ach_params.freezed.dart index eb76582c..b85054d8 100644 --- a/packages/stripe_platform_interface/lib/src/models/ach_params.freezed.dart +++ b/packages/stripe_platform_interface/lib/src/models/ach_params.freezed.dart @@ -24,7 +24,8 @@ mixin _$CollectBankAccountParams { /// Billingdetails of the account holder /// /// It is required to fill in the name in the billing details - BillingDetails get billingDetails => throw _privateConstructorUsedError; + CollectBankAccountPaymentMethodData get paymentMethodData => + throw _privateConstructorUsedError; /// The paymentmethod type. At this point only method [PaymentMethodType.USBankAccount] /// is supported. @@ -43,9 +44,10 @@ abstract class $CollectBankAccountParamsCopyWith<$Res> { _$CollectBankAccountParamsCopyWithImpl<$Res, CollectBankAccountParams>; @useResult $Res call( - {BillingDetails billingDetails, PaymentMethodType paymentMethodType}); + {CollectBankAccountPaymentMethodData paymentMethodData, + PaymentMethodType paymentMethodType}); - $BillingDetailsCopyWith<$Res> get billingDetails; + $CollectBankAccountPaymentMethodDataCopyWith<$Res> get paymentMethodData; } /// @nodoc @@ -62,14 +64,14 @@ class _$CollectBankAccountParamsCopyWithImpl<$Res, @pragma('vm:prefer-inline') @override $Res call({ - Object? billingDetails = null, + Object? paymentMethodData = null, Object? paymentMethodType = null, }) { return _then(_value.copyWith( - billingDetails: null == billingDetails - ? _value.billingDetails - : billingDetails // ignore: cast_nullable_to_non_nullable - as BillingDetails, + paymentMethodData: null == paymentMethodData + ? _value.paymentMethodData + : paymentMethodData // ignore: cast_nullable_to_non_nullable + as CollectBankAccountPaymentMethodData, paymentMethodType: null == paymentMethodType ? _value.paymentMethodType : paymentMethodType // ignore: cast_nullable_to_non_nullable @@ -79,9 +81,10 @@ class _$CollectBankAccountParamsCopyWithImpl<$Res, @override @pragma('vm:prefer-inline') - $BillingDetailsCopyWith<$Res> get billingDetails { - return $BillingDetailsCopyWith<$Res>(_value.billingDetails, (value) { - return _then(_value.copyWith(billingDetails: value) as $Val); + $CollectBankAccountPaymentMethodDataCopyWith<$Res> get paymentMethodData { + return $CollectBankAccountPaymentMethodDataCopyWith<$Res>( + _value.paymentMethodData, (value) { + return _then(_value.copyWith(paymentMethodData: value) as $Val); }); } } @@ -96,10 +99,11 @@ abstract class _$$CollectBankAccountParamsImplCopyWith<$Res> @override @useResult $Res call( - {BillingDetails billingDetails, PaymentMethodType paymentMethodType}); + {CollectBankAccountPaymentMethodData paymentMethodData, + PaymentMethodType paymentMethodType}); @override - $BillingDetailsCopyWith<$Res> get billingDetails; + $CollectBankAccountPaymentMethodDataCopyWith<$Res> get paymentMethodData; } /// @nodoc @@ -115,14 +119,14 @@ class __$$CollectBankAccountParamsImplCopyWithImpl<$Res> @pragma('vm:prefer-inline') @override $Res call({ - Object? billingDetails = null, + Object? paymentMethodData = null, Object? paymentMethodType = null, }) { return _then(_$CollectBankAccountParamsImpl( - billingDetails: null == billingDetails - ? _value.billingDetails - : billingDetails // ignore: cast_nullable_to_non_nullable - as BillingDetails, + paymentMethodData: null == paymentMethodData + ? _value.paymentMethodData + : paymentMethodData // ignore: cast_nullable_to_non_nullable + as CollectBankAccountPaymentMethodData, paymentMethodType: null == paymentMethodType ? _value.paymentMethodType : paymentMethodType // ignore: cast_nullable_to_non_nullable @@ -136,7 +140,7 @@ class __$$CollectBankAccountParamsImplCopyWithImpl<$Res> @JsonSerializable(explicitToJson: true) class _$CollectBankAccountParamsImpl implements _CollectBankAccountParams { const _$CollectBankAccountParamsImpl( - {required this.billingDetails, + {required this.paymentMethodData, this.paymentMethodType = PaymentMethodType.USBankAccount}); factory _$CollectBankAccountParamsImpl.fromJson(Map json) => @@ -146,7 +150,7 @@ class _$CollectBankAccountParamsImpl implements _CollectBankAccountParams { /// /// It is required to fill in the name in the billing details @override - final BillingDetails billingDetails; + final CollectBankAccountPaymentMethodData paymentMethodData; /// The paymentmethod type. At this point only method [PaymentMethodType.USBankAccount] /// is supported. @@ -156,7 +160,7 @@ class _$CollectBankAccountParamsImpl implements _CollectBankAccountParams { @override String toString() { - return 'CollectBankAccountParams(billingDetails: $billingDetails, paymentMethodType: $paymentMethodType)'; + return 'CollectBankAccountParams(paymentMethodData: $paymentMethodData, paymentMethodType: $paymentMethodType)'; } @override @@ -164,8 +168,8 @@ class _$CollectBankAccountParamsImpl implements _CollectBankAccountParams { return identical(this, other) || (other.runtimeType == runtimeType && other is _$CollectBankAccountParamsImpl && - (identical(other.billingDetails, billingDetails) || - other.billingDetails == billingDetails) && + (identical(other.paymentMethodData, paymentMethodData) || + other.paymentMethodData == paymentMethodData) && (identical(other.paymentMethodType, paymentMethodType) || other.paymentMethodType == paymentMethodType)); } @@ -173,7 +177,7 @@ class _$CollectBankAccountParamsImpl implements _CollectBankAccountParams { @JsonKey(ignore: true) @override int get hashCode => - Object.hash(runtimeType, billingDetails, paymentMethodType); + Object.hash(runtimeType, paymentMethodData, paymentMethodType); @JsonKey(ignore: true) @override @@ -192,7 +196,7 @@ class _$CollectBankAccountParamsImpl implements _CollectBankAccountParams { abstract class _CollectBankAccountParams implements CollectBankAccountParams { const factory _CollectBankAccountParams( - {required final BillingDetails billingDetails, + {required final CollectBankAccountPaymentMethodData paymentMethodData, final PaymentMethodType paymentMethodType}) = _$CollectBankAccountParamsImpl; @@ -204,7 +208,7 @@ abstract class _CollectBankAccountParams implements CollectBankAccountParams { /// Billingdetails of the account holder /// /// It is required to fill in the name in the billing details - BillingDetails get billingDetails; + CollectBankAccountPaymentMethodData get paymentMethodData; @override /// The paymentmethod type. At this point only method [PaymentMethodType.USBankAccount] @@ -216,6 +220,175 @@ abstract class _CollectBankAccountParams implements CollectBankAccountParams { get copyWith => throw _privateConstructorUsedError; } +CollectBankAccountPaymentMethodData + _$CollectBankAccountPaymentMethodDataFromJson(Map json) { + return _CollectBankAccountPaymentMethodData.fromJson(json); +} + +/// @nodoc +mixin _$CollectBankAccountPaymentMethodData { + BillingDetails get billingDetails => throw _privateConstructorUsedError; + + Map toJson() => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + $CollectBankAccountPaymentMethodDataCopyWith< + CollectBankAccountPaymentMethodData> + get copyWith => throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $CollectBankAccountPaymentMethodDataCopyWith<$Res> { + factory $CollectBankAccountPaymentMethodDataCopyWith( + CollectBankAccountPaymentMethodData value, + $Res Function(CollectBankAccountPaymentMethodData) then) = + _$CollectBankAccountPaymentMethodDataCopyWithImpl<$Res, + CollectBankAccountPaymentMethodData>; + @useResult + $Res call({BillingDetails billingDetails}); + + $BillingDetailsCopyWith<$Res> get billingDetails; +} + +/// @nodoc +class _$CollectBankAccountPaymentMethodDataCopyWithImpl<$Res, + $Val extends CollectBankAccountPaymentMethodData> + implements $CollectBankAccountPaymentMethodDataCopyWith<$Res> { + _$CollectBankAccountPaymentMethodDataCopyWithImpl(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? billingDetails = null, + }) { + return _then(_value.copyWith( + billingDetails: null == billingDetails + ? _value.billingDetails + : billingDetails // ignore: cast_nullable_to_non_nullable + as BillingDetails, + ) as $Val); + } + + @override + @pragma('vm:prefer-inline') + $BillingDetailsCopyWith<$Res> get billingDetails { + return $BillingDetailsCopyWith<$Res>(_value.billingDetails, (value) { + return _then(_value.copyWith(billingDetails: value) as $Val); + }); + } +} + +/// @nodoc +abstract class _$$CollectBankAccountPaymentMethodDataImplCopyWith<$Res> + implements $CollectBankAccountPaymentMethodDataCopyWith<$Res> { + factory _$$CollectBankAccountPaymentMethodDataImplCopyWith( + _$CollectBankAccountPaymentMethodDataImpl value, + $Res Function(_$CollectBankAccountPaymentMethodDataImpl) then) = + __$$CollectBankAccountPaymentMethodDataImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({BillingDetails billingDetails}); + + @override + $BillingDetailsCopyWith<$Res> get billingDetails; +} + +/// @nodoc +class __$$CollectBankAccountPaymentMethodDataImplCopyWithImpl<$Res> + extends _$CollectBankAccountPaymentMethodDataCopyWithImpl<$Res, + _$CollectBankAccountPaymentMethodDataImpl> + implements _$$CollectBankAccountPaymentMethodDataImplCopyWith<$Res> { + __$$CollectBankAccountPaymentMethodDataImplCopyWithImpl( + _$CollectBankAccountPaymentMethodDataImpl _value, + $Res Function(_$CollectBankAccountPaymentMethodDataImpl) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? billingDetails = null, + }) { + return _then(_$CollectBankAccountPaymentMethodDataImpl( + billingDetails: null == billingDetails + ? _value.billingDetails + : billingDetails // ignore: cast_nullable_to_non_nullable + as BillingDetails, + )); + } +} + +/// @nodoc + +@JsonSerializable(explicitToJson: true) +class _$CollectBankAccountPaymentMethodDataImpl + implements _CollectBankAccountPaymentMethodData { + const _$CollectBankAccountPaymentMethodDataImpl( + {required this.billingDetails}); + + factory _$CollectBankAccountPaymentMethodDataImpl.fromJson( + Map json) => + _$$CollectBankAccountPaymentMethodDataImplFromJson(json); + + @override + final BillingDetails billingDetails; + + @override + String toString() { + return 'CollectBankAccountPaymentMethodData(billingDetails: $billingDetails)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$CollectBankAccountPaymentMethodDataImpl && + (identical(other.billingDetails, billingDetails) || + other.billingDetails == billingDetails)); + } + + @JsonKey(ignore: true) + @override + int get hashCode => Object.hash(runtimeType, billingDetails); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$CollectBankAccountPaymentMethodDataImplCopyWith< + _$CollectBankAccountPaymentMethodDataImpl> + get copyWith => __$$CollectBankAccountPaymentMethodDataImplCopyWithImpl< + _$CollectBankAccountPaymentMethodDataImpl>(this, _$identity); + + @override + Map toJson() { + return _$$CollectBankAccountPaymentMethodDataImplToJson( + this, + ); + } +} + +abstract class _CollectBankAccountPaymentMethodData + implements CollectBankAccountPaymentMethodData { + const factory _CollectBankAccountPaymentMethodData( + {required final BillingDetails billingDetails}) = + _$CollectBankAccountPaymentMethodDataImpl; + + factory _CollectBankAccountPaymentMethodData.fromJson( + Map json) = + _$CollectBankAccountPaymentMethodDataImpl.fromJson; + + @override + BillingDetails get billingDetails; + @override + @JsonKey(ignore: true) + _$$CollectBankAccountPaymentMethodDataImplCopyWith< + _$CollectBankAccountPaymentMethodDataImpl> + get copyWith => throw _privateConstructorUsedError; +} + VerifyMicroDepositsParams _$VerifyMicroDepositsParamsFromJson( Map json) { return _VerifyMicroDepositsParams.fromJson(json); diff --git a/packages/stripe_platform_interface/lib/src/models/ach_params.g.dart b/packages/stripe_platform_interface/lib/src/models/ach_params.g.dart index 35edc199..e9a444b1 100644 --- a/packages/stripe_platform_interface/lib/src/models/ach_params.g.dart +++ b/packages/stripe_platform_interface/lib/src/models/ach_params.g.dart @@ -9,8 +9,8 @@ part of 'ach_params.dart'; _$CollectBankAccountParamsImpl _$$CollectBankAccountParamsImplFromJson( Map json) => _$CollectBankAccountParamsImpl( - billingDetails: BillingDetails.fromJson( - json['billingDetails'] as Map), + paymentMethodData: CollectBankAccountPaymentMethodData.fromJson( + json['paymentMethodData'] as Map), paymentMethodType: $enumDecodeNullable( _$PaymentMethodTypeEnumMap, json['paymentMethodType']) ?? PaymentMethodType.USBankAccount, @@ -19,7 +19,7 @@ _$CollectBankAccountParamsImpl _$$CollectBankAccountParamsImplFromJson( Map _$$CollectBankAccountParamsImplToJson( _$CollectBankAccountParamsImpl instance) => { - 'billingDetails': instance.billingDetails.toJson(), + 'paymentMethodData': instance.paymentMethodData.toJson(), 'paymentMethodType': _$PaymentMethodTypeEnumMap[instance.paymentMethodType]!, }; @@ -49,6 +49,20 @@ const _$PaymentMethodTypeEnumMap = { PaymentMethodType.Unknown: 'Unknown', }; +_$CollectBankAccountPaymentMethodDataImpl + _$$CollectBankAccountPaymentMethodDataImplFromJson( + Map json) => + _$CollectBankAccountPaymentMethodDataImpl( + billingDetails: BillingDetails.fromJson( + json['billingDetails'] as Map), + ); + +Map _$$CollectBankAccountPaymentMethodDataImplToJson( + _$CollectBankAccountPaymentMethodDataImpl instance) => + { + 'billingDetails': instance.billingDetails.toJson(), + }; + _$VerifyMicroDepositsParamsImpl _$$VerifyMicroDepositsParamsImplFromJson( Map json) => _$VerifyMicroDepositsParamsImpl( diff --git a/pubspec.yaml b/pubspec.yaml index 019607d1..a69e5888 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -5,3 +5,4 @@ environment: dev_dependencies: melos: ^3.1.0 + flutter_lints: ^5.0.0