Customer Sheet
Let customers manage their own payment methods.
Note: 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.
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
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 page on GitHub. To receive notifications when a new release is published, watch releases for the repository.
When your app starts, configure the SDK with your Stripe publishable key so that it can make requests to the Stripe API.
void main() async {
Stripe.publishableKey = stripePublishableKey;
runApp(const App());
}
Use your test mode keys while you test and develop, and your live mode keys when you publish your app.
2. Add an enpoint [Server Side]
First, you need a Stripe account. Register now.
Server-side
This integration uses three Stripe API objects:
-
A PaymentIntent. Stripe uses this to represent your intent to collect payment from a customer, tracking your charge attempts and payment state changes throughout the process.
-
A Customer (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.
-
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:
- Retrieves the Customer, or creates a new one.
- Creates an Ephemeral Key for the Customer.
- Creates a PaymentIntent, passing the Customer id.
- Returns the Payment Intent’s client secret, the Ephemeral Key’s secret, and the Customer’s id to your app.
Check examples implementations for your server here
3. Initialize the Customer Sheet [Client Side]
First initialize the customer sheet using the CustomerSheetInitParams.adapter() factory:
Future<void> initCustomerSheet() async {
try {
// 1. Retrieve customer data from your backend
final data = await _fetchCustomerSheet();
// 2. Create billing details (optional)
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',
),
);
// 3. Initialize the customer sheet
await Stripe.instance.initCustomerSheet(
customerSheetInitParams: CustomerSheetInitParams.adapter(
// Main params
setupIntentClientSecret: data['setupIntent'],
merchantDisplayName: 'Flutter Stripe Store Demo',
// Customer params
customerId: data['customer'],
customerEphemeralKeySecret: data['ephemeralKeySecret'],
// Optional params
style: ThemeMode.system,
defaultBillingDetails: billingDetails,
allowsRemovalOfLastSavedPaymentMethod: true,
),
);
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error: $e')),
);
rethrow;
}
}
4. Present the Customer Sheet [Client Side]
After initialization, present the customer sheet to let users manage their payment methods:
Future<void> presentCustomerSheet() async {
try {
// Display the customer sheet
final result = await Stripe.instance.presentCustomerSheet();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'Payment preferences modified. 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'),
),
);
}
}
}
5. Retrieve Payment Option Selection (Optional) [Client Side]
You can also retrieve the currently selected payment option without presenting the sheet:
Future<void> getSelectedPaymentOption() async {
final result = await Stripe.instance.retrieveCustomerSheetPaymentOptionSelection();
if (result != null) {
print('Selected payment option: ${result.paymentOption?.label}');
}
}
Change Appearance
You can customize the appearance of the customer sheet by passing an appearance parameter:
await Stripe.instance.initCustomerSheet(
customerSheetInitParams: CustomerSheetInitParams.adapter(
setupIntentClientSecret: data['setupIntent'],
merchantDisplayName: 'Flutter Stripe Store Demo',
customerId: data['customer'],
customerEphemeralKeySecret: data['ephemeralKeySecret'],
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),
),
),
),
),
),
);
