How to Integrate a Payment Gateway in Flutter: A Simple Guide
Why a Payment Gateway Matters in Your Flutter App
When users click “Buy Now,” they expect the transaction to be smooth, secure, and almost invisible. A payment gateway does the heavy lifting—encrypting card data, handling authorizations, and communicating with banks or wallets. Skipping this step or choosing a flimsy solution can lead to broken purchases, chargebacks, and a damaged reputation.
In the Flutter ecosystem, the choice of gateway often boils down to two things: ease of integration and platform‑agnostic support. Whether you target iOS, Android, or the web, the gateway you pick should feel native to each platform without forcing you to write separate native code for every checkout flow.
Picking the Right Gateway
Not every gateway is created equal. Here are a few popular options and what makes them click for Flutter developers:
- Stripe – Excellent documentation, solid web and mobile SDKs, and support for Apple Pay and Google Pay.
- PayPal / Braintree – Familiar to many users, plus built‑in fraud detection.
- Razorpay – A good fit for Indian merchants, with native support for UPI and wallets.
- Square – Strong point‑of‑sale features, ideal if you also sell offline.
Ask yourself: Do you need recurring billing? Do you plan to accept local payment methods? Do you want a single‑line checkout or a custom UI? Your answers will narrow the field quickly.
Setting Up the Project
Before touching any code, make sure your Flutter environment is fresh:
- Flutter ≥ 3.0 (stable channel)
- Android SDK ≥ 21, iOS ≥ 11
- Enable Internet permission in
AndroidManifest.xmland the appropriateNSAppTransportSecurityentries for iOS.
Run flutter doctor to verify everything is in order. A clean start saves you from cryptic build errors later on.
Integrating Stripe – A Walkthrough
1. Add the Dependency
The official package stripe_payment (or its newer cousin flutter_stripe) lives on pub.dev. Add it to pubspec.yaml:
dependencies:flutter_stripe: ^9.0.0
Run flutter pub get. The package pulls in native Android and iOS libraries, so you won’t have to edit Gradle or CocoaPods manually.
2. Obtain API Keys
Log into the Stripe dashboard, create a new project, and copy the Publishable Key (for the client) and the Secret Key (for your server). Never embed the secret key in the Flutter code; it belongs on a backend you control.
3. Initialize the SDK
Call the initialization method early, typically in main():
void main() async {WidgetsFlutterBinding.ensureInitialized();
Stripe.publishableKey = 'pk_test_…';
await Stripe.instance.applySettings();
runApp(MyApp());
}
4. Create a Payment Intent on the Server
The client asks your server for a payment intent. A minimal Node.js snippet looks like this:
const stripe = require('stripe')('sk_test_…');app.post('/create-intent', async (req, res) => {
const intent = await stripe.paymentIntents.create({
amount: 1999, // cents
currency: 'usd',
});
res.json({ clientSecret: intent.client_secret });
});
This endpoint returns the clientSecret, which the Flutter app will use to complete the transaction.
5. Collect Card Details
Flutter Stripe offers a ready‑made widget:
CardField(onCardChanged: (card) {
// enable the pay button when card is complete
},
);
If you prefer a custom UI, you can call Stripe.instance.createToken with the card data you gather yourself.
6. Confirm the Payment
When the user taps “Pay,” send a request to your /create-intent endpoint, fetch the clientSecret, then:
await Stripe.instance.confirmPayment(paymentIntentClientSecret: clientSecret,
data: PaymentMethodParams.card(),
);
If the call succeeds, the payment is captured. Handle errors—declined cards, network glitches—by showing a friendly toast or dialog.
Testing the Flow
Stripe provides test card numbers (4242 4242 4242 4242, for example). Run the app in debug mode, enter a test number, and watch the success message appear. Remember to switch to live keys before publishing.
Beyond the Basics: Web and Apple/Google Pay
If your Flutter project also targets the web, the flutter_stripe package supports a JavaScript‑based checkout. Enable it in web/index.html and pass the same clientSecret to Stripe.confirmCardPayment.
For Apple Pay and Google Pay, you need to register the merchant IDs with the respective platforms and add a few extra lines to the initialization:
await Stripe.instance.applySettings(ApplePayConfig(merchantId: 'merchant.com.example'),
GooglePayConfig(environment: 'TEST'),
);
These one‑liners unlock the native payment sheets, which are faster and more trustworthy for users who already have cards saved in their wallets.
Alternative Gateways: Quick Tips
Not every project fits Stripe’s model. Here’s a cheat sheet for the other big players:
- PayPal/Braintree: Use the
braintree_paymentplugin. You’ll need a server‑side token generation endpoint similar to Stripe’s intent creation. - Razorpay: The
razorpay_flutterplugin bundles a native checkout UI; just pass the amount, currency, and order ID from your backend. - Square: Their SDK focuses on in‑store devices, but the
square_in_app_paymentspackage works for mobile apps with a simple token‑exchange flow.
All of them share a common pattern: client obtains a short‑lived token from a secure server, then hands it to the native SDK to finish the transaction.
Handling Edge Cases
Real‑world payments rarely go perfectly. Keep these scenarios in mind:
- Network interruptions – Store the
clientSecrettemporarily; you can retry the confirmation later. - Currency mismatches – Display the chosen currency prominently, and validate it server‑side before creating an intent.
- 3‑D Secure challenges – Most modern SDKs handle the redirect automatically, but you should listen for a
PaymentIntentResultthat indicates a further step is required.
Wrapping Up the Integration
At its core, a Flutter payment integration is a dance between three parts: the Flutter UI, a tiny backend that talks to the gateway, and the native SDK that seals the deal. Once you’ve wired those three together, adding extra payment methods or subscriptions is just a matter of extending the same endpoints.
Take the time to test on real devices, watch logs for obscure error codes, and keep your secret keys safely hidden. With those habits in place, your app will handle money as gracefully as it handles animations.