Integrating Stripe in Flutter seems simple... until Android reminds you that it lives in its own universe of Gradle, Kotlin, and Material themes. When I started, the plugin wouldn't even initialize and would throw the typical generic "The plugin failed to initialize" error at me. Since then, I've been perfecting a clear, orderly, and, above all, proven process.
Payment gateways are among those somewhat complex developments, as is the use of databases with HiveDB, but we must implement them since they are FUNDAMENTAL pieces in our apps.
Here is the guide that would have saved me hours of failed compilation.
We will look at the steps to install the flutter stripe package in Flutter and be able to use the Stripe API within the Flutter app.
We install the dependency we are going to use via:
pubspec.yaml
dependencies:
***
flutter_stripe:The official page:
https://pub.dev/packages/flutter_stripe
Prerequisites and Necessary Versions (Gradle, Kotlin, and Android)
Before installing any package, I recommend verifying that your project meets the minimum versions. In my case, most errors simply came because the project was using Gradle 7.x and an outdated Kotlin version.
Minimum Android, Gradle, and Kotlin Version
- Stripe requires:
- Android 5.0 (API 21+)
- Kotlin 1.8.0 or higher
- Android Gradle Plugin 8+
- Gradle 8.x
- Use of Theme.AppCompat or Theme.MaterialComponents
Changing the gradle-wrapper version to level 8
It is important to note that the plugin requires several configurations; specifically, it uses Gradle level 8, which may entail applying several additional configurations.
The steps to initialize the previous plugin are as follows:
Use Android 5.0 (API level 21) and above.
Use Kotlin version 1.8.0 and above: example
Requires Android Gradle plugin 8 and higher
Using a descendant of Theme.AppCompat for your activity: example, example night theme
Using an up-to-date Android gradle build tools version: example and an up-to-date gradle version accordingly: example
Using FlutterFragmentActivity instead of FlutterActivity in MainActivity.kt: example
Add the following rules to your proguard-rules.pro file: exampleThe above is an excerpt from what is shown in the official documentation.
Your project may not have the latest Gradle versions, so you must verify and correct them if necessary; for this, we modify from:
android/gradle/wrapper/gradle-wrapper.properties
distributionUrl=https\://services.gradle.org/distributions/gradle-7.x.x-all.zipTo some available version 8. To do this, you can visit the previous page:
https://services.gradle.org/distributions
And copy one of the version 8, for example:
android/gradle/wrapper/gradle-wrapper.properties
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zipKotlin and Android Gradle Plugin (AGP) Adjustments
We must also raise the Kotlin version:
android/settings.gradle
plugins {
***
id "org.jetbrains.kotlin.android" version "1.8.0" apply false
}If you don't configure some of the previous steps, when implementing the widget to make the payment as we will see in the next section, you will see an error like the following on screen:
Stripe exception: PlatformException(flutter_stripe initialization failed, The plugin failed to initialize: Your theme isn't set to use Theme.AppCompat or Theme.MaterialComponents. Please make sure you follow all the steps detailed inside the README: https://github.com/flutter-stripe/ flutter_stripe#android If you continue to have trouble, follow this discussion to get some support https://github.com/flutter-stripe/ flutter_stripe/discussions/538, null, nullThis error is generic and will generally appear if you make a mistake in any of the steps necessary to configure the plugin in a project.
Other essential changes or configurations in Android
We add the following rules:
android\app\proguard-rules.pro
-dontwarn com.stripe.android.pushProvisioning.PushProvisioningActivity$g -dontwarn com.stripe.android.pushProvisioning.PushProvisioningActivityStarter$Args -dontwarn com.stripe.android.pushProvisioning.PushProvisioningActivityStarter$Error -dontwarn com.stripe.android.pushProvisioning.PushProvisioningActivityStarter -dontwarn com.stripe.android.pushProvisioning.PushProvisioningEphemeralKeyProviderInstalling the flutter_stripe package
The official plugin is here: https://pub.dev/packages/flutter_stripe
In your pubspec.yaml:
dependencies: flutter_stripe:Dependency in pubspec.yaml
Make sure to use the latest version, as Stripe updates frequently.
Configuring Theme.AppCompat or MaterialComponents
Stripe needs your Android theme to derive from:
Theme.AppCompat
or
Theme.MaterialComponents
One of the first times I tried to integrate the plugin, I received this message:
“Your theme isn't set to use Theme.AppCompat or Theme.MaterialComponents…”It was simply that my theme inherited from an old one.
Mandatory Migration to FlutterFragmentActivity
In your MainActivity.kt:
import io.flutter.embedding.android.FlutterFragmentActivity
class MainActivity: FlutterFragmentActivity() {
}Common errors when initializing the plugin and how to solve them
The typical errors I encountered:
- “flutter_stripe initialization failed”
- “Your theme isn’t set to use Theme.AppCompat…”
- “The plugin failed to initialize…”
They are generally due to:
- old Gradle versions
- outdated Kotlin
- lack of FlutterFragmentActivity
- incorrect theme
- missing Proguard rules
Stripe Initialization in Flutter
Once the Android part is solid, you can work in Dart.
Configure public keys
Use your publishable key:
Stripe.publishableKey = 'pk_test_xxxxxx';Create and initialize Stripe in main.dart
void main() async {
WidgetsFlutterBinding.ensureInitialized();
Stripe.publishableKey = 'pk_test_xxxxxx';
runApp(const MyApp());
}Load the PaymentSheet
await Stripe.instance.initPaymentSheet(
paymentSheetParameters: SetupPaymentSheetParameters(
merchantDisplayName: 'Mi Tienda',
paymentIntentClientSecret: clientSecret,
),
);Complete Payment Integration Example
Now, we can create the payment, which is the most important part. For this, the PaymentIntent class is used from your backend:
Your backend must create a PaymentIntent and return clientSecret.
Typical example (Node):
const paymentIntent = await stripe.paymentIntents.create({ amount: 1000, currency: 'usd', });Display PaymentSheet in the app
await Stripe.instance.presentPaymentSheet();Confirm payment and status handling
try { await Stripe.instance.presentPaymentSheet(); print("Payment completed"); } catch (e) { print("Error paying: $e"); }Tips based on personal experience
How to avoid generic plugin errors
It happened to me several times: the plugin showed errors with no clear hint.
I learned this:
- Check versions before adding Stripe.
- Make sure your Android theme is MaterialComponents.
- Clean the project after updating versions:
flutter cleanWhat to check before compiling
- Gradle 8.x
- Kotlin 1.8+
- AGP 8+
- Correct theme
- FlutterFragmentActivity
Here you can see the implementation of a payment with Stripe:
Future<Map<String, dynamic>> _createPaymentIntent(
int price, String currency, BuildContext context) async {
try {
Map<String, dynamic> body = {
// Amount must be in smaller unit of currency
// so we have multiply it by 100
'amount': (price * 100).toString(),
'currency': currency,
'payment_method_types[]': 'card',
};
var response = await http.post(
Uri.parse('https://api.stripe.com/v1/payment_intents'),
headers: {
'Authorization': 'Bearer $stripeSecret',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: body,
);
// print('Payment Intent Body: ${response.body.toString()}');
return jsonDecode(response.body.toString());
} catch (err) {
showToastMessage(context, 'Stripe exception: ${err.toString()}');
}
return {};
}
makePayment(
int price, String tagPack, String userToken, BuildContext context,
[String coupon = '', String currency = "usd"]) async {
// Create payment intent data
final paymentIntent = await _createPaymentIntent(price, currency, context);
//*** recurso pagado
if (await _makePayment(context, price, paymentIntent)) {
return;
}
// *** compras exitosas
final appModel = Provider.of<AppModel>(context, listen: false);
final data = // TODO CALL API?
showToastMessage(
context, LocaleKeys.thankYouForPurchasingTheCourseWeHopeYouLikeIt.tr());
// espero un segundo y redirecciono
Timer(
const Duration(seconds: 1),
() => Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
pack_index_page.IndexPage(LocaleKeys.pack.tr()))));
}
}To use it, we can configure it on a button:
MaterialButton(
color: Theme.of(context).primaryColor,
textTheme: Theme.of(context).buttonTheme.textTheme,
onPressed: () {
if (_isButtonEnabled) {
makePayment(
double.parse(
totalPrice,
).toInt(),
tutorialPacksModel[0].tag,
appModel.userToken,
context,
couponUseCoupon,
);
Future.delayed(const Duration(seconds: 5), () {
setState(() {
_isButtonEnabled = true;
});
});
}
_isButtonEnabled = false;
},
child: Text(
LocaleKeys.payWithStripe.tr(),
style: Theme.of(
context,
).textTheme.bodyLarge!.copyWith(color: Colors.white),
),
),
],
),How to debug initialization failures
If you get a generic error, it's almost always due to misaligned versions.
In my case, updating Gradle and Kotlin solved 90% of the problems.
Conclusion
Integrating Stripe in Flutter is not difficult, but Android demands surgical precision with versions, themes, and configurations.
With this guide, you have a proven process that is much more complete than typical tutorials.
If you follow the steps exactly, the PaymentSheet will work without mysteries or generic errors.
Frequently Asked Questions (FAQ)
- Why does Stripe fail to initialize?
- Generally due to an incorrect theme, outdated Gradle, or missing FlutterFragmentActivity.
- What minimum versions does the plugin require?
- Android 5.0+, Gradle 8+, Kotlin 1.8+, AGP 8+.
- Does Stripe work the same on Android and iOS?
- Yes, but iOS doesn't require as many infrastructure adjustments.
- How to test Stripe in Test mode?
- Use the test keys and test cards provided by Stripe.
It's better to implement two payment gateways than one, and PayPal and Flutter are essential.
I agree to receive announcements of interest about this Blog.
We will see the steps to install the flutter stripe package in Flutter and be able to use the Stripe API within the app in Flutter.