Checkout Flutter SDK
A comprehensive Flutter SDK for integrating payment processing into your Flutter applications. This SDK provides a secure, user-friendly checkout experience with support for multiple payment methods, currencies, and customization options across both Android and iOS platforms.
Table of Contents
- Overview
- Features
- Installation
- Quick Start
- Basic Usage
- Configuration
- Callbacks
- Advanced Features
- Example App
- Platform Support
- Troubleshooting
- Architecture
- API Reference
- Preparing Your Flutter App for Release
Overview
The Checkout Flutter SDK allows you to integrate payment processing into your Flutter app with just a few lines of code. It handles the complex payment flow, security, and user interface across both Android and iOS platforms, so you can focus on your app's core functionality.
What does it do?
- π³ Processes payments securely across platforms
- π Supports multiple currencies and payment methods
- π± Handles both card and digital wallet payments
- π Manages security and encryption automatically
- π Works seamlessly on Android and iOS
Features
β Cross-Platform: Works on both Android and iOS
β Multiple Payment Methods: Credit/Debit cards, Apple Pay, Google Pay, and more
β Multi-Currency Support: Process payments in various currencies
β Localization: Support for English and Arabic languages
β Security: Built-in encryption and security measures
β Card Scanner: Scan card details using device camera
β Real-time Validation: Instant feedback on payment details
β Flutter-Native: Built specifically for Flutter development
Installation
Requirements
- Flutter 3.3.0 or later
- Dart 3.7.2 or later
- Android SDK 21+ / iOS 11.0+
Add to pubspec.yaml
dependencies:
checkout_flutter: ^1.0.0
Install the package
flutter pub get
Platform Setup
Android
No additional setup required! The plugin handles Android configuration automatically.
iOS
No additional setup required! The plugin handles iOS configuration automatically.
Quick Start
Here's how to get started with the Checkout Flutter SDK in just 5 minutes:
1. Import the package
import 'package:checkout_flutter/checkout_flutter.dart';
2. Create a basic checkout
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:checkout_flutter/checkout_flutter.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _checkoutStatus = 'Ready to checkout';
@override
void initState() {
super.initState();
}
/// Start the checkout process using direct function calls
/// No need for CheckoutFlutter class - just call startCheckout() directly
Future<void> _startCheckout() async {
try {
setState(() {
_checkoutStatus = 'Starting checkout...';
});
Map<String, dynamic> configurations = {
"hashString": "",
"language": "en",
"themeMode": "light",
"supportedPaymentMethods": "ALL",
"paymentType": "ALL",
"selectedCurrency": "KWD",
"supportedCurrencies": "ALL",
"supportedPaymentTypes": [],
"supportedRegions": [],
"supportedSchemes": [],
"supportedCountries": [],
"gateway": {
"publicKey": "pk_test_your_key_here",
"merchantId": "",
},
"customer": {
"firstName": "Android",
"lastName": "Test",
"email": "[email protected]",
"phone": {"countryCode": "965", "number": "55567890"},
},
"transaction": {
"mode": "charge",
"charge": {
"saveCard": true,
"auto": {"type": "VOID", "time": 100},
"redirect": {
"url": "https://demo.staging.tap.company/v2/sdk/checkout",
},
"threeDSecure": true,
"subscription": {
"type": "SCHEDULED",
"amount_variability": "FIXED",
"txn_count": 0,
},
"airline": {
"reference": {"booking": ""},
},
},
},
"amount": "5",
"order": {
"id": "",
"currency": "KWD",
"amount": "5",
"items": [
{
"amount": "5",
"currency": "KWD",
"name": "Item Title 1",
"quantity": 1,
"description": "item description 1",
},
],
},
"cardOptions": {
"showBrands": true,
"showLoadingState": false,
"collectHolderName": true,
"preLoadCardName": "",
"cardNameEditable": true,
"cardFundingSource": "all",
"saveCardOption": "all",
"forceLtr": false,
"alternativeCardInputs": {"cardScanner": true, "cardNFC": true},
},
"isApplePayAvailableOnClient": true,
};
// Call startCheckout function directly
final success = await startCheckout(
configurations: configurations,
onReady: () {
setState(() {
_checkoutStatus = 'Checkout is ready!';
});
print('Checkout is ready!');
},
onSuccess: (data) {
setState(() {
_checkoutStatus = 'Payment successful: $data';
});
print('Payment successful: $data');
},
onError: (error) {
setState(() {
_checkoutStatus = 'Payment failed: $error';
});
print('Payment failed: $error');
},
onClose: () {
setState(() {
_checkoutStatus = 'Checkout closed';
});
print('Checkout closed');
},
onCancel: () {
setState(() {
_checkoutStatus = 'Checkout cancelled';
});
print('Checkout cancelled (Android)');
},
);
if (!success) {
setState(() {
_checkoutStatus = 'Failed to start checkout';
});
}
} catch (e) {
setState(() {
_checkoutStatus = 'Error: $e';
});
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Checkout Flutter Example'),
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Text(
'Status',
style: Theme.of(context).textTheme.titleMedium,
),
SizedBox(height: 8),
Text(
_checkoutStatus,
style: Theme.of(context).textTheme.bodyMedium,
textAlign: TextAlign.center,
),
],
),
),
),
SizedBox(height: 24),
ElevatedButton.icon(
onPressed: _startCheckout,
icon: Icon(Icons.credit_card),
label: Text('Start Checkout'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
padding: EdgeInsets.symmetric(vertical: 16),
),
),
],
),
),
),
);
}
}
That's it! You now have a working payment system in Flutter.
Basic Usage
Understanding the Flow
sequenceDiagram participant App as Flutter App participant SDK as Checkout SDK participant Native as Native Platform participant UI as Payment UI participant Server as Payment Server App->>SDK: startCheckout(config, callbacks) SDK->>Native: Initialize native checkout Native->>UI: Present checkout interface UI->>App: onReady() Note over UI: User enters payment details UI->>Server: Process payment Server->>UI: Payment result alt Payment Success UI->>App: onSuccess(data) else Payment Failed UI->>App: onError(error) end UI->>App: onClose() Native->>SDK: Cleanup
Step-by-Step Integration
Step 1: Configure Your Payment
Map<String, dynamic> configurations = {
// Required: Amount to charge
"amount": "25.99",
// Required: Gateway configuration
"gateway": {
"publicKey": "pk_test_your_key_here",
"merchantId": "your_merchant_id"
},
// Required: Customer information
"customer": {
"firstName": "John",
"lastName": "Doe",
"email": "[email protected]",
"phone": {
"countryCode": "1",
"number": "1234567890"
}
},
// Required: Order details
"order": {
"currency": "USD",
"amount": "25.99",
"items": [
{
"name": "Premium Subscription",
"amount": "25.99",
"currency": "USD",
"quantity": 1,
"description": "Monthly premium subscription"
}
]
}
};
Step 2: Start Checkout with Callbacks
Future<void> _processPayment() async {
final success = await startCheckout(
configurations: configurations,
// Called when the checkout UI is ready
onReady: () {
print('Checkout interface is ready');
// Optional: Show loading indicator, log analytics, etc.
},
// Called when payment is successful
onSuccess: (String data) {
print('Payment completed successfully!');
// Parse the success data and update your UI
_handlePaymentSuccess(data);
},
// Called when payment fails
onError: (String error) {
print('Payment failed: $error');
// Handle payment error
_handlePaymentError(error);
},
// Called when user closes the checkout
onClose: () {
print('User closed the checkout');
// Handle checkout cancellation
},
// Called when checkout is cancelled (Android only)
onCancel: () {
print('Checkout was cancelled');
// Handle cancellation specific to Android
},
);
if (!success) {
print('Failed to start checkout');
// Handle startup failure
}
}
Step 3: Handle Results
void _handlePaymentSuccess(String data) {
// Parse the payment data
try {
final paymentData = jsonDecode(data);
final transactionId = paymentData['id'];
// Update your app's state
setState(() {
_paymentStatus = 'Payment successful!';
_transactionId = transactionId;
});
// Navigate to success screen
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PaymentSuccessScreen(
transactionId: transactionId,
),
),
);
} catch (e) {
print('Failed to parse payment data: $e');
}
}
void _handlePaymentError(String error) {
setState(() {
_paymentStatus = 'Payment failed';
});
// Show error dialog
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Payment Failed'),
content: Text('Please try again or use a different payment method.'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text('OK'),
),
],
),
);
}
Configuration
Basic Configuration Options
Map<String, dynamic> configurations = {
// REQUIRED FIELDS
"amount": "10.00", // Amount to charge
"gateway": {...}, // Gateway configuration
"customer": {...}, // Customer details
"order": {...}, // Order information
// OPTIONAL FIELDS
"language": "en", // "en" or "ar"
"themeMode": "light", // "light", "dark", "light_mono", "dark_colored"
"supportedPaymentMethods": "ALL", // "ALL" or specific methods
"selectedCurrency": "USD", // Default currency
"paymentType": "ALL" // "ALL", "WEB", "CARD", "DEVICE"
};
Gateway Configuration
"gateway": {
"publicKey": "pk_test_your_public_key", // Your public key from the dashboard
"merchantId": "your_merchant_id" // Your merchant ID
}
β οΈ Important: Use pk_test_
for testing and pk_live_
for production.
Customer Configuration
"customer": {
"firstName": "John",
"lastName": "Doe",
"email": "[email protected]",
"phone": {
"countryCode": "1", // Country code without +
"number": "1234567890" // Phone number
}
}
Order Configuration
"order": {
"id": "order_123", // Optional: Your order ID
"currency": "USD", // Currency code (USD, EUR, GBP, etc.)
"amount": "25.99", // Order amount
"items": [ // Array of items
{
"name": "Product Name",
"amount": "25.99",
"currency": "USD",
"quantity": 1,
"description": "Product description"
}
]
}
Minimal Configuration
// Use this minimal config for testing
Map<String, dynamic> testConfig = {
"amount": "1.00",
"gateway": {
"publicKey": "pk_test_your_key",
"merchantId": "test_merchant"
},
"customer": {
"email": "[email protected]"
},
"order": {
"currency": "USD",
"amount": "1.00"
}
};
Callbacks
Understanding what each callback means and how to handle them:
onReady()
onReady: () {
// The checkout interface has loaded and is ready for user interaction
// This is a good place to:
// - Hide loading indicators
// - Log analytics events
// - Update UI state
print('Checkout is ready for user interaction');
}
onSuccess(String data)
onSuccess: (String data) {
// Payment was processed successfully
// The 'data' parameter contains payment details in JSON format
try {
final paymentResult = jsonDecode(data);
final transactionId = paymentResult['id'];
final amount = paymentResult['amount'];
print('Transaction ID: $transactionId');
print('Amount: $amount');
// Update your app's state
// - Save transaction details
// - Update user's account
// - Show success message
// - Navigate to confirmation screen
} catch (e) {
print('Failed to parse payment data: $e');
}
}
onError(String error)
onError: (String error) {
// Payment failed or encountered an error
// The 'error' parameter contains error details
print('Payment error: $error');
// Common error handling patterns:
if (error.contains('cancelled')) {
// User cancelled the payment
_showMessage('Payment was cancelled');
} else if (error.contains('declined')) {
// Payment was declined
_showErrorDialog('Payment Declined', 'Please check your card details');
} else if (error.contains('network')) {
// Network error
_showErrorDialog('Network Error', 'Please check your internet connection');
} else {
// Other errors
_showErrorDialog('Error', 'Something went wrong. Please try again.');
}
}
onClose()
onClose: () {
// The checkout interface was closed
// This is called after onSuccess, onError, or when user manually closes
print('Checkout interface closed');
// Clean up any resources
// - Remove loading indicators
// - Reset UI state
// - Log analytics
// - Return to previous screen if needed
}
onCancel() (Android Only)
onCancel: () {
// Checkout was cancelled (Android-specific callback)
// This provides additional cancellation handling for Android
print('Checkout was cancelled on Android');
// Handle Android-specific cancellation logic
// - Show cancellation message
// - Reset form state
// - Log cancellation event
}
Advanced Features
Theme Customization
"themeMode": "light" // Default light theme
"themeMode": "dark" // Dark theme
"themeMode": "light_mono" // Light monochrome
"themeMode": "dark_colored" // Dark with colors
Payment Method Selection
// Allow all payment methods
"supportedPaymentMethods": "ALL"
// Specific payment methods
"supportedPaymentMethods": ["VISA", "MASTERCARD", "APPLE_PAY"]
Card Options
"cardOptions": {
"showBrands": true, // Show card brand logos
"collectHolderName": true, // Ask for cardholder name
"cardNameEditable": true, // Allow editing card name
"saveCardOption": "all", // Show save card option
"alternativeCardInputs": {
"cardScanner": true, // Enable card scanning
"cardNFC": true // Enable NFC reading
}
}
Multi-language Support
"language": "en" // English
"language": "ar" // Arabic
Transaction Configuration
"transaction": {
"mode": "charge", // Transaction mode
"charge": {
"saveCard": true, // Save card for future use
"threeDSecure": true, // Enable 3D Secure
"redirect": {
"url": "https://your-redirect-url.com"
}
}
}
Example App
The following example app demonstrates all SDK features:
https://github.com/Tap-Payments/Checkout-Flutter/tree/main/example
Running the Example
- Navigate to the example directory:
cd example
- Install dependencies:
flutter pub get
- Add your test API keys in
lib/main.dart
- Run the app:
flutter run
Key Features Demonstrated
- Basic Integration: Simple payment flow
- Configuration Options: All customization options
- Callback Handling: Proper response handling
- Error Management: Comprehensive error handling
- UI Updates: Real-time status updates
Example App Structure
example/
βββ lib/
β βββ main.dart # Main example implementation
βββ pubspec.yaml # Dependencies
βββ README.md # Example-specific documentation
Platform Support
Android
- Minimum SDK: 21 (Android 5.0)
- Target SDK: Latest
- Supported Features: All payment methods, card scanner, NFC
- Permissions: Automatically handled by the SDK
iOS
- Minimum Version: 11.0
- Supported Features: All payment methods, Apple Pay, card scanner
- Permissions: Automatically handled by the SDK
Flutter
- Minimum Version: 3.3.0
- Dart Version: 3.7.2+
- Supported Platforms: Android, iOS
Troubleshooting
Common Issues
1. SDK Not Starting
Problem: startCheckout
returns false
Solution:
- Check that all required fields are provided in configuration
- Verify your public key is correct
- Ensure proper Flutter/Dart versions
- Check device connectivity
2. Payment Fails Immediately
Problem: onError
is called immediately
Solution:
- Verify your API keys are correct
- Check network connectivity
- Ensure amount is properly formatted as string
- Validate customer email format
3. Callbacks Not Working
Problem: Callback functions not being called
Solution:
- Ensure callbacks are properly defined
- Check for syntax errors in callback functions
- Verify the SDK version compatibility
- Test on both Android and iOS
4. Platform-Specific Issues
Problem: Works on one platform but not the other
Solution:
- Check platform-specific requirements
- Verify minimum SDK/iOS versions
- Test on physical devices
- Check platform-specific permissions
-
ArchitectureSDK Structure Overview
graph TB A[Flutter App] --> B[Checkout Flutter SDK] B --> C[Platform Interface] C --> D[Method Channel] D --> E[Android Native] D --> F[iOS Native] E --> G[Android Checkout UI] F --> H[iOS Checkout UI] B --> I[Callback System] I --> J[onReady] I --> K[onSuccess] I --> L[onError] I --> M[onClose] I --> N[onCancel] G --> O[Payment Gateway] H --> O
API Reference
startCheckout Function
Future<bool> startCheckout({
required Map<String, dynamic> configurations,
Function()? onClose,
Function()? onReady,
Function(String)? onSuccess,
Function(String)? onError,
Function()? onCancel,
})
Starts the checkout process with the given configuration and callbacks.
Parameters:
configurations
: Map containing payment configuration (required)onClose
: Called when checkout interface is closed (optional)onReady
: Called when checkout interface is ready (optional)onSuccess
: Called when payment succeeds with data (optional)onError
: Called when payment fails with error message (optional)onCancel
: Called when checkout is cancelled - Android only (optional)
Returns:
Future<bool>
:true
if checkout started successfully,false
otherwise
Preparing Your Flutter App for Release
When you're ready to publish your Flutter app to the Play Store or share it with users
itβs important to build it in release mode to improve performance and reduce app size.
Before you start, please follow the official Flutter guide to sign your app:
Add ProGuard Rules
To further optimize and protect your Android app, we recommend adding a ProGuard file.
- In your project, go to android/app/
- Create a new file called proguard-rules.pro
- Copy and paste the following content
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# ========================================
# FLUTTER RECOMMENDED PROGUARD RULES
# ========================================
# Keep all Flutter classes
-keep class io.flutter.** { *; }
-keep class io.flutter.embedding.** { *; }
-keep class io.flutter.plugin.** { *; }
-keep class io.flutter.plugins.** { *; }
# Keep Flutter engine and embedding classes
-keep class io.flutter.embedding.engine.** { *; }
-keep class io.flutter.embedding.android.** { *; }
# Keep Flutter plugin registry and platform channels
-keep class io.flutter.plugin.common.** { *; }
-keep class io.flutter.embedding.engine.plugins.** { *; }
# Keep Flutter method channel implementations
-keep class * implements io.flutter.plugin.common.MethodChannel$MethodCallHandler { *; }
-keep class * implements io.flutter.plugin.common.EventChannel$StreamHandler { *; }
# Keep Flutter platform view factories
-keep class * implements io.flutter.plugin.platform.PlatformViewFactory { *; }
-keep class * implements io.flutter.plugin.platform.PlatformView { *; }
# ========================================
# KEEP ALL TAP SDK CLASSES
# ========================================
# Keep ALL Tap Checkout SDK classes - no obfuscation at all
-keep class company.tap.tapcheckout_android.** { *; }
-keep interface company.tap.tapcheckout_android.** { *; }
-keepnames class company.tap.tapcheckout_android.** { *; }
-keepclassmembers class company.tap.tapcheckout_android.** { *; }
# Keep all inner classes, companion objects, and nested classes
-keep class company.tap.tapcheckout_android.**$* { *; }
-keep class company.tap.tapcheckout_android.**$Companion { *; }
-keep class company.tap.tapcheckout_android.**$** { *; }
# Keep all methods, fields, and constructors for Tap SDK
-keepclassmembers class company.tap.tapcheckout_android.** {
public <init>(...);
public <methods>;
private <methods>;
protected <methods>;
<fields>;
}
# ========================================
# KEEP ALL FLUTTER PLUGIN CLASSES
# ========================================
# Keep ALL Flutter plugin classes - no obfuscation at all
-keep class com.example.checkout_flutter.** { *; }
-keep interface com.example.checkout_flutter.** { *; }
-keepnames class com.example.checkout_flutter.** { *; }
-keepclassmembers class com.example.checkout_flutter.** { *; }
# Keep all inner classes and companion objects for plugin
-keep class com.example.checkout_flutter.**$* { *; }
-keep class com.example.checkout_flutter.**$Companion { *; }
# Keep all methods, fields, and constructors for plugin
-keepclassmembers class com.example.checkout_flutter.** {
public <init>(...);
public <methods>;
private <methods>;
protected <methods>;
<fields>;
}
# ========================================
# KOTLIN SPECIFIC RULES
# ========================================
# Keep all Kotlin metadata to prevent reflection issues
-keep class kotlin.Metadata { *; }
-keep class kotlin.** { *; }
-keepclassmembers class kotlin.** { *; }
# Keep Kotlin coroutines completely
-keep class kotlinx.coroutines.** { *; }
-keepnames class kotlinx.coroutines.** { *; }
-keepclassmembers class kotlinx.coroutines.** { *; }
-dontwarn kotlinx.coroutines.**
# Keep all companion objects and singletons
-keepnames class * {
public static ** Companion;
public static ** INSTANCE;
}
# Keep Kotlin data classes and their properties
-keepclassmembers class * {
@kotlin.jvm.JvmField <fields>;
public ** component*();
public ** copy(...);
public ** copy$default(...);
}
# ========================================
# SERIALIZATION AND JSON
# ========================================
# Keep Gson classes
-keep class com.google.gson.** { *; }
-keep class * extends com.google.gson.TypeAdapter { *; }
-keep class * implements com.google.gson.TypeAdapterFactory { *; }
-keep class * implements com.google.gson.JsonSerializer { *; }
-keep class * implements com.google.gson.JsonDeserializer { *; }
# Keep serialization annotations
-keepclassmembers class * {
@com.google.gson.annotations.SerializedName <fields>;
@com.google.gson.annotations.Expose <fields>;
}
# Keep all fields for data classes to prevent ClassCastException
-keepclassmembers class * {
<fields>;
}
# ========================================
# NETWORK LIBRARIES
# ========================================
# Keep OkHttp3 classes completely
-dontwarn okhttp3.**
-dontwarn okio.**
-keep class okhttp3.** { *; }
-keep interface okhttp3.** { *; }
-keepnames class okhttp3.** { *; }
# Keep old OkHttp classes (com.squareup.okhttp) - used by some dependencies
-dontwarn com.squareup.okhttp.**
-keep class com.squareup.okhttp.** { *; }
-keep interface com.squareup.okhttp.** { *; }
# Keep Retrofit classes completely
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepnames class retrofit2.** { *; }
# Keep Picasso and related classes
-keep class com.squareup.picasso.** { *; }
-dontwarn com.squareup.picasso.**
# ========================================
# ANDROID FRAMEWORK CLASSES
# ========================================
# Keep WebView related classes
-keep class android.webkit.** { *; }
-keep class * extends android.webkit.WebViewClient { *; }
-keep class * extends android.webkit.WebChromeClient { *; }
# Keep custom view classes with all constructors
-keep public class * extends android.view.View {
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
public <init>(android.content.Context, android.util.AttributeSet, int, int);
public void set*(...);
*** get*();
<fields>;
<methods>;
}
# Keep Parcelable implementations
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
<fields>;
<methods>;
}
# Keep enum classes
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
**[] $VALUES;
public *;
}
# Keep native methods
-keepclasseswithmembernames class * {
native <methods>;
}
# ========================================
# ESSENTIAL ATTRIBUTES
# ========================================
# Keep all annotations and signatures for runtime reflection
-keepattributes *Annotation*
-keepattributes Signature
-keepattributes InnerClasses
-keepattributes EnclosingMethod
-keepattributes RuntimeVisibleAnnotations
-keepattributes RuntimeInvisibleAnnotations
-keepattributes RuntimeVisibleParameterAnnotations
-keepattributes RuntimeInvisibleParameterAnnotations
# Keep source file names and line numbers for better crash reports
-keepattributes SourceFile,LineNumberTable
# ========================================
# PREVENT COMMON ISSUES
# ========================================
# Keep classes that might be instantiated via reflection
-keep class * {
public <init>();
public <init>(...);
}
# Additional safety rules to prevent ClassCastException
-keep,allowshrinking,allowoptimization class * {
<fields>;
}
# ========================================
# MISSING CLASSES - IGNORE WARNINGS FOR NON-ESSENTIAL CLASSES
# ========================================
# Google Play Core classes - ignore warnings (not essential for basic functionality)
-dontwarn com.google.android.play.core.splitcompat.**
-dontwarn com.google.android.play.core.splitinstall.**
-dontwarn com.google.android.play.core.tasks.**
# Old OkHttp (com.squareup.okhttp) - ignore warnings for Picasso compatibility
-dontwarn com.squareup.okhttp.**
# Java beans classes - ignore warnings (not available on Android)
-dontwarn java.beans.**
# Jackson databind classes - ignore warnings
-dontwarn com.fasterxml.jackson.**
# Other JVM-specific classes not available on Android
-dontwarn java.lang.instrument.**
-dontwarn sun.misc.**
-dontwarn javax.annotation.**
-dontwarn org.conscrypt.**
-dontwarn org.bouncycastle.**
-dontwarn org.openjsse.**
# Ignore warnings for classes that may not be available in all Android versions
-dontwarn android.support.**
-dontwarn androidx.annotation.Keep
Build Your App for Release
Once youβve set that up, you can build your app in release mode.
Just run the commands in your terminal:
flutter build apk --release
Support
For questions, issues, or feature requests:
- π§ Email: [email protected]
- π¬ Flutter Community: Flutter Dev Community
Updated about 21 hours ago