Skip to content

Commit

Permalink
Sync with React Native 0.17.0 (#874)
Browse files Browse the repository at this point in the history
* Android sync with Stripe React Native 0.17.0

* sync iOS with Stripe React Native 0.17.0

* add missing class

* update stripe server

* add datamodel for financial connections

* Fix #863

* Android sync 0.18.0

* sync iOS 0.18.0

* update libraries

* implement financial connection methods in the plugin

* allow confirming payment with only a client secret

* add docs for financial connections

* bump compile sdk version of example app to latest version

* bump financial connections to the right version.

The app didn't compile on android

* add a integration test for confirmPayment, fix Android side

* fix crash on webhook payment screen

* fix new integration test as well

Co-authored-by: Remon Helmond <remonhelmond@gmail.com>
  • Loading branch information
jonasbark and remonh87 authored Sep 4, 2022
1 parent c0718d4 commit b95e979
Show file tree
Hide file tree
Showing 102 changed files with 4,168 additions and 711 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ Cardfield | Medium | Single line cardfield. Offers more flexibility b
Card form | Medium | Simular as the cardfield but the entry fields are spread across multi lines | [docs](https://docs.page/flutter-stripe/flutter_stripe/card_field) |


### Financial connections
We also support Financial connections in our latest sdk. Check out the [docs](https://docs.page/flutter-stripe/flutter_stripe/financial_connections) to learn more on how to set it up.

## Stripe initialization

To initialize Stripe in your Flutter app, use the `Stripe` base class.
Expand Down
1 change: 1 addition & 0 deletions docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
["Ideal", "/ideal"]
]
],
["Financial connections", "/financial_connections" ],
["Troubleshooting", "/troubleshooting"],
["Api Reference", "https://pub.dev/documentation/flutter_stripe/latest/flutter_stripe/flutter_stripe-library.html"]
]
Expand Down
114 changes: 114 additions & 0 deletions docs/financial_connections.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
---
title: Financial Connections
description: Handling financial connections operations
---

# Stripe Financial connections (only available for us bank accounts)

### Route payments between multiple parties

