A unified, production-ready payment API for Flutter that supports multiple payment processors with a single, consistent interface. Switch between payment providers without rewriting your code.
- π Unified API - One consistent interface for all payment processors
- π³ 6 Payment Processors - Stripe, Paddle, Braintree, Lemon Squeezy, Totalpay, and Fake (for testing)
- π Hot-Swappable - Switch processors at runtime without code changes
- π± Ready-to-Use Widgets - Pre-built payment UI components
- π¨ Highly Customizable - Customize every aspect to match your brand
- π Secure by Design - PCI-compliant patterns, no card data storage
- π§ͺ Testing Support - Built-in fake processor for development
- π Analytics Ready - Firebase, Sentry, and custom analytics integrations
- π Smart Caching - Automatic data caching with secure storage
- π Production Ready - Comprehensive error handling and retry logic
- π― Type Safe - Full Dart type safety with Freezed models
- β‘ State Management - Built-in Riverpod integration
| Processor | Subscriptions | One-time Payments | Plan Swapping | Webhooks | Testing |
|---|---|---|---|---|---|
| Stripe | β | β | β | β | Sandbox |
| Paddle | β | β | β | β | Sandbox |
| Braintree | β | β | β | β | Sandbox |
| Lemon Squeezy | β | β | β | β | Test Mode |
| Totalpay | β | β | β | β | Sandbox |
| Fake | β | β | β | β | Built-in |
- Unified API across all payment processors
- Native Google Pay integration for Android
- Native Apple Pay integration for iOS (iOS 13.0+)
- Type-safe payment models using Freezed
- State management with Riverpod
- Comprehensive error handling
- Easy switching between processors
- Built-in retry logic
- Local payment method storage
- Support for one-time and recurring payments
- Production-ready architecture
Add to your pubspec.yaml:
dependencies:
flutter_universal_payments: ^0.1.0Then run:
flutter pub getimport 'package:flutter_universal_payments/flutter_universal_payments.dart';
// 1. Configure your payment processor
final config = PaymentConfigurationBuilder()
.useStripe(
publishableKey: 'pk_test_...',
secretKey: 'sk_test_...',
webhookSecret: 'whsec_...',
)
.enableLogging()
.build();
// 2. Initialize the payment service
await FlutterUniversalPayments.initialize(
config: config,
storage: storage, // Your Storage implementation
);
// 3. Get the service instance
final paymentService = FlutterUniversalPayments.instance;
// 4. Initialize customer
await paymentService.initialize(
email: 'customer@example.com',
name: 'John Doe',
);
// 5. Create a subscription
final subscription = await paymentService.subscribe(
priceId: 'price_monthly_999',
trialDays: 14,
);
print('Subscription created: ${subscription.id}');The package includes ready-to-use payment widgets:
// Display pricing plans
PricingTable(
plans: [
SubscriptionPlanData(
id: 'basic',
name: 'Basic',
price: Price(
id: 'price_basic',
amount: 999,
currency: 'USD',
interval: BillingInterval.month,
),
features: ['Feature 1', 'Feature 2'],
),
],
onPlanSelected: (plan) async {
await paymentService.subscribe(priceId: plan.price.id);
},
)
// Payment card input
PaymentCardInput(
onCardChanged: (cardData) {
// Handle card data
},
)
// Subscription status display
SubscriptionStatusWidget(
subscription: subscription,
)- Getting Started Guide - Detailed setup for each processor
- Widgets Documentation - UI components and customization
- Advanced Usage - Webhooks, custom processors, best practices
- API Reference - Complete API docs
- Stripe Integration
- Paddle Integration
- Braintree Integration
- Lemon Squeezy Integration
- Totalpay Integration
// Initialize a customer
await paymentService.initialize(
email: 'customer@example.com',
name: 'John Doe',
phone: '+1234567890',
);
// Get current customer
final customer = await paymentService.getCurrentCustomer();
// Refresh customer data
await paymentService.refreshCustomer();// Create subscription with trial
final subscription = await paymentService.subscribe(
priceId: 'price_monthly',
trialDays: 14,
);
// Check subscription status
final hasActive = await paymentService.hasActiveSubscription('product_id');
final isOnTrial = await paymentService.isOnTrial('product_id');
// Change subscription plan
await paymentService.changePlan(
subscriptionId: subscription.id,
newPriceId: 'price_annual',
);
// Cancel subscription
await paymentService.cancelSubscription(
id: subscription.id,
immediate: false, // Grace period until end of billing cycle
);
// Resume canceled subscription
await paymentService.resumeSubscription(id: subscription.id);// Add payment method
await paymentService.setDefaultPaymentMethod(paymentMethodToken);
// Get all payment methods
final methods = await paymentService.getPaymentMethods();
// Remove payment method
await paymentService.removePaymentMethod(methodId);// Create a one-time charge
final charge = await paymentService.makePayment(
amount: 2999, // $29.99
currency: 'USD',
description: 'Premium upgrade',
paymentMethodToken: token,
// Configure Google Pay
final googlePayConfig = GooglePayConfig(
merchantId: 'your-merchant-id',
merchantName: 'Your Store',
environment: GooglePayEnvironment.production,
);One of the most powerful features is the ability to switch payment processors without changing your code:
// Start with Stripe
final stripeConfig = PaymentConfigurationBuilder()
.useStripe(publishableKey: '...', secretKey: '...')
.build();
await FlutterUniversalPayments.initialize(config: stripeConfig);
// Later, switch to Paddle
final paddleConfig = PaymentConfigurationBuilder()
.usePaddle(
vendorId: '...',
authCode: '...',
publicKey: '...',
)
.build();
await FlutterUniversalPayments.reinitialize(config: paddleConfig);
// Your app code remains the same!All widgets are highly customizable:
PricingTable(
plans: plans,
layout: PricingLayout.grid(crossAxisCount: 3),
cardDecoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.blue, Colors.purple],
),
borderRadius: BorderRadius.circular(20),
),
selectedPlanColor: Colors.green,
onPlanSelected: (plan) => handlePlanSelection(plan),
headerBuilder: (context) => CustomHeader(),
)Built-in support for analytics and logging:
// Enable logging
PaymentLogger.enable();
PaymentLogger.setLogLevel(LogLevel.debug);
// Add analytics providers
PaymentLogger.registerAnalyticsProvider(
FirebaseAnalyticsProvider(analytics),
);
// Automatic event logging
// - Payment success/failure
// - Subscription created/canceled
// - Plan changes
// - Checkout eventsUse the built-in fake processor for testing:
final testConfig = PaymentConfigurationBuilder()
.useFake(
simulateDelays: true,
delayDuration: Duration(seconds: 1),
failureRate: 0.1, // 10% failure rate
)
.build();
await FlutterUniversalPayments.initialize(config: testConfig);The package follows clean architecture principles:
lib/
βββ src/
β βββ models/ # Data models (Customer, Subscription, Charge, etc.)
β βββ processors/ # Payment processor implementations
β βββ services/ # Business logic (PaymentService)
β βββ widgets/ # UI components
β βββ utils/ # Logging, analytics
β βββ exceptions/ # Custom exceptions
βββ flutter_universal_payments.dart # Public API
- Never store sensitive card data locally
- Use tokenization for payment methods
- Implement webhook signature verification
- Enable logging with sensitive data masking
- Use secure storage for customer IDs and tokens
- Always use HTTPS endpoints
- Validate all user inputs
See Advanced Usage for detailed security guidelines.
We welcome contributions! Please see our Contributing Guide for details.
# Clone the repository
git clone https://github.com/aliumairdev/flutter_pay_kit.git
cd flutter_pay_kit
# Install dependencies
flutter pub get
# Run code generation
flutter pub run build_runner build
# Run tests
flutter test
# Run example app
cd example
flutter runThis project is licensed under the MIT License - see the LICENSE file for details.
// Check availability final isAvailable = await googlePayConfig.isAvailable();
if (isAvailable) { // Request payment final token = await googlePayConfig.requestPayment(amount: 2500);
if (token != null) { // Process the token with your payment processor print('Payment token: $token'); } }
For detailed Google Pay integration instructions, see [GOOGLE_PAY_INTEGRATION.md](GOOGLE_PAY_INTEGRATION.md).
// Check if Apple Pay is available
final isAvailable = await ApplePayHandler.isAvailable();
if (isAvailable) {
// Request payment
final result = await ApplePayHandler.requestPayment(
amount: 1999, // $19.99 in cents
currency: 'USD',
merchantId: 'merchant.com.yourcompany.yourapp',
countryCode: 'US',
label: 'Premium Subscription',
);
// Process the payment token with your backend
final paymentData = result['paymentData'];
// Send to your payment processor
}
For complete Apple Pay setup instructions, see APPLE_PAY_SETUP.md.
- Documentation: doc/getting_started.md
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Apple Pay support
- Google Pay support
- PayPal direct integration
- Cryptocurrency payments
- Invoice generation
- Receipt management
- Multi-currency support
- Tax calculation integration
- Fraud detection hooks
- Dart SDK:
>=3.0.0 <4.0.0 - Flutter SDK:
>=3.10.0
Check out the example directory for a complete Flutter app demonstrating all features:
- Customer initialization
- Subscription management
- Payment method handling
- One-time payments
- UI widgets showcase
- Analytics integration
- Flutter Documentation
- Dart Documentation
- Riverpod Documentation
- Stripe API Documentation
- Paddle API Documentation
- Braintree API Documentation
Made with β€οΈ by the Flutter community