Skip to content

Commit 458ae0b

Browse files
* Add payment sheet guide * Update sidebar docs * Revert sheet page * Update sheet.mdx * add troubleshooting section * update sheet documentation to latest implementation * add docs for handling ideal payment * pr review fixes Co-authored-by: Jaime Blasco <[email protected]>
1 parent f061544 commit 458ae0b

File tree

5 files changed

+650
-0
lines changed

5 files changed

+650
-0
lines changed

docs.json

+9
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@
44
"logo" : "https://user-images.githubusercontent.com/19904063/116995247-20519e80-acda-11eb-8e1b-7d0efbd193ad.png",
55
"sidebar": [
66
["Overview", "/"],
7+
["Accept a Payment", [
8+
["Payment Sheet", "/sheet"]
9+
]
10+
],
11+
["Regional payments", [
12+
["Ideal", "/ideal"]
13+
]
14+
],
15+
["Troubleshooting", "/troubleshooting"],
716
["Api Reference", "https://pub.dev/documentation/flutter_stripe/latest/flutter_stripe/flutter_stripe-library.html"]
817
]
918
}
107 KB
Loading

docs/ideal.mdx

+197
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
---
2+
title: Ideal payment
3+
description: Accept an Ideal payment
4+
---
5+
6+
# Accept a payment - Ideal
7+
8+
### Securely handling ideal payments
9+
10+
<img src="https://b.stripecdn.com/docs-statics-srv/assets/bd5ffc39f955d37bb53ef7d854ae4474.png" height="36" />
11+
12+
Ideal is a payment method that is a common payment method in the Netherlands.
13+
14+
This integration combines all of the steps required to creating a payment intent with Ideal as well as handling the result.
15+
16+
17+
## 1. Create
18+
19+
First, you need a Stripe account. [Register now](https://dashboard.stripe.com/register).
20+
21+
#### Server-side
22+
23+
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 Ideal payment here](https://stripe.com/docs/payments/ideal/accept-a-payment?platform=react-native#react-native-setup-server-side). For a full list of supported banks check [here](https://stripe.com/docs/payments/ideal/accept-a-payment?platform=ios#bank-reference).
24+
25+
#### Client-side
26+
27+
The Flutter SDK is open source, fully documented.
28+
29+
To install the SDK, follow these steps:
30+
- Run the commmand `flutter pub add flutter_stripe`
31+
- This will add a line like this to your project's pubspec.yaml with the latest package version
32+
33+
34+
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).
35+
36+
37+
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.
38+
39+
```dart
40+
void main() async {
41+
Stripe.publishableKey = stripePublishableKey;
42+
runApp(const App());
43+
}
44+
```
45+
46+
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.
47+
48+
## 2. Add an endpoint [Server Side]
49+
50+
First you need to create a `PaymentIntent` on your backend server. A paymentintent is an object that represents your intent to collect a payment from a customer and tracks the lifecycle of the payment process through each stage.
51+
52+
Checkout the example implementation for your server in the [official stripe docs](https://stripe.com/docs/payments/ideal/accept-a-payment?platform=react-native#react-native-create-payment-intent)
53+
54+
Returns the Payment Intent’s [client secret](https://stripe.com/docs/api/payment_intents/object#payment_intent_object-client_secret), to your app.
55+
56+
## 3. Collect the payment details [Client Side]
57+
58+
There are 2 ways to collect payment details in the Stripe sdk:
59+
- By using the payment sheet
60+
- Using the Sdk's webview and present the bank's website or app.
61+
62+
### By using the payment sheet
63+
Before displaying the payment sheet, your checkout page should:
64+
65+
- Show the products being purchased and the total amount
66+
- Collect any required shipping information
67+
- Include a checkout button to present Stripe’s UI
68+
69+
Next, integrate Stripe’s prebuilt payment UI into your app’s checkout.
70+
71+
First you need to inititalize the payment sheet
72+
73+
```dart
74+
Future<void> initPaymentSheet() async {
75+
try {
76+
// 1. create payment intent on the server
77+
final data = await _createTestPaymentSheet();
78+
79+
// 2. initialize the payment sheet
80+
await Stripe.instance.initPaymentSheet(
81+
paymentSheetParameters: SetupPaymentSheetParameters(
82+
// Enable custom flow
83+
customFlow: true,
84+
// Main params
85+
merchantDisplayName: 'Flutter Stripe Store Demo',
86+
paymentIntentClientSecret: data['paymentIntent'],
87+
// Customer keys
88+
customerEphemeralKeySecret: data['ephemeralKey'],
89+
customerId: data['customer'],
90+
// Extra options
91+
testEnv: true,
92+
applePay: true,
93+
googlePay: true,
94+
style: ThemeMode.dark,
95+
merchantCountryCode: 'DE',
96+
),
97+
);
98+
setState(() {
99+
_ready = true;
100+
});
101+
} catch (e) {
102+
ScaffoldMessenger.of(context).showSnackBar(
103+
SnackBar(content: Text('Error: $e')),
104+
);
105+
rethrow;
106+
}
107+
}
108+
```
109+
110+
When the customer taps a **Checkout** button, call present to present the payment sheet. After the customer completes the payment, the sheet is dismissed.
111+
```dart
112+
await Stripe.instance.presentPaymentSheet();
113+
```
114+
115+
Unless your business model requires immediate payment (e.g., an on-demand service), don’t assume you have received payment at this point. Instead, inform the customer that you confirmed their order and notify them by email when you fulfill their order in the next step.
116+
117+
### Using the Sdk's webview
118+
119+
#### Step1: configure the callback url
120+
121+
The Stripe sdk specificies `safepay/` as the host for the return URL for bank redirect methods. After the customer completes the payment this callback url will be called using your custom url scheme.
122+
To specify a custom url scheme and how to handle it checkout the [official Flutter docs](https://docs.flutter.dev/development/ui/navigation/deep-linking).
123+
124+
After you have specified the custom scheme make sure to specify it in the initialization parameters of the Flutter Stripe sdk
125+
126+
```dart
127+
Stripe.publishableKey = stripePublishableKey;
128+
Stripe.urlScheme = 'flutterstripe';
129+
await Stripe.instance.applySettings();
130+
```
131+
132+
#### Step2: Create a screen that opens the webview
133+
134+
Unless your business model requires immediate payment (e.g., an on-demand service), don’t assume you have received payment at this point. Instead, inform the customer that you confirmed their order and notify them by email when you fulfill their order in the next step.
135+
Before displaying the payment sheet, your checkout page should:
136+
137+
- Show the products being purchased and the total amount
138+
- Collect any required shipping information
139+
- Include a checkout button to launch the SDK's webview (see example below) and handle the result or errors.
140+
141+
``` dart
142+
Future<void> _pay(BuildContext context) async{
143+
try {
144+
await Stripe.instance.confirmPayment(
145+
clientSecret,
146+
PaymentMethodParams.ideal(bankName: kIsWeb ? 'revolut' : null),
147+
);
148+
ScaffoldMessenger.of(context).showSnackBar(
149+
SnackBar(
150+
content: Text('Payment succesfully completed'),
151+
),
152+
);
153+
} on Exception catch (e) {
154+
if (e is StripeException) {
155+
ScaffoldMessenger.of(context).showSnackBar(
156+
SnackBar(
157+
content: Text('Error from Stripe: ${e.error.localizedMessage}'),
158+
),
159+
);
160+
} else {
161+
ScaffoldMessenger.of(context).showSnackBar(
162+
SnackBar(
163+
content: Text('Unforeseen error: ${e}'),
164+
),
165+
);
166+
}
167+
}
168+
}
169+
170+
@override
171+
Widget build(BuildContext context) {
172+
return ExampleScaffold(
173+
title: 'Ideal',
174+
tags: ['Payment method'],
175+
padding: EdgeInsets.all(16),
176+
children: [
177+
LoadingButton(
178+
onPressed: () async {
179+
await pay(context);
180+
},
181+
text: 'Pay',
182+
),
183+
],
184+
);
185+
}
186+
```
187+
188+
## 4. Handle post-payment events
189+
190+
Stripe sends a [`payment_intent.succeeded`](https://stripe.com/docs/api/events/types#event_types-payment_intent.succeeded) event when the payment completes. Use the Dashboard, a custom webhook, or a partner solution to receive these events and run actions, like sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow.
191+
192+
Listen for these events rather than waiting on a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes. Setting up your integration to listen for asynchronous events also makes it easier to accept more payment methods in the future. Check out our [guide to payment methods](https://stripe.com/payments/payment-methods-guide) to see the differences between all supported payment methods.
193+
194+
## 5. Test the integration
195+
196+
If you are using your test Api key stripe will show a test page after confirming the intent. You can choose yourself whether or not to authorize or fail the payment. For more info about testing check the [Stripe docs](https://stripe.com/docs/payments/ideal/accept-a-payment?platform=ios#test-your-integration).
197+

0 commit comments

Comments
 (0)