To learn more about how it works read: [Official Stripe connect docs](https://stripe.com/docs/connect).


## 1. Create

First, you need a Stripe account. [Register now](https://dashboard.stripe.com/register).

#### Server-side

This integration requires endpoints on your server that talk to the Stripe API. Use one official libraries for access to the Stripe API from your server. [Follow the steps to create an Financial account session here](https://stripe.com/docs/connect/collect-then-transfer-guide?platform=react-native&ui=payment-sheet#setup-server-side).

#### Client-side

The Flutter SDK is open source, fully documented.

To install the SDK, follow these steps:
- Run the command `flutter pub add flutter_stripe`
- This will add a line like this to your project's pubspec.yaml with the latest package version


For details on the latest SDK release and past versions, see the [Releases](https://github.com/flutter-stripe/flutter_stripe/releases) page on GitHub. To receive notifications when a new release is published, [watch releases for the repository](https://docs.github.com/en/github/managing-subscriptions-and-notifications-on-github/managing-subscriptions-for-activity-on-github/viewing-your-subscriptions#watching-releases-for-a-repository).


When your app starts, configure the SDK with your Stripe [publishable key](https://dashboard.stripe.com/) so that it can make requests to the Stripe API.

```dart
void main() async {
Stripe.publishableKey = stripePublishableKey;
runApp(const App());
}
```

Use your [test mode](https://stripe.com/docs/keys#obtain-api-keys) keys while you test and develop, and your [live mode](https://stripe.com/docs/keys#test-live-modes) keys when you publish your app.

## 2. Create an account holder. [Server Side]

To attach data to an account holder you must first create one.
For detailed api instructions checkout the [official docs](https://stripe.com/docs/financial-connections/other-data-powered-products?platform=react-native#create-a-customer).


## 3. Create a Financial connections session [Server Side]
Before you can retrieve data from a user's bank account through Stripe financial connections, your user must authenticate their account with the authentication flow.

[Click here to learn more how to setup a session](https://stripe.com/docs/financial-connections/other-data-powered-products?platform=react-native#create-a-session).

## 4. Collect a financials account [Client Side]

On the client side you need to receive the sessionsecret in order to start the authorisation flow on the mobile. The example code looks like this:

```dart
Future<void> _collectAccount(BuildContext context) async {
// Precondition:
// 1. Make sure to create a financial connection session on the backend and
// forward the client secret of the session to the app.
final result = await retrieveSessionClientSecret();
final clientSecret = await result['clientSecret'];
// 2. use the client secret to confirm the payment and handle the result.
try {
final result = await Stripe.instance.collectFinancialConnectionsAccounts(
clientSecret: clientSecret,
);
setState(() {
response = result.toString();
});
} on Exception catch (e) {
if (e is StripeException) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Error from Stripe: ${e.error.localizedMessage}'),
),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Unforeseen error: ${e}'),
),
);
}
}
}
@override
Widget build(BuildContext context) {
return ExampleScaffold(
title: 'Financial connections',
tags: ['Financial connections'],
padding: EdgeInsets.all(16),
children: [
LoadingButton(
onPressed: () async {
await _collectAccount(context);
},
text: 'Collect financial account',
),
Divider(),
SizedBox(height: 20),
ResponseCard(response: response),
],
);
}
```

The `collectFinancialConnectionsAccounts` method from the Flutter Stripe sdk returns a future that completes when the users completes the modal authentication flow. The result is in case if success a `FinancialConnectionSessionResult` or in case of failure (or cancellation) a `StripeException`.
8 changes: 4 additions & 4 deletions example/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion 31
compileSdkVersion 33

sourceSets {
main.java.srcDirs += 'src/main/kotlin'
Expand All @@ -36,7 +36,7 @@ android {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.flutter.stripe.example"
minSdkVersion 21
targetSdkVersion 31
targetSdkVersion 33
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
Expand All @@ -60,6 +60,6 @@ dependencies {
implementation 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:6.7.0'
implementation 'com.google.android.gms:play-services-wallet:19.1.0'
implementation 'com.stripe:stripe-wechatpay:17.1.0'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
androidTestImplementation 'androidx.test:runner:1.4.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
47 changes: 46 additions & 1 deletion example/integration_test/payment_method_test.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import 'dart:convert';
import 'dart:io';

import 'package:flutter_stripe/flutter_stripe.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:http/http.dart' as http;
import 'package:integration_test/integration_test.dart';

import '.env.dart';
import 'ip.dart';

const billingDetails = BillingDetails(
email: 'email@flutterstripe.com',
Expand All @@ -27,7 +30,31 @@ void main() {
Stripe.urlScheme = 'flutterstripe';

group('PaymentMethod', () {
testWidgets('card', (tester) async {
testWidgets('confirmPayment', (tester) async {
final clientSecret = await fetchPaymentIntentClientSecret();

await Stripe.instance.dangerouslyUpdateCardDetails(CardDetails(
number: '4242424242424242',
cvc: '424',
expirationMonth: 04,
expirationYear: 2025,
));
final paymentIntent = await Stripe.instance.confirmPayment(
clientSecret['clientSecret'],
PaymentMethodParams.card(
paymentMethodData: PaymentMethodData(
billingDetails: billingDetails,
),
options: PaymentMethodOptions(
setupFutureUsage: null,
),
),
);

expect(paymentIntent.id, startsWith('pi_'));
});

testWidgets('card confirm', (tester) async {
await Stripe.instance.dangerouslyUpdateCardDetails(CardDetails(
number: '4242424242424242',
cvc: '424',
Expand Down Expand Up @@ -163,3 +190,21 @@ void main() {
});
});
}

Future<Map<String, dynamic>> fetchPaymentIntentClientSecret() async {
final ipAddress = kApiUrl.split('\n').last.trim();
final url = Uri.parse('http://$ipAddress:4242/create-payment-intent');
final response = await http.post(
url,
headers: {
'Content-Type': 'application/json',
},
body: json.encode({
'currency': 'usd',
'amount': 1099,
'payment_method_types': ['card'],
'request_three_d_secure': 'any',
}),
);
return json.decode(response.body);
}
58 changes: 32 additions & 26 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,33 +1,36 @@
PODS:
- Flutter (1.0.0)
- integration_test (0.0.1):
- Flutter
- pay_ios (0.0.1):
- Flutter
- Stripe (22.5.1):
- Stripe/Stripe3DS2 (= 22.5.1)
- StripeApplePay (= 22.5.1)
- StripeCore (= 22.5.1)
- StripeUICore (= 22.5.1)
- Stripe/Stripe3DS2 (22.5.1):
- StripeApplePay (= 22.5.1)
- StripeCore (= 22.5.1)
- StripeUICore (= 22.5.1)
- Stripe (22.7.0):
- Stripe/Stripe3DS2 (= 22.7.0)
- StripeApplePay (= 22.7.0)
- StripeCore (= 22.7.0)
- StripeUICore (= 22.7.0)
- Stripe/Stripe3DS2 (22.7.0):
- StripeApplePay (= 22.7.0)
- StripeCore (= 22.7.0)
- StripeUICore (= 22.7.0)
- stripe_ios (0.0.1):
- Flutter
- Stripe (~> 22.5.1)
- StripeFinancialConnections (~> 22.5.1)
- StripeApplePay (22.5.1):
- StripeCore (= 22.5.1)
- StripeCore (22.5.1)
- StripeFinancialConnections (22.5.1):
- StripeCore (= 22.5.1)
- StripeUICore (= 22.5.1)
- StripeUICore (22.5.1):
- StripeCore (= 22.5.1)
- Stripe (~> 22.7.0)
- StripeFinancialConnections (~> 22.7.0)
- StripeApplePay (22.7.0):
- StripeCore (= 22.7.0)
- StripeCore (22.7.0)
- StripeFinancialConnections (22.7.0):
- StripeCore (= 22.7.0)
- StripeUICore (= 22.7.0)
- StripeUICore (22.7.0):
- StripeCore (= 22.7.0)
- webview_flutter_wkwebview (0.0.1):
- Flutter

DEPENDENCIES:
- Flutter (from `Flutter`)
- integration_test (from `.symlinks/plugins/integration_test/ios`)
- pay_ios (from `.symlinks/plugins/pay_ios/ios`)
- stripe_ios (from `.symlinks/plugins/stripe_ios/ios`)
- webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`)
Expand All @@ -43,6 +46,8 @@ SPEC REPOS:
EXTERNAL SOURCES:
Flutter:
:path: Flutter
integration_test:
:path: ".symlinks/plugins/integration_test/ios"
pay_ios:
:path: ".symlinks/plugins/pay_ios/ios"
stripe_ios:
Expand All @@ -52,15 +57,16 @@ EXTERNAL SOURCES:

SPEC CHECKSUMS:
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
integration_test: a1e7d09bd98eca2fc37aefd79d4f41ad37bdbbe5
pay_ios: 8c7beb9c61d885f3f51b61f75f8793023fc8843a
Stripe: 2b2decd03146e08a350960966d41f3028c2eac29
stripe_ios: e94186250816de030881ced3399154eab186e439
StripeApplePay: b14f06ac6fc24b56704c1e598149ed0cc45e166f
StripeCore: 4833738f2ca4336712f279f3c2867a0a7eb67c93
StripeFinancialConnections: 982115b82af429968d8aa78d329a42ed7ba3feab
StripeUICore: 08c1efbd7e3c54ee7fa74334a37a1d4c08ba944d
Stripe: 464637e1fe036d69343c8b62f96d38c98efc4584
stripe_ios: a0caca0ef103a32909183c62a652a91a0773b443
StripeApplePay: 19c54b75a272ec9d9b99f34cdec0a84cf64fad8c
StripeCore: 42478ef61de37f1b85a4e1ac9d61bcf776bd2e2f
StripeFinancialConnections: e4d7ae81c67b4c32ed46a22f1841abb319bb8e24
StripeUICore: a8748e6c865f0b0e1e6bb767667f3b132977b033
webview_flutter_wkwebview: 005fbd90c888a42c5690919a1527ecc6649e1162

PODFILE CHECKSUM: 4e8f8b2be68aeea4c0d5beb6ff1e79fface1d048
PODFILE CHECKSUM: 7be2f5f74864d463a8ad433546ed1de7e0f29aef

COCOAPODS: 1.11.3
6 changes: 2 additions & 4 deletions example/lib/screens/card_payments/webhook_payment_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,9 @@ class _WebhookPaymentScreenState extends State<WebhookPaymentScreen> {
'Content-Type': 'application/json',
},
body: json.encode({
'email': _email,
'currency': 'usd',
'items': [
{'id': 'id'}
],
'amount': 1099,
'payment_method_types': ['card'],
'request_three_d_secure': 'any',
}),
);
Expand Down
Loading

0 comments on commit b95e979

Please sign in to comment.