Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
114 changes: 114 additions & 0 deletions example/lib/screens/card_payments/web_card_field_customization.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import 'package:flutter/material.dart';
import 'package:flutter_stripe/flutter_stripe.dart';

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

@override
State<WebCardFieldCustomizationExample> createState() => _WebCardFieldCustomizationExampleState();
}

class _WebCardFieldCustomizationExampleState extends State<WebCardFieldCustomizationExample> {
late String _fontFamily = 'Montserrat';
late String _cssSrc = 'https://fonts.googleapis.com/css?family=Montserrat';

final _cardEditController = CardEditController();
final _cardFocusNode = FocusNode();

late final _fontFamilyController = TextEditingController(text: _fontFamily);
late final _cssSrcController = TextEditingController(text: _cssSrc);

@override
void initState() {
super.initState();
_cardFocusNode.addListener(_onCardFocusChange);
}

@override
void dispose() {
_cardFocusNode.removeListener(_onCardFocusChange);
_cardFocusNode.dispose();
_fontFamilyController.dispose();
_cssSrcController.dispose();
super.dispose();
}

void _onCardFocusChange() {
print('Card focus: ${_cardFocusNode.hasFocus}');
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
children: [
Container(
height: 150,
alignment: Alignment.center,
padding: EdgeInsets.symmetric(vertical: 20, horizontal: 20),
child: CardField(
controller: _cardEditController,
focusNode: _cardFocusNode,
autofocus: true,
enablePostalCode: true,
style: TextStyle(
fontSize: 20.0,
fontFamily: _fontFamily,
color: Color(0xFF272B2B),
),
placeholderColor: Colors.blueGrey,
onCardChanged: (_) {},
webFonts: [
WebFont(
family: _fontFamily,
cssSrc: _cssSrc,
),
],
),
),
Divider(height: 1),
Padding(
padding: EdgeInsets.all(16),
child: Column(
children: [
TextField(
controller: _fontFamilyController,
decoration: InputDecoration(
labelText: 'Font Family',
),
onChanged: (value) => setState(() => _fontFamily = value),
),
TextField(
controller: _cssSrcController,
decoration: InputDecoration(
labelText: 'CSS Source',
),
onChanged: (value) => setState(() => _cssSrc = value),
),
SizedBox(height: 16),
Row(
children: [
ElevatedButton(
onPressed: () {
_cardEditController.focus();
},
child: Text('Request Focus'),
),
const SizedBox(width: 10),
ElevatedButton(
onPressed: () {
FocusScope.of(context).unfocus();
},
child: Text('Lose Focus'),
),
],
),
],
),
),
],
),
);
}
}
17 changes: 8 additions & 9 deletions example/lib/screens/screens.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:stripe_example/screens/card_payments/web_card_field_customization.dart';
import 'package:stripe_example/screens/checkout/checkout_screen.dart';
import 'package:stripe_example/screens/customer_sheet/customer_sheet_screen.dart';
import 'package:stripe_example/screens/payment_sheet/payment_element/payment_element.dart';
Expand Down Expand Up @@ -54,8 +55,7 @@ class ExampleSection extends StatelessWidget {
initiallyExpanded: expanded,
childrenPadding: EdgeInsets.only(left: 20),
title: Text(title),
children:
ListTile.divideTiles(tiles: children, context: context).toList(),
children: ListTile.divideTiles(tiles: children, context: context).toList(),
);
}
}
Expand Down Expand Up @@ -121,7 +121,6 @@ class Example extends StatelessWidget {
],
),
],
expanded: true,
),
ExampleSection(title: 'Customer sheet', children: [
Example(
Expand All @@ -133,9 +132,12 @@ class Example extends StatelessWidget {
ExampleSection(
title: 'Card Payments',
children: [
Example(
title: 'Web Card Field Customization',
builder: (c) => WebCardFieldCustomizationExample(),
),
Example(
title: 'Simple - Using webhooks',
style: TextStyle(fontWeight: FontWeight.w600),
builder: (c) => WebhookPaymentScreen(),
),
Example(
Expand All @@ -157,6 +159,7 @@ class Example extends StatelessWidget {
platformsSupported: [DevicePlatform.android, DevicePlatform.ios],
),
],
expanded: true,
),
ExampleSection(
title: 'Wallets',
Expand Down Expand Up @@ -356,11 +359,7 @@ class Example extends StatelessWidget {
Example(
title: 'Checkout',
builder: (c) => CheckoutScreenExample(),
platformsSupported: [
DevicePlatform.android,
DevicePlatform.ios,
DevicePlatform.web
],
platformsSupported: [DevicePlatform.android, DevicePlatform.ios, DevicePlatform.web],
),
];
}
19 changes: 9 additions & 10 deletions example/lib/screens/themes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class _ThemeCardExampleState extends State<ThemeCardExample> {
body: Column(
children: [
Theme(
data: ThemeData(),
data: theme,
child: Container(
height: 150,
alignment: Alignment.center,
Expand All @@ -74,20 +74,19 @@ class _ThemeCardExampleState extends State<ThemeCardExample> {
child: CardField(
autofocus: true,
enablePostalCode: postalCodeEnabled,
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.w400,
fontFamily: 'Brandon Text',
color: Color(0xFF272B2B),
),
placeholderColor: Color(0xFF636D6D),
style: TextStyle(fontFamily: 'Montserrat'),
onCardChanged: (_) {},
decoration: InputDecoration(
labelText: theme.inputDecorationTheme.floatingLabelBehavior ==
FloatingLabelBehavior.always
labelText: theme.inputDecorationTheme.floatingLabelBehavior == FloatingLabelBehavior.always
? 'Card Field'
: null,
),
webFonts: [
WebFont(
family: 'Montserrat',
cssSrc: 'https://fonts.googleapis.com/css?family=Montserrat',
),
],
),
),
),
Expand Down
11 changes: 10 additions & 1 deletion packages/stripe/lib/src/widgets/card_field.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ class CardField extends StatefulWidget {
this.postalCodeHintText,
this.controller,
this.androidPlatformViewRenderType = AndroidPlatformViewRenderType.expensiveAndroidView,
this.webFonts,
this.focusNode,
}) : super(key: key);

/// Decoration related to the input fields.
Expand Down Expand Up @@ -113,13 +115,19 @@ class CardField extends StatefulWidget {
/// Defaults to [AndroidPlatformViewRenderType.expensiveAndroidView]
final AndroidPlatformViewRenderType androidPlatformViewRenderType;

final List<WebFont>? webFonts;

final FocusNode? focusNode;

@override
// ignore: library_private_types_in_public_api
_CardFieldState createState() => _CardFieldState();
}

class _CardFieldState extends State<CardField> {
final FocusNode _node = FocusNode(debugLabel: 'CardField', descendantsAreFocusable: false);
late final _node = (widget.focusNode ?? FocusNode())
..debugLabel = 'CardField'
..descendantsAreFocusable = false;

CardEditController? _fallbackContoller;
CardEditController get controller {
Expand Down Expand Up @@ -184,6 +192,7 @@ class _CardFieldState extends State<CardField> {
onFocus: widget.onFocus,
placeholder: placeholder,
style: style,
webFonts: widget.webFonts,
)
: CustomSingleChildLayout(
delegate: const _NegativeMarginLayout(margin: platformMargin),
Expand Down
4 changes: 4 additions & 0 deletions packages/stripe_ios/pubspec_overrides.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# melos_managed_dependency_overrides: stripe_android,stripe_ios,stripe_platform_interface
dependency_overrides:
stripe_platform_interface:
path: ../stripe_platform_interface
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import 'package:flutter/foundation.dart';
import 'package:stripe_platform_interface/src/models/card_field_input.dart';

const String kDebugPCIMessage =
'Handling card data manually will break PCI compliance provided by Stripe. '
const String kDebugPCIMessage = 'Handling card data manually will break PCI compliance provided by Stripe. '
'Please make sure you understand the severe consecuences of it. '
'https://stripe.com/docs/security/guide#validating-pci-compliance. \n'
'To handle PCI compliance yourself and allow to edit card data programatically,'
Expand All @@ -28,17 +27,15 @@ abstract class CardFieldContext {
}
}

void updateCardDetails(
CardFieldInputDetails value, CardEditController controller) {
void updateCardDetails(CardFieldInputDetails value, CardEditController controller) {
controller._updateDetails(value);
}
}

class CardEditController extends ChangeNotifier {
CardEditController({CardFieldInputDetails? initialDetails})
: initalDetails = initialDetails,
_details =
initialDetails ?? const CardFieldInputDetails(complete: false);
_details = initialDetails ?? const CardFieldInputDetails(complete: false);

final CardFieldInputDetails? initalDetails;
CardFieldInputDetails _details;
Expand Down Expand Up @@ -75,8 +72,7 @@ class CardEditController extends ChangeNotifier {

CardFieldContext? _context;
CardFieldContext get context {
assert(
_context != null, 'CardEditController is not attached to any CardView');
assert(_context != null, 'CardEditController is not attached to any CardView');
return _context!;
}
}
21 changes: 21 additions & 0 deletions packages/stripe_platform_interface/lib/src/models/web_font.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import 'dart:core';

class WebFont {
final String family;
final String? src;
final String? display;
final String? style;
final String? unicodeRange;
final String? weight;
final String? cssSrc;

WebFont({
required this.family,
this.src,
this.display,
this.style,
this.unicodeRange,
this.weight,
this.cssSrc,
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ abstract class StripePlatform extends PlatformInterface {
FocusNode? focusNode,
bool autofocus = false,
bool dangerouslyUpdateFullCardDetails = false,
List<WebFont>? webFonts,
}) {
throw UnimplementedError();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ export 'src/models/setup_intent.dart';
export 'src/models/three_d_secure.dart';
export 'src/models/wallet.dart';
export 'src/stripe_platform_interface.dart';
export 'src/models/web_font.dart';
2 changes: 2 additions & 0 deletions packages/stripe_web/lib/src/web_stripe.dart
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,7 @@ class WebStripe extends StripePlatform {
FocusNode? focusNode,
bool autofocus = false,
bool dangerouslyUpdateFullCardDetails = false,
List<WebFont>? webFonts,
}) {
return WebCardField(
controller: controller,
Expand All @@ -414,6 +415,7 @@ class WebStripe extends StripePlatform {
focusNode: focusNode,
autofocus: autofocus,
dangerouslyUpdateFullCardDetails: dangerouslyUpdateFullCardDetails,
webFonts: webFonts,
);
}

Expand Down
Loading