Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bank accounts #2014

Merged
merged 7 commits into from
Dec 22, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ analyzer:
# TODO (albertus-stripe): Remove this once the melos PR is merged since this won't be an issue anymore
invalid_dependency: ignore
invalid_annotation_target: ignore #https://github.com/rrousselGit/freezed#disabling-invalid_annotation_target-warning-and-warning-in-generates-files
library_private_types_in_public_api: ignore
exclude:
- "bin/cache/**"
- "**/*.freezed.dart"
Expand Down
2 changes: 1 addition & 1 deletion example/android/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pluginManagement {

plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "8.7.3" apply false
id "com.android.application" version "8.6.1" apply false
remonh87 marked this conversation as resolved.
Show resolved Hide resolved
id "org.jetbrains.kotlin.android" version "1.8.10" apply false
}

Expand Down
13 changes: 7 additions & 6 deletions example/integration_test/app_test.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'dart:convert';
import 'dart:developer';

import 'package:flutter/material.dart';
import 'package:flutter_stripe/flutter_stripe.dart';
Expand All @@ -19,9 +20,9 @@ void main() {
group('Payment sheet', () {
testWidgets('init payment sheet', (_) async {
// 1. create payment intent on the server
final _paymentSheetData = await _createTestPaymentSheet();
final paymentSheetData = await _createTestPaymentSheet();

expect(_paymentSheetData['paymentIntent'], isNotNull);
expect(paymentSheetData['paymentIntent'], isNotNull);
// 2. initialize the payment sheet
expect(
Stripe.instance.initPaymentSheet(
Expand All @@ -33,9 +34,9 @@ void main() {
),
style: ThemeMode.dark,
merchantDisplayName: 'Flutter Stripe Store Demo',
customerId: _paymentSheetData['customer'],
paymentIntentClientSecret: _paymentSheetData['paymentIntent'],
customerEphemeralKeySecret: _paymentSheetData['ephemeralKey'],
customerId: paymentSheetData['customer'],
paymentIntentClientSecret: paymentSheetData['paymentIntent'],
customerEphemeralKeySecret: paymentSheetData['ephemeralKey'],
),
),
completes,
Expand Down Expand Up @@ -90,7 +91,7 @@ void main() {
Future<Map<String, dynamic>> _createTestPaymentSheet() async {
// ifconfig | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' could return multiple IPs, divided by new line - use the last one
final ipAddress = kApiUrl.split('\n').last.trim();
print('IP Address of the server: $ipAddress');
log('IP Address of the server: $ipAddress');
final url = Uri.parse('http://$ipAddress:4242/payment-sheet');
final response = await http.post(
url,
Expand Down
2 changes: 1 addition & 1 deletion example/integration_test/payment_method_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ void main() {
expirationMonth: 04,
expirationYear: 2025,
));
;

final paymentIntent = await Stripe.instance.confirmPayment(
paymentIntentClientSecret: clientSecret['clientSecret'],
data: PaymentMethodParams.card(
Expand Down
4 changes: 3 additions & 1 deletion example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// ignore_for_file: use_key_in_widget_constructors

import 'package:flutter/material.dart';
import 'package:flutter_stripe/flutter_stripe.dart';
import 'package:stripe_example/.env.dart';
Expand All @@ -14,7 +16,7 @@ void main() async {
}

class App extends StatelessWidget {
const App({Key? key}) : super(key: key);
const App({super.key});

@override
Widget build(BuildContext context) {
Expand Down
30 changes: 19 additions & 11 deletions example/lib/screens/card_payments/custom_card_payment_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import 'package:stripe_example/config.dart';
import 'package:stripe_example/widgets/loading_button.dart';

class CustomCardPaymentScreen extends StatefulWidget {
const CustomCardPaymentScreen({super.key});

@override
_CustomCardPaymentScreenState createState() =>
_CustomCardPaymentScreenState();
Expand Down Expand Up @@ -120,6 +122,8 @@ class _CustomCardPaymentScreenState extends State<CustomCardPaymentScreen> {
}

Future<void> _handlePayPress() async {
final scaffoldMessenger = ScaffoldMessenger.of(context);

await Stripe.instance.dangerouslyUpdateCardDetails(_card);

try {
Expand Down Expand Up @@ -158,16 +162,18 @@ class _CustomCardPaymentScreenState extends State<CustomCardPaymentScreen> {

if (paymentIntentResult['error'] != null) {
// Error during creating or confirming Intent
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error: ${paymentIntentResult['error']}')));
return;
if (context.mounted) {
scaffoldMessenger.showSnackBar(SnackBar(
content: Text('Error: ${paymentIntentResult['error']}')));
return;
}
}

if (paymentIntentResult['clientSecret'] != null &&
paymentIntentResult['requiresAction'] == null) {
// Payment succedeed

ScaffoldMessenger.of(context).showSnackBar(SnackBar(
scaffoldMessenger.showSnackBar(SnackBar(
content:
Text('Success!: The payment was confirmed successfully!')));
return;
Expand All @@ -184,25 +190,27 @@ class _CustomCardPaymentScreenState extends State<CustomCardPaymentScreen> {
await confirmIntent(paymentIntent.id);
} else {
// Payment succedeed
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('Error: ${paymentIntentResult['error']}')));
if (context.mounted) {
scaffoldMessenger.showSnackBar(SnackBar(
content: Text('Error: ${paymentIntentResult['error']}')));
}
}
}
} catch (e) {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('Error: $e')));
scaffoldMessenger.showSnackBar(SnackBar(content: Text('Error: $e')));
rethrow;
}
}

Future<void> confirmIntent(String paymentIntentId) async {
final scaffoldMessenger = ScaffoldMessenger.of(context);
final result = await callNoWebhookPayEndpointIntentId(
paymentIntentId: paymentIntentId);
if (result['error'] != null) {
ScaffoldMessenger.of(context)
if (result['error'] != null && context.mounted) {
scaffoldMessenger
.showSnackBar(SnackBar(content: Text('Error: ${result['error']}')));
} else {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
scaffoldMessenger.showSnackBar(SnackBar(
content: Text('Success!: The payment was confirmed successfully!')));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import 'package:stripe_example/widgets/loading_button.dart';
import 'package:stripe_example/widgets/response_card.dart';

class NoWebhookPaymentCardFormScreen extends StatefulWidget {
const NoWebhookPaymentCardFormScreen({super.key});

@override
_NoWebhookPaymentCardFormScreenState createState() =>
_NoWebhookPaymentCardFormScreenState();
Expand Down Expand Up @@ -86,6 +88,8 @@ class _NoWebhookPaymentCardFormScreenState
return;
}

final scaffoldMessenger = ScaffoldMessenger.of(context);

try {
// 1. Gather customer billing information (ex. email)

Expand Down Expand Up @@ -120,19 +124,23 @@ class _NoWebhookPaymentCardFormScreenState

if (paymentIntentResult['error'] != null) {
// Error during creating or confirming Intent
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error: ${paymentIntentResult['error']}')));
if (context.mounted) {
scaffoldMessenger.showSnackBar(SnackBar(
content: Text('Error: ${paymentIntentResult['error']}')));
}
return;
}

if (paymentIntentResult['clientSecret'] != null &&
paymentIntentResult['requiresAction'] == null) {
// Payment succedeed

ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content:
Text('Success!: The payment was confirmed successfully!')));
return;
if (context.mounted) {
scaffoldMessenger.showSnackBar(SnackBar(
content:
Text('Success!: The payment was confirmed successfully!')));
return;
}
}

if (paymentIntentResult['clientSecret'] != null &&
Expand All @@ -153,27 +161,34 @@ class _NoWebhookPaymentCardFormScreenState
// 5. Call API to confirm intent
await confirmIntent(paymentIntent.id);
} else {
// Payment succedeed
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('Error: ${paymentIntentResult['error']}')));
if (context.mounted) {
// Payment succedeed
scaffoldMessenger.showSnackBar(SnackBar(
content: Text('Error: ${paymentIntentResult['error']}')));
}
}
}
} catch (e) {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('Error: $e')));
if (context.mounted) {
scaffoldMessenger.showSnackBar(SnackBar(content: Text('Error: $e')));
}
rethrow;
}
}

Future<void> confirmIntent(String paymentIntentId) async {
final scaffoldMessenger = ScaffoldMessenger.of(context);
final result = await callNoWebhookPayEndpointIntentId(
paymentIntentId: paymentIntentId);
if (result['error'] != null) {
ScaffoldMessenger.of(context)
if (result['error'] != null && context.mounted) {
scaffoldMessenger
.showSnackBar(SnackBar(content: Text('Error: ${result['error']}')));
} else {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('Success!: The payment was confirmed successfully!')));
if (context.mounted) {
scaffoldMessenger.showSnackBar(SnackBar(
content:
Text('Success!: The payment was confirmed successfully!')));
}
}
}

Expand Down
38 changes: 26 additions & 12 deletions example/lib/screens/card_payments/no_webhook_payment_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import 'package:stripe_example/widgets/loading_button.dart';
import 'package:stripe_example/widgets/response_card.dart';

class NoWebhookPaymentScreen extends StatefulWidget {
const NoWebhookPaymentScreen({super.key});

@override
_NoWebhookPaymentScreenState createState() => _NoWebhookPaymentScreenState();
}
Expand Down Expand Up @@ -85,6 +87,8 @@ class _NoWebhookPaymentScreenState extends State<NoWebhookPaymentScreen> {
return;
}

final scaffoldMessenger = ScaffoldMessenger.of(context);

try {
// 1. Gather customer billing information (ex. email)
final billingDetails = BillingDetails(
Expand Down Expand Up @@ -118,16 +122,19 @@ class _NoWebhookPaymentScreenState extends State<NoWebhookPaymentScreen> {

if (paymentIntentResult['error'] != null) {
// Error during creating or confirming Intent
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error: ${paymentIntentResult['error']}')));
if (context.mounted) {
scaffoldMessenger.showSnackBar(SnackBar(
content: Text('Error: ${paymentIntentResult['error']}')));
}
return;
}

if (paymentIntentResult['clientSecret'] != null &&
paymentIntentResult['requiresAction'] == null) {
paymentIntentResult['requiresAction'] == null &&
context.mounted) {
// Payment succedeed

ScaffoldMessenger.of(context).showSnackBar(SnackBar(
scaffoldMessenger.showSnackBar(SnackBar(
content:
Text('Success!: The payment was confirmed successfully!')));
return;
Expand All @@ -146,26 +153,33 @@ class _NoWebhookPaymentScreenState extends State<NoWebhookPaymentScreen> {
await confirmIntent(paymentIntent.id);
} else {
// Payment succedeed
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('Error: ${paymentIntentResult['error']}')));
if (context.mounted) {
scaffoldMessenger.showSnackBar(SnackBar(
content: Text('Error: ${paymentIntentResult['error']}')));
}
}
}
} catch (e) {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('Error: $e')));
if (context.mounted) {
scaffoldMessenger.showSnackBar(SnackBar(content: Text('Error: $e')));
}
rethrow;
}
}

Future<void> confirmIntent(String paymentIntentId) async {
final scaffoldMessenger = ScaffoldMessenger.of(context);
final result = await callNoWebhookPayEndpointIntentId(
paymentIntentId: paymentIntentId);
if (result['error'] != null) {
ScaffoldMessenger.of(context)
if (result['error'] != null && context.mounted) {
scaffoldMessenger
.showSnackBar(SnackBar(content: Text('Error: ${result['error']}')));
} else {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('Success!: The payment was confirmed successfully!')));
if (context.mounted) {
scaffoldMessenger.showSnackBar(SnackBar(
content:
Text('Success!: The payment was confirmed successfully!')));
}
}
}

Expand Down
10 changes: 7 additions & 3 deletions example/lib/screens/card_payments/webhook_payment_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import 'package:stripe_example/widgets/loading_button.dart';
import 'package:stripe_example/widgets/response_card.dart';

class WebhookPaymentScreen extends StatefulWidget {
const WebhookPaymentScreen({super.key});

@override
_WebhookPaymentScreenState createState() => _WebhookPaymentScreenState();
}
Expand Down Expand Up @@ -71,6 +73,7 @@ class _WebhookPaymentScreenState extends State<WebhookPaymentScreen> {
}

Future<void> _handlePayPress() async {
final scaffoldMessenger = ScaffoldMessenger.of(context);
if (_card == null) {
return;
}
Expand Down Expand Up @@ -107,9 +110,10 @@ class _WebhookPaymentScreenState extends State<WebhookPaymentScreen> {
_saveCard == true ? PaymentIntentsFutureUsage.OffSession : null,
),
);

ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('Success!: The payment was confirmed successfully!')));
if (context.mounted) {
scaffoldMessenger.showSnackBar(SnackBar(
content: Text('Success!: The payment was confirmed successfully!')));
}
}

Future<Map<String, dynamic>> fetchPaymentIntentClientSecret() async {
Expand Down
Loading
Loading