Flutter, Google’s UI toolkit for building natively compiled applications for mobile, web, and desktop from a single codebase, has gained immense popularity due to its fast development cycle and expressive UI. Integrating a payment gateway like Stripe into your Flutter app allows you to securely process payments, offering a seamless user experience. Stripe is a powerful and versatile platform, enabling you to accept various payment methods.
Why Integrate Stripe for Payments?
- Secure Transactions: Stripe handles sensitive payment data securely.
- Wide Range of Payment Methods: Supports credit cards, debit cards, and other payment methods like Apple Pay and Google Pay.
- Easy Integration: Stripe offers robust APIs and SDKs for easy integration.
- Customizable UI: Provides tools to create a custom payment UI to match your app’s design.
Prerequisites
Before you start, make sure you have the following:
- A Stripe account: If you don’t have one, sign up at stripe.com.
- Flutter SDK installed.
- An Android or iOS device/emulator for testing.
Step-by-Step Integration Guide
Here’s how to integrate Stripe for payments in your Flutter app:
Step 1: Set Up Your Flutter Project
Create a new Flutter project if you haven’t already:
flutter create stripe_payment_app
cd stripe_payment_app
Step 2: Add Dependencies
Add the flutter_stripe
package to your pubspec.yaml
file:
dependencies:
flutter:
sdk: flutter
flutter_stripe: ^9.0.0 # Use the latest version
Then, run:
flutter pub get
Step 3: Configure Stripe Keys
Initialize Stripe with your publishable key in your Flutter app. It’s best practice to keep your publishable key and secret key separate and secure. Use environment variables or a secure configuration file. Here’s how to initialize Stripe in your main.dart
file:
import 'package:flutter/material.dart';
import 'package:flutter_stripe/flutter_stripe.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
Stripe.publishableKey = "YOUR_STRIPE_PUBLISHABLE_KEY";
await Stripe.instance.applySettings();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Stripe Payment App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Stripe Payment Demo'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
// Implement Payment Functionality
},
child: Text('Pay with Stripe'),
),
),
);
}
}
Step 4: Implement Payment Functionality
Create a function to handle the payment process. This involves creating a payment intent on your server and then confirming it on the client-side (Flutter app).
Backend (Node.js Example)
First, set up a simple backend using Node.js and the Stripe SDK to create payment intents:
const express = require('express');
const stripe = require('stripe')('YOUR_STRIPE_SECRET_KEY'); // Replace with your secret key
const app = express();
const port = 3000;
app.use(express.json());
app.post('/create-payment-intent', async (req, res) => {
try {
const { amount, currency } = req.body;
const paymentIntent = await stripe.paymentIntents.create({
amount: amount,
currency: currency,
automatic_payment_methods: {
enabled: true,
},
});
res.send({
clientSecret: paymentIntent.client_secret,
});
} catch (error) {
console.error(error);
res.status(500).send({ error: error.message });
}
});
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
Flutter (Client-Side)
Now, in your Flutter app, call this endpoint and use the clientSecret
to confirm the payment:
import 'package:flutter/material.dart';
import 'package:flutter_stripe/flutter_stripe.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
class MyHomePage extends StatelessWidget {
Future initPaymentSheet() async {
try {
// 1. Create a payment intent on the server
final response = await http.post(
Uri.parse('http://localhost:3000/create-payment-intent'), // Replace with your server endpoint
headers: {'Content-Type': 'application/json'},
body: jsonEncode({
'amount': 1099, // Amount in cents
'currency': 'usd',
}),
);
final jsonResponse = jsonDecode(response.body);
// 2. Initialize the payment sheet
await Stripe.instance.initPaymentSheet(
paymentSheetParameters: PaymentSheetParameters(
paymentIntentClientSecret: jsonResponse['clientSecret'],
style: ThemeMode.system,
merchantDisplayName: 'Flutter Stripe Store Demo',
),
);
// 3. Display the payment sheet
await Stripe.instance.presentPaymentSheet();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Payment successful!')),
);
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error: $e')),
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Stripe Payment Demo'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
initPaymentSheet();
},
child: Text('Pay with Stripe'),
),
),
);
}
}
Step 5: Handle Payment Success and Errors
Ensure your app handles both successful payments and errors appropriately. Use try-catch
blocks to catch exceptions and display user-friendly messages.
Advanced Configurations
Here are a few advanced configurations you can consider:
1. Using Apple Pay and Google Pay
To accept payments via Apple Pay and Google Pay, you need to configure these payment methods in your Stripe account and enable them in your Flutter app.
import 'package:flutter_stripe/flutter_stripe.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
Stripe.publishableKey = "YOUR_STRIPE_PUBLISHABLE_KEY";
await Stripe.instance.applySettings(
settings: PaymentSheetIosSettings(
merchantDisplayName: "Example Merchant",
allowsDelayedPaymentMethods: true
),
);
runApp(MyApp());
}
2. Using PaymentMethod Widget for More Customization
If you require more customization of the payment collection process you could use PaymentMethod widget
import 'package:flutter/material.dart';
import 'package:flutter_stripe/flutter_stripe.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State {
PaymentMethod? _paymentMethod;
Future _createPaymentMethod() async {
try {
final paymentMethod = await Stripe.instance.createPaymentMethod(
params: const PaymentMethodParams.card(
paymentMethodData: PaymentMethodData(
billingDetails: BillingDetails(
email: 'email@example.com',
),
),
));
setState(() {
_paymentMethod = paymentMethod;
});
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error: $e')),
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Stripe Payment Demo'),
),
body: Center(
child: Column(
children: [
ElevatedButton(
onPressed: _createPaymentMethod,
child: const Text('Create Payment Method'),
),
Text('Payment Method: ${_paymentMethod?.id ?? 'Not Created'}')
],
)
),
);
}
}
Testing Your Integration
Stripe provides test card numbers and other testing tools to help you thoroughly test your integration before going live. Use these tools to simulate different payment scenarios and ensure your app behaves correctly.
Conclusion
Integrating Stripe for payments in your Flutter app enables secure and seamless transactions, enhancing the user experience. By following the steps outlined in this guide, you can quickly set up Stripe, process payments, and handle different payment methods. Remember to always prioritize security and adhere to best practices when handling sensitive payment data. With Stripe and Flutter, you can create powerful e-commerce applications that meet the demands of modern users.