Skip to content

Commit ae51739

Browse files
jonasbarkremonh87jamesblasco
authored
Sync (#217)
* sync android code from react native * BREAKING: rename confirmpaymentmethod to confirmpayment * update token result object * add methods blur, focus and clear to cardfield * make sure CardEditEvent is not exported by extracting it to a different file * Update iOS side * Display error also in debug * Update focus and blur methods on iOS Co-authored-by: Remon <[email protected]> Co-authored-by: Jaime Blasco <[email protected]>
1 parent 82e9023 commit ae51739

28 files changed

+345
-177
lines changed

example/lib/screens/google_pay_screen.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class _GooglePayScreenState extends State<GooglePayScreen> {
9191
);
9292

9393
// 3. Confirm Google pay payment method
94-
await Stripe.instance.confirmPaymentMethod(
94+
await Stripe.instance.confirmPayment(
9595
clientSecret,
9696
params,
9797
);

example/lib/screens/no_webhook_payment_screen.dart

+97-64
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import 'dart:convert';
22

33
import 'package:flutter/material.dart';
4-
import 'package:http/http.dart' as http;
54
import 'package:flutter_stripe/flutter_stripe.dart';
5+
import 'package:http/http.dart' as http;
66
import 'package:stripe_example/widgets/loading_button.dart';
77
import 'package:stripe_platform_interface/stripe_platform_interface.dart';
88

@@ -15,6 +15,13 @@ class NoWebhookPaymentScreen extends StatefulWidget {
1515

1616
class _NoWebhookPaymentScreenState extends State<NoWebhookPaymentScreen> {
1717
CardFieldInputDetails? _card;
18+
final _editController = CardEditController();
19+
20+
@override
21+
void dispose() {
22+
_editController.dispose();
23+
super.dispose();
24+
}
1825

1926
@override
2027
Widget build(BuildContext context) {
@@ -25,6 +32,7 @@ class _NoWebhookPaymentScreenState extends State<NoWebhookPaymentScreen> {
2532
Padding(
2633
padding: EdgeInsets.all(16),
2734
child: CardField(
35+
controller: _editController,
2836
onCardChanged: (card) {
2937
setState(() {
3038
_card = card;
@@ -39,6 +47,32 @@ class _NoWebhookPaymentScreenState extends State<NoWebhookPaymentScreen> {
3947
text: 'Pay',
4048
),
4149
),
50+
Divider(
51+
thickness: 2,
52+
),
53+
Row(
54+
mainAxisAlignment: MainAxisAlignment.center,
55+
children: [
56+
Padding(
57+
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16),
58+
child: ElevatedButton(
59+
onPressed: () => _editController.blur(),
60+
child: Text('Blur'),
61+
),
62+
),
63+
ElevatedButton(
64+
onPressed: () => _editController.clear(),
65+
child: Text('Clear'),
66+
),
67+
Padding(
68+
padding: const EdgeInsets.only(left: 16.0),
69+
child: ElevatedButton(
70+
onPressed: () => _editController.focus(),
71+
child: Text('Focus'),
72+
),
73+
),
74+
],
75+
),
4276
],
4377
),
4478
);
@@ -50,82 +84,81 @@ class _NoWebhookPaymentScreenState extends State<NoWebhookPaymentScreen> {
5084
}
5185

5286
try {
87+
// 1. Gather customer billing information (ex. email)
88+
89+
final billingDetails = BillingDetails(
90+
91+
phone: '+48888000888',
92+
address: Address(
93+
city: 'Houston',
94+
country: 'US',
95+
line1: '1459 Circle Drive',
96+
line2: '',
97+
state: 'Texas',
98+
postalCode: '77063',
99+
),
100+
); // mocked data for tests
101+
102+
// 2. Create payment method
103+
final paymentMethod =
104+
await Stripe.instance.createPaymentMethod(PaymentMethodParams.card(
105+
billingDetails: billingDetails,
106+
));
107+
108+
// 3. call API to create PaymentIntent
109+
final paymentIntentResult = await callNoWebhookPayEndpointMethodId(
110+
useStripeSdk: true,
111+
paymentMethodId: paymentMethod.id,
112+
currency: 'usd', // mocked data
113+
items: [
114+
{'id': 'id'}
115+
],
116+
);
53117

54-
// 1. Gather customer billing information (ex. email)
55-
56-
final billingDetails = BillingDetails(
57-
58-
phone: '+48888000888',
59-
address: Address(
60-
city: 'Houston',
61-
country: 'US',
62-
line1: '1459 Circle Drive',
63-
line2: '',
64-
state: 'Texas',
65-
postalCode: '77063',
66-
),
67-
); // mocked data for tests
68-
69-
// 2. Create payment method
70-
final paymentMethod =
71-
await Stripe.instance.createPaymentMethod(PaymentMethodParams.card(
72-
billingDetails: billingDetails,
73-
));
74-
75-
// 3. call API to create PaymentIntent
76-
final paymentIntentResult = await callNoWebhookPayEndpointMethodId(
77-
useStripeSdk: true,
78-
paymentMethodId: paymentMethod.id,
79-
currency: 'usd', // mocked data
80-
items: [
81-
{'id': 'id'}
82-
],
83-
);
84-
85-
if (paymentIntentResult['error'] != null) {
86-
// Error during creating or confirming Intent
87-
ScaffoldMessenger.of(context).showSnackBar(
88-
SnackBar(content: Text('Error: ${paymentIntentResult['error']}')));
89-
return;
90-
}
118+
if (paymentIntentResult['error'] != null) {
119+
// Error during creating or confirming Intent
120+
ScaffoldMessenger.of(context).showSnackBar(
121+
SnackBar(content: Text('Error: ${paymentIntentResult['error']}')));
122+
return;
123+
}
91124

92-
if (paymentIntentResult['clientSecret'] != null &&
93-
paymentIntentResult['requiresAction'] == null) {
94-
// Payment succedeed
125+
if (paymentIntentResult['clientSecret'] != null &&
126+
paymentIntentResult['requiresAction'] == null) {
127+
// Payment succedeed
95128

96-
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
97-
content: Text('Success!: The payment was confirmed successfully!')));
98-
return;
99-
}
129+
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
130+
content:
131+
Text('Success!: The payment was confirmed successfully!')));
132+
return;
133+
}
100134

101-
if (paymentIntentResult['clientSecret'] != null &&
102-
paymentIntentResult['requiresAction'] == true) {
103-
// 4. if payment requires action calling handleCardAction
104-
final paymentIntent = await Stripe.instance
105-
.handleCardAction(paymentIntentResult['clientSecret']);
135+
if (paymentIntentResult['clientSecret'] != null &&
136+
paymentIntentResult['requiresAction'] == true) {
137+
// 4. if payment requires action calling handleCardAction
138+
final paymentIntent = await Stripe.instance
139+
.handleCardAction(paymentIntentResult['clientSecret']);
106140

107-
// todo handle error
108-
/*if (cardActionError) {
141+
// todo handle error
142+
/*if (cardActionError) {
109143
Alert.alert(
110144
`Error code: ${cardActionError.code}`,
111145
cardActionError.message
112146
);
113147
} else*/
114148

115-
if (paymentIntent.status == PaymentIntentsStatus.RequiresConfirmation) {
116-
// 5. Call API to confirm intent
117-
await confirmIntent(paymentIntent.id);
118-
} else {
119-
// Payment succedeed
120-
ScaffoldMessenger.of(context).showSnackBar(
121-
SnackBar(content: Text('Error: ${paymentIntentResult['error']}')));
149+
if (paymentIntent.status == PaymentIntentsStatus.RequiresConfirmation) {
150+
// 5. Call API to confirm intent
151+
await confirmIntent(paymentIntent.id);
152+
} else {
153+
// Payment succedeed
154+
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
155+
content: Text('Error: ${paymentIntentResult['error']}')));
156+
}
122157
}
123-
}
124-
125158
} catch (e) {
126-
ScaffoldMessenger.of(context).showSnackBar(
127-
SnackBar(content: Text('Error: $e')));
128-
rethrow;
159+
ScaffoldMessenger.of(context)
160+
.showSnackBar(SnackBar(content: Text('Error: $e')));
161+
rethrow;
129162
}
130163
}
131164

example/lib/screens/setup_future_payment_screen.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ class _SetupFuturePaymentScreenState extends State<SetupFuturePaymentScreen> {
186186

187187
// TODO lastPaymentError
188188
if (_retrievedPaymentIntent?.paymentMethodId != null && _card != null) {
189-
await Stripe.instance.confirmPaymentMethod(
189+
await Stripe.instance.confirmPayment(
190190
_retrievedPaymentIntent!.clientSecret,
191191
PaymentMethodParams.cardFromMethodId(
192192
paymentMethodId: _retrievedPaymentIntent!.paymentMethodId!),

example/lib/screens/webhook_payment_screen.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ class _WebhookPaymentScreenState extends State<WebhookPaymentScreen> {
9696
// 3. Confirm payment with card details
9797
// The rest will be done automatically using webhooks
9898
// ignore: unused_local_variable
99-
final paymentIntent = await Stripe.instance.confirmPaymentMethod(
99+
final paymentIntent = await Stripe.instance.confirmPayment(
100100
clientSecret['clientSecret'],
101101
PaymentMethodParams.card(
102102
billingDetails: billingDetails,

example/lib/widgets/loading_button.dart

+2-7
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,17 @@ class _LoadingButtonState extends State<LoadingButton> {
2929
setState(() {
3030
_isLoading = true;
3131
});
32-
32+
3333
try {
3434
await widget.onPressed!();
3535
} catch (e) {
36-
if (kDebugMode) {
37-
rethrow;
38-
} else {
3936
ScaffoldMessenger.of(context)
4037
.showSnackBar(SnackBar(content: Text('Error $e')));
41-
}
38+
rethrow;
4239
} finally {
4340
setState(() {
4441
_isLoading = false;
4542
});
4643
}
47-
48-
4944
}
5045
}

packages/stripe/lib/flutter_stripe.dart

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ export 'src/model/apple_pay_button.dart';
44
export 'src/stripe.dart';
55
export 'src/widgets/apple_pay_button.dart';
66
export 'src/widgets/card_field.dart';
7+
export 'src/widgets/card_edit_controller.dart';

packages/stripe/lib/src/stripe.dart

+7-5
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ class Stripe {
155155

156156
/// Retrieves a [PaymentIntent] using the provided [clientSecret].
157157
///
158-
/// Throws a [StripeException] in case retrieving the intent fails.
158+
/// Throws a [StripeException] in case retrieving the intent fails.
159159
Future<PaymentIntent> retrievePaymentIntent(String clientSecret) async {
160160
await _awaitForSettings();
161161
try {
@@ -207,16 +207,18 @@ class Stripe {
207207
/// Confirms a payment method, using the provided [paymentIntentClientSecret]
208208
/// and [data].
209209
///
210-
/// See [PaymentMethodParams] for more details.
211-
/// Throws a [StripeException] when confirming the paymentmethod fails.
212-
Future<PaymentIntent> confirmPaymentMethod(
210+
/// See [PaymentMethodParams] for more details. The method returns a
211+
/// [PaymentIntent]. Throws a [StripeException] when confirming the
212+
/// paymentmethod fails.
213+
214+
Future<PaymentIntent> confirmPayment(
213215
String paymentIntentClientSecret,
214216
PaymentMethodParams data, [
215217
Map<String, String> options = const {},
216218
]) async {
217219
await _awaitForSettings();
218220
try {
219-
final paymentMethod = await _platform.confirmPaymentMethod(
221+
final paymentMethod = await _platform.confirmPayment(
220222
paymentIntentClientSecret, data, options);
221223
return paymentMethod;
222224
} on StripeError {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import 'package:flutter/material.dart';
2+
3+
import 'card_edit_event.dart';
4+
5+
class CardEditController extends ValueNotifier<CardEditEvent> {
6+
CardEditController() : super(CardEditEvent.none);
7+
8+
void focus() {
9+
value = CardEditEvent.focus;
10+
notifyListeners();
11+
}
12+
13+
void blur() {
14+
value = CardEditEvent.blur;
15+
notifyListeners();
16+
}
17+
18+
void clear() {
19+
value = CardEditEvent.clear;
20+
notifyListeners();
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
enum CardEditEvent { none, focus, blur, clear }

0 commit comments

Comments
 (0)