Skip to content

Commit

Permalink
Add web plugin for beta release (#476)
Browse files Browse the repository at this point in the history
* add web support

* feat: prepare release for web

* fix: analyzer problems

* fix: address changes requested

* fix: format and update readme
  • Loading branch information
jamesblasco authored Dec 19, 2021
1 parent d439026 commit 08b7a1e
Show file tree
Hide file tree
Showing 73 changed files with 21,260 additions and 315 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ This is caused by the Stripe SDK requires the use of the AppCompat theme for the

Compatible with apps targeting iOS 11 or above.

#### Web (Experimental)

Now you can use Stripe with Flutter web! Notice right now it is highly experimental and only a subset of features is implemented.

Check the steps needed [here](https://github.com/flutter-stripe/flutter_stripe/tree/main/packages/stripe_web)


## Usage example

```dart
Expand Down
Binary file added example/assets/android.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added example/assets/apple.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added example/assets/web.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
PODS:
- Flutter (1.0.0)
- integration_test (0.0.1):
- Flutter
- pay_ios (0.0.1):
- Flutter
- Stripe (21.9.0):
Expand All @@ -15,11 +17,15 @@ PODS:
- StripeCore (21.9.0)
- StripeUICore (21.9.0):
- StripeCore (= 21.9.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`)

SPEC REPOS:
trunk:
Expand All @@ -30,18 +36,24 @@ 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:
:path: ".symlinks/plugins/stripe_ios/ios"
webview_flutter_wkwebview:
:path: ".symlinks/plugins/webview_flutter_wkwebview/ios"

SPEC CHECKSUMS:
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
integration_test: 7db6d89f336f671dcbc7563ee27a5b08f6f8aee1
pay_ios: 8c7beb9c61d885f3f51b61f75f8793023fc8843a
Stripe: 41c3d261501e1dc84755b1bdabdaae50ebf92b53
stripe_ios: fce03ba840e641cc31ff5bdb67f5d5b9c938b897
StripeCore: 2ea9531e863ef20f191a0d61f00dedb7f061baef
StripeUICore: a0f9e40520823d34c63baec0782fc4a0c7fb7484
webview_flutter_wkwebview: 005fbd90c888a42c5690919a1527ecc6649e1162

PODFILE CHECKSUM: 4e8f8b2be68aeea4c0d5beb6ff1e79fface1d048

Expand Down
17 changes: 14 additions & 3 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_stripe/flutter_stripe.dart';
import 'package:stripe_example/.env.dart';

import 'screens/checkout/checkout_screen.dart';
import 'screens/screens.dart';
import 'widgets/dismiss_focus_overlay.dart';

Expand All @@ -22,7 +22,16 @@ class App extends StatelessWidget {
return DismissFocusOverlay(
child: MaterialApp(
theme: exampleAppTheme,
home: HomePage(),
routes: {...CheckoutScreenExample.routes},
onGenerateInitialRoutes: (settings) {
print(settings);
return [
MaterialPageRoute(builder: (context) {
return HomePage();
})
];
},
navigatorObservers: [],
),
);
}
Expand Down Expand Up @@ -57,7 +66,9 @@ class _HomePageState extends State<HomePage> {

final exampleAppTheme = ThemeData(
colorScheme: ColorScheme.light(
primary: Color(0xff6058F7), secondary: Color(0xff6058F7)),
primary: Color(0xff6058F7),
secondary: Color(0xff6058F7),
),
primaryColor: Colors.white,
appBarTheme: AppBarTheme(elevation: 1),
);
108 changes: 108 additions & 0 deletions example/lib/screens/checkout/checkout_screen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import 'dart:convert';
import 'dart:developer';
import 'package:stripe_example/.env.dart';
import 'platforms/stripe_checkout.dart'
if (dart.library.js) 'platforms/stripe_checkout_web.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

import 'package:stripe_checkout/stripe_checkout.dart';
import 'package:http/http.dart' as http;

final kApiUrl = defaultTargetPlatform == TargetPlatform.android
? 'http://10.0.2.2:4242'
: 'http://localhost:4242';

class CheckoutScreenExample extends StatefulWidget {
CheckoutScreenExample({Key? key, this.title, this.snackBarText})
: super(key: key);

final String? title;

final String? snackBarText;

static final routes = {
// For Flutter web
'/success': (c) => CheckoutScreenExample(
title: 'Checkout - Done',
snackBarText: 'Paid succesfully',
),
'/canceled': (c) => CheckoutScreenExample(
title: 'Checkout - Canceled',
snackBarText: 'Checkout canceled',
),
};

@override
_CheckoutScreenExample createState() => _CheckoutScreenExample();
}

class _CheckoutScreenExample extends State<CheckoutScreenExample> {
@override
void initState() {
if (widget.snackBarText != null) {
WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(widget.snackBarText!)),
);
});
}
super.initState();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title ?? 'Checkout Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: getCheckout,
child: Text('Open Checkout'),
)
],
),
),
);
}

Future<void> getCheckout() async {
final String sessionId = await _createCheckoutSession();
final result = await redirectToCheckout(
context: context,
sessionId: sessionId,
publishableKey: stripePublishableKey,
);

if (mounted) {
final text = result.when(
success: () => 'Paid succesfully',
canceled: () => 'Checkout canceled',
error: (e) => 'Error $e');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(text)),
);
}
}

Future<String> _createCheckoutSession() async {
final url = Uri.parse('$kApiUrl/create-checkout-session');
final response = await http.post(
url,
headers: {
'Content-Type': 'application/json',
},
body: json.encode({
if (kIsWeb) 'port': getUrlPort(),
}),
);
final Map<String, dynamic> bodyResponse = json.decode(response.body);
final id = bodyResponse['id'] as String;
log('Checkout session id $id');
return id;
}
}
8 changes: 8 additions & 0 deletions example/lib/screens/checkout/platforms/stripe_checkout.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//@dart= 2.12
String getUrlPort() {
throw 'Not implemented';
}

String getReturnUrl() {
return 'Not implemented';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import 'dart:html' as html;

String getUrlPort() => html.window.location.port;

String getReturnUrl() => html.window.location.href;
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:convert';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_stripe/flutter_stripe.dart';
import 'package:http/http.dart' as http;
Expand Down Expand Up @@ -41,7 +42,7 @@ class IdealScreen extends StatelessWidget {
try {
await Stripe.instance.confirmPayment(
clientSecret,
PaymentMethodParams.ideal(),
PaymentMethodParams.ideal(bankName: kIsWeb ? 'revolut' : null),
);

ScaffoldMessenger.of(context).showSnackBar(
Expand Down
Loading

0 comments on commit 08b7a1e

Please sign in to comment.