lokotro_pay 3.0.0
lokotro_pay: ^3.0.0 copied to clipboard
Lokotro Pay: A modern Flutter payment plugin with a clean white-surface checkout, themeable brand colors, and support for cards, mobile money, e-wallets, and more.
Changelog #
All notable changes to the Lokotro Pay plugin will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
3.0.0 - 2026-05-01 #
Auth-v3. Replaces the long-lived app-key credential model with per-checkout
session tokens minted server-to-server, plus transport-layer hardening:
idempotency keys for retry safety, device-fingerprint binding for replay
defence, and gateway-side body rebinding (the gateway already enforces
this — see lokotro_gateway_api Phase 1).
Breaking #
LokotroPayConfigs.tokenrenamed tosessionToken. The legacy field is retained as a@Deprecatedgetter that forwards tosessionToken. Existing 2.x integrations compile against 3.x with a deprecation warning, but new code must use the new name. The legacy field is removed in 4.0.- HTTP client switches from
app-keyheader toAuthorization: Bearer <session_token>. The session token is no longer interchangeable with the legacy app-key — your merchant backend must mint one per checkout viaPOST /api/v1/internal/sessions/createon the gateway. See thegateway_sessions_client.pyexample inbloonio_apps_api. setAppKey/setAuthToken/clearAppKey/clearAuthTokenonLokotroHttpClientare deprecated in favour ofsetSessionToken/clearSessionToken. Same onLokotroCommonService.setAppKeyandLokotroPaymentService.setAppKey. Aliases removed in 4.0.
Added #
LokotroDeviceFingerprint— SHA-256 hex of stable device attributes (Android:ANDROID_ID+Build.FINGERPRINT; iOS:identifierForVendor+systemVersion; web/desktop: best-effort per-platform). Cached after first computation. Auto-attached asX-Device-Fingerprintto every authenticated request.- Auto-injected
Idempotency-Key(UUID v4) on every POST request unless the caller pre-set one viaOptions.headers. The gateway caches(key, body_hash) → responsefor 24h: same key + same body replays the original response, same key + different body returns 409. Safe retry for network blips.
Changed #
- The HTTP client now always sends the new auth headers; the legacy
app-keyheader is dropped from every request even if a caller somehow ends up calling the deprecatedsetAppKey. setSessionTokenproactively removes the legacyapp-keyheader if anything still sets it, as defence-in-depth during the 3.x deprecation window.
Migration #
Mobile / Flutter integrators
Two changes:
LokotroPayCheckout(
configs: LokotroPayConfigs(
- token: appKey, // v2.x: app-key from your backend
+ sessionToken: sessionToken, // v3.x: per-checkout session_token
acceptLanguage: 'fr',
),
paymentBody: LokotroPaymentBody(...),
)
- httpClient.setAppKey(appKey);
+ httpClient.setSessionToken(sessionToken);
The legacy token parameter and setAppKey / setAuthToken methods
still work in 3.x with a deprecation warning, so a delta-by-delta
migration is fine. They go away in 4.0.
Backend integrators
Your merchant backend now mints a session per checkout:
from lokotro_pay_client import GatewaySessionsClient
result = await GatewaySessionsClient().create_session(
amount=order.amount_str, # exact string the SDK will submit
currency=order.currency, # 'usd' / 'cdf' / 'xof'
customer_reference=order.id,
# optional: device_fingerprint, ttl_seconds, idempotency_key
)
return {"session_token": result.session_token, "expires_at": result.expires_at}
Hand the session_token to your mobile app over your normal
checkout-init API. The session is single-use; mint a fresh one for
each new transaction.
Security #
- Body rebinding (gateway-side, already enforced as of
lokotro_gateway_apiPhase 1):amount/currency/customer_referenceyou declare at session creation are immutable for the life of the session. A client that tampers with these in the SDK call is rejected with 400. - Device fingerprint binding (gateway-side): on first sighting the
session locks to the presenting fingerprint. Subsequent requests
must match. The default rollout mode on the gateway is
warnfor 14 days to catch false-positives (factory resets, OS-level vendor-id changes) before enforcement. - Idempotency key replay protection (gateway-side): same key with same body replays the cached response; same key with a different body 409s.
2.0.1 - 2026-04-30 #
Removed #
LokotroPayConfig.publishableKey— this field was added in 2.0.0 by analogy with Stripe/Adyen-style SDKs, but the lokotro gateway does not validate a static merchant credential. All authentication still flows through the per-checkouttokenonLokotroPayConfigs(sent asX-App-Key), as it did in 1.x. The field was dead weight that asked integrators to source a credential that did not exist.
Migration #
void main() {
LokotroPay.init(const LokotroPayConfig(
- publishableKey: 'pk_live_...',
environment: LokotroPayEnvironment.production,
));
runApp(const MyApp());
}
This is technically source-breaking (the named parameter no longer exists),
but 2.0.0 was published only briefly and no real consumers were depending
on the field. If a future release introduces a real merchant-key flow with
gateway-side validation, it will land as an additive 2.x.0.
2.0.0 - 2026-04-30 #
This is a security-driven major release. The SDK no longer reads its own
.env files, no longer fetches fonts from fonts.gstatic.com at runtime, and
no longer accepts a host-controlled customApiUrl. Backend destination is now
fully owned by the SDK, satisfying PCI DSS / OWASP MASVS-NETWORK-1 expectations
that the path of card-data traffic is determined by the SDK and not the
integrator.
Breaking #
LokotroPay.init(LokotroPayConfig(...))is now required at app startup, before anyLokotroPayCheckoutis mounted. The configuration is locked for the lifetime of the process — callinginita second time throwsStateError. This prevents a compromised code path from swapping merchant credentials or environment at runtime.LokotroPayConfigs.customApiUrlremoved. Host apps can no longer override the backend URL. The destination per environment is hardcoded inside the SDK; integrators select between sandbox / staging / production via theLokotroPayEnvironmentenum onLokotroPayConfig.LokotroPayConfigs.isProductionremoved. Environment is now a process-wide concern set onLokotroPayConfigand read viaLokotroPay.instance.config.isProduction.LokotroPayEnv.initialize(...),initializeFromExistingEnv(),reset()removed.LokotroPayEnvis now a read-only facade overLokotroPay.instance.config. Remove any explicit calls — initialisation happens inLokotroPay.init.- Bundled
dev.env/prod.envremoved from the package. Hosts no longer need to ship them, and the SDK no longer reads them.
Removed #
- Dependency on
flutter_dotenv. The SDK no longer reads environment files at runtime. - Dependency on
google_fonts. The SDK no longer fetches Comfortaa fromfonts.gstatic.comduring checkout — this third-party network call leaked a "this app is in a payment flow" signal and broadened PCI DSS scope.
Added #
LokotroPayConfig(immutable,@immutable) with:publishableKey(public, merchant-scoped)environmentenum (sandbox/staging/production)defaultLocale,requestTimeout,logger- native-pay merchant IDs:
googlePayMerchantId,googlePayGatewayMerchantId,applePayMerchantId pinnedSpkiSha256hook for TLS certificate pinning (populate before production cutover; empty list disables pinning)toString()redacts the publishable key
LokotroPay.init,LokotroPay.instance,LokotroPay.isInitialized,LokotroPay.debugReset(debug/profile builds only — asserted-off in release).- Comfortaa bundled as a package asset (
assets/fonts/Comfortaa-Variable.ttf, ~197 KB OFL variable font, axes Light → Bold) withOFL.txtlicense. Available to host apps viaLokotroPayThemeConfig.comfortaa(...)orTextStyle(fontFamily: 'Comfortaa', package: 'lokotro_pay', ...). LokotroPayThemeConfig.comfortaa(...)gainedfontStyleandletterSpacingparameters for parity with the previousGoogleFontshelper.
Migration #
+ // 1. At app startup:
+ void main() {
+ LokotroPay.init(const LokotroPayConfig(
+ publishableKey: 'pk_live_...',
+ environment: LokotroPayEnvironment.production,
+ defaultLocale: 'fr',
+ ));
+ runApp(const MyApp());
+ }
// 2. Per-checkout configs no longer carry environment fields:
LokotroPayCheckout(
configs: LokotroPayConfigs(
token: appKey,
- isProduction: true,
- customApiUrl: 'https://my-proxy.example.com',
acceptLanguage: 'fr',
),
paymentBody: ...,
)
- // 3. Drop any per-screen LokotroPayEnv.initialize calls — gone.
- await LokotroPayEnv.initialize(isProduction: true);
If your app previously imported flutter_dotenv only to satisfy
lokotro_pay's constraint, you can remove it. If it imported google_fonts
only for Comfortaa, you can either drop it or use the bundled font via
LokotroPayThemeConfig.comfortaa(...).
Security #
- Added
pinnedSpkiSha256hook onLokotroPayConfig. Wire into the Dio client before production rollout, and include at least one backup SPKI alongside the primary so emergency cert rotations don't brick deployed apps.
1.1.0 - 2026-04-17 #
Changed #
- Default theme is now a clean white payment surface instead of the dark green
glassmorphism look. Brand colors fall back to the host app's
Theme.of(context).colorSchemewhen nothemeConfigis provided, so the widget visually matches the embedding application by default. - Checkout is wrapped in
Theme(...)so every child screen reads brand and surface colors throughTheme.of(context).colorScheme.{primary, secondary, tertiary, surface, onSurface, outline, ...}— previously most screens hardcoded dark-green colors and ignoredthemeConfig. - Modernized success / error / warning / info result screens for a financial UI: white card with subtle shadow, halo'd filled status badge with elastic pop, formatted amount focal (currency label + 36px tabular-numeric value), scoped transaction-detail panel.
- Status colors (success / error / warning) are now intentionally not themeable — they always render in semantic green / red / amber so users recognize outcomes at a glance.
- Default
LokotroPayThemeConfig.system()factory now resolves to light by default.
Added #
-
LokotroPayThemeConfiggainssecondaryColorandtertiaryColorfields so merchants can pass a full brand triplet alongside the app key:LokotroPayCheckout( configs: LokotroPayConfigs(token: 'app-key'), themeConfig: const LokotroPayThemeConfig( primaryColor: Color(0xFF2563EB), secondaryColor: Color(0xFF1E40AF), tertiaryColor: Color(0xFF3BFBDA), ), ... ) -
LokotroPayThemeConfig.buildThemeData(context)helper builds a Material 3ThemeDataresolving merchant config → hostcolorScheme→ minimal neutral defaults, in that order. -
LokotroPayThemeConfig.lightLokotroBrand()factory for callers that want to opt back into the legacy olive-green look.
Migration #
- No code changes required for existing integrations — all new theme fields are
optional. The default visual will change from dark green to a clean white
surface; merchants who relied on the old look can pass
themeConfig: LokotroPayThemeConfig.lightLokotroBrand()(orLokotroPayThemeConfig.dark()for the dark variant).
1.0.4 - 2025-12-20 #
Fixed #
- 🐛 Fixed syntax error in
lokotro_pay_checkout.dart(missing print statement) - 📝 Updated documentation URL to
https://docs.lokotroo.com
1.0.1 - 2025-12-17 #
Changed #
- 📝 Updated README with correct API documentation
- 🔧 Fixed
LokotroPaymentBodydocumentation (usecustomerReferenceinstead ofsystemRef) - 📦 Updated Android package identifier to
com.bloonio.lokotro_pay - 🧹 Fixed all Dart analyzer warnings (unused imports, deprecated methods, etc.)
Fixed #
- Removed unused imports across multiple files
- Fixed deprecated
withOpacityusage - Fixed unnecessary null checks and assertions
1.0.0 - 2025-12-17 #
Added #
- 🎉 Initial release of Lokotro Pay Flutter plugin
- 🎨 Modern glassmorphism design with dark theme
- 💳 Support for multiple payment methods:
- Payment Cards (Visa, Mastercard, American Express)
- Mobile Money integration
- E-Wallet support
- Bank Transfer functionality
- E-Flash instant payments
- Lokotro Wallet integration
- Virtual Card support
- 🔄 Reactive state management with RxDart
- 🌍 Multi-environment support (development/production)
- 📱 Responsive design for all screen sizes
- 🎯 Haptic feedback for enhanced user experience
- 🔒 Enterprise-grade security for payment processing
- 🚀 Easy integration with comprehensive API
- 📖 Complete documentation and examples
- 🧪 Comprehensive test suite
- 🎨 Customizable themes and colors
- 🛠️ Utility functions for common operations
- 📊 Progress indicators and loading states
- ✅ Form validation and error handling
- 🎭 Beautiful animations and transitions
- 🔧 Environment configuration management
- 📡 HTTP client with interceptors and retry logic
- 🎪 Result screens for success/error/warning/info states
- 🖼️ Image widgets with fallback support
- 📝 Input formatters for card numbers and dates
- 🎨 SVG icon support with placeholder assets
- 📱 Example app demonstrating all features
Technical Details #
- Built with Flutter SDK >=3.3.0
- Dart SDK ^3.8.1
- Modern architecture with clean separation of concerns
- Comprehensive error handling and logging
- Performance optimized for smooth user experience
UI/UX Features #
- Glassmorphism design language inspired by Lokotro
- Premium dark theme with beautiful gradients
- Smooth animations and haptic feedback
- Responsive layouts for all screen sizes
- Consistent design system throughout
Security Features #
- Secure HTTP communication with proper encryption
- Token-based authentication
- Input validation and sanitization
- Network security best practices
[Unreleased] #
Planned Features #
- 🌐 Internationalization (i18n) support
- 🔔 Push notification integration
- 📊 Analytics and reporting
- 🎨 Additional theme options
- 📱 Platform-specific optimizations
For more information, visit our GitHub repository.
