From 26fd2745e5c731c26f06902b1f9ba060b137da60 Mon Sep 17 00:00:00 2001
From: Remon <>
Date: Wed, 11 Oct 2023 20:21:42 +0100
Subject: [PATCH] DOC: customer sheet
---
README.md | 2 +
docs.json | 3 +
docs/customer_sheet.mdx | 186 ++++++++++++++++++
.../customer_sheet/customer_sheet_screen.dart | 4 +-
packages/stripe/README.md | 2 +
5 files changed, 195 insertions(+), 2 deletions(-)
create mode 100644 docs/customer_sheet.mdx
diff --git a/README.md b/README.md
index 6f0f11a91..bb14fb34b 100644
--- a/README.md
+++ b/README.md
@@ -92,6 +92,8 @@ Payment sheet | Easy | Our recommended way of handling payments. It off
Cardfield | Medium | Single line cardfield. Offers more flexibility but has less built-in functionality. | [docs](https://docs.page/flutter-stripe/flutter_stripe/card_field) |
Card form | Medium | Similar as the cardfield but the entry fields are spread across multi lines | [docs](https://docs.page/flutter-stripe/flutter_stripe/card_field) |
+### Mobile elements [BETA]
+We also support the customer sheet mobile element. Check out the [docs](https://docs.page/flutter-stripe/flutter_stripe/customer_sheet) to learn more on how to set it up.
### 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.
diff --git a/docs.json b/docs.json
index 58d046c99..ebd8a89c1 100644
--- a/docs.json
+++ b/docs.json
@@ -11,6 +11,9 @@
["CardFormField", "/card_field"]
]
],
+ ["Mobile elements",
+ ["Customer Sheet", "/customer_sheet"]
+ ],
["Regional payments", [
["ACH direct debit", "/ach"],
["Ideal", "/ideal"]
diff --git a/docs/customer_sheet.mdx b/docs/customer_sheet.mdx
new file mode 100644
index 000000000..0dc23e636
--- /dev/null
+++ b/docs/customer_sheet.mdx
@@ -0,0 +1,186 @@
+---
+title: Customer sheet
+description: Offer a pre-built UI for your customers to manage their saved payment methods.
+---
+
+# Mobile elements - Customer Sheet
+
+### Let customers manage their own payments.
+
+
+
+Important the customer sheet is in Beta so it is not guaranteed to work under all circumstances.
+
+## 1. Set up Stripe [Server Side] [Client Side]
+
+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 here](https://stripe.com/docs/payments/accept-a-payment?platform=ios&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 commmand `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. Add an enpoint [Server Side]
+
+First, you need a Stripe account. [Register now](https://dashboard.stripe.com/register).
+
+#### Server-side
+
+This integration uses three Stripe API objects:
+
+1. A [PaymentIntent](https://stripe.com/docs/api/payment_intents). Stripe uses this to represent your intent to collect payment from a customer, tracking your charge attempts and payment state changes throughout the process.
+
+2. A [Customer](https://stripe.com/docs/api/customers) (optional). To set up a card for future payments, it must be attached to a Customer. Create a Customer object when your customer creates an account with your business. If your customer is making a payment as a guest, you can create a Customer object before payment and associate it with your own internal representation of the customer’s account later.
+
+3. A Customer Ephemeral Key (optional). Information on the Customer object is sensitive, and can’t be retrieved directly from an app. An Ephemeral Key grants the SDK temporary access to the Customer.
+
+>> If you never save cards to a Customer and don’t allow returning Customers to reuse saved cards, you can omit the Customer and Customer Ephemeral Key objects from your integration.
+
+For security reasons, your app can’t create these objects. Instead, add an endpoint on your server that:
+
+1. Retrieves the Customer, or creates a new one.
+2. Creates an Ephemeral Key for the Customer.
+3. Creates a PaymentIntent, passing the Customer id.
+4. Returns the Payment Intent’s [client secret](https://stripe.com/docs/api/payment_intents/object#payment_intent_object-client_secret), the Ephemeral Key’s secret, and the Customer’s id to your app.
+
+Check examples implementations for your server [here](https://stripe.com/docs/payments/accept-a-payment?platform=ios#add-server-endpoint)
+
+## 3. Collect customer details [Client Side]
+
+First initialize the customer sheet
+
+```dart
+ Future initCustomerSheet() async {
+ try {
+ // 1. retrieve customer from backend.
+ final data = await _createTestCustomerSheet();
+
+ // create some billingdetails
+ final billingDetails = BillingDetails(
+ name: 'Flutter Stripe',
+ email: 'email@stripe.com',
+ phone: '+48888000888',
+ address: Address(
+ city: 'Houston',
+ country: 'US',
+ line1: '1459 Circle Drive',
+ line2: '',
+ state: 'Texas',
+ postalCode: '77063',
+ ),
+ ); // mocked data for tests
+
+ // 2. initialize the customer sheet
+ await Stripe.instance.initCustomerSheet(
+ customerSheetInitParams: CustomerSheetInitParams(
+ // Main params
+ setupIntentClientSecret: data['setupIntent'],
+ merchantDisplayName: 'Flutter Stripe Store Demo',
+ // Customer params
+ customerId: data['customer'],
+ customerEphemeralKeySecret: data['ephemeralKeySecret'],
+ style: ThemeMode.system,
+ defaultBillingDetails: billingDetails,
+ ),
+ );
+ setState(() {
+ step = 1;
+ });
+ } catch (e) {
+ ScaffoldMessenger.of(context).showSnackBar(
+ SnackBar(content: Text('Error: $e')),
+ );
+ rethrow;
+ }
+ }
+ ```
+
+ Then you can show the customer sheet
+
+ ```dart
+ Future confirmCustomerSheet() async {
+ try {
+ // 3. display the customer sheet.
+ final result = await Stripe.instance.presentCustomerSheet();
+
+ setState(() {
+ step = 0;
+ });
+
+ ScaffoldMessenger.of(context).showSnackBar(
+ SnackBar(
+ content: Text(
+ 'Payment succesfully modified option selected: ${result?.paymentOption?.label}}'),
+ ),
+ );
+ } 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}'),
+ ),
+ );
+ }
+ }
+ }
+ ```
+
+## 3. Optional configuration
+
+### Change appearance
+
+It is possible to change the appearance of the customer sheet.
+
+```dart
+ await Stripe.instance.initCustomerSheet(
+ appearance: PaymentSheetAppearance(
+ colors: PaymentSheetAppearanceColors(
+ background: Colors.lightBlue,
+ primary: Colors.blue,
+ componentBorder: Colors.red,
+ ),
+ shapes: PaymentSheetShape(
+ borderWidth: 4,
+ shadow: PaymentSheetShadowParams(color: Colors.red),
+ ),
+ primaryButton: PaymentSheetPrimaryButtonAppearance(
+ shapes: PaymentSheetPrimaryButtonShape(blurRadius: 8),
+ colors: PaymentSheetPrimaryButtonTheme(
+ light: PaymentSheetPrimaryButtonThemeColors(
+ background: Color.fromARGB(255, 231, 235, 30),
+ text: Color.fromARGB(255, 235, 92, 30),
+ border: Color.fromARGB(255, 235, 92, 30),
+ ),
+ ),
+ ),
+ ),
+);
+```
diff --git a/example/lib/screens/customer_sheet/customer_sheet_screen.dart b/example/lib/screens/customer_sheet/customer_sheet_screen.dart
index df982ba3f..4410a98d6 100644
--- a/example/lib/screens/customer_sheet/customer_sheet_screen.dart
+++ b/example/lib/screens/customer_sheet/customer_sheet_screen.dart
@@ -83,7 +83,7 @@ class _CustomerSheetScreenState extends State {
),
); // mocked data for tests
- // 2. initialize the payment sheet
+ // 2. initialize the customer sheet
await Stripe.instance.initCustomerSheet(
customerSheetInitParams: CustomerSheetInitParams(
// Main params
@@ -119,7 +119,7 @@ class _CustomerSheetScreenState extends State {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
- 'Payment succesfully completed option selected: ${result?.paymentOption?.label}}'),
+ 'Payment preferences modfied completed option selected: ${result?.paymentOption?.label}}'),
),
);
} on Exception catch (e) {
diff --git a/packages/stripe/README.md b/packages/stripe/README.md
index 6f0f11a91..bb14fb34b 100644
--- a/packages/stripe/README.md
+++ b/packages/stripe/README.md
@@ -92,6 +92,8 @@ Payment sheet | Easy | Our recommended way of handling payments. It off
Cardfield | Medium | Single line cardfield. Offers more flexibility but has less built-in functionality. | [docs](https://docs.page/flutter-stripe/flutter_stripe/card_field) |
Card form | Medium | Similar as the cardfield but the entry fields are spread across multi lines | [docs](https://docs.page/flutter-stripe/flutter_stripe/card_field) |
+### Mobile elements [BETA]
+We also support the customer sheet mobile element. Check out the [docs](https://docs.page/flutter-stripe/flutter_stripe/customer_sheet) to learn more on how to set it up.
### 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.