Archived - This documentation is for Flutter SDK v1.x, frozen at the final v1 release, v1.11.2. v1 is no longer the latest version. For the latest version, see Flutter SDK v2. To upgrade, see the Migration Guide.
Official Flutter SDK for integrating GlomoPay payment checkout flows into your mobile applications.
Full Changelog is also available.
Before using this SDK, you need:
- API credentials (Public Key) from your GlomoPay dashboard
- An order ID created via the GlomoPay API (or a subscription ID for subscription payments)
| Requirement | Version |
|---|---|
| Flutter | >= 3.7.0 |
| Dart SDK | >= 3.0.0 |
Add the dependency to your pubspec.yaml:
dependencies:
flutter:
sdk: flutter
glomopay_sdk: ^1.11.2Or install via the CLI:
flutter pub add glomopay_sdkThen import the package:
import 'package:glomopay_sdk/glomopay_sdk.dart';Add the following permissions to android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29" />Add the following keys to ios/Runner/Info.plist:
<key>NSCameraUsageDescription</key>
<string>This app requires access to the camera to upload documents required for payment verification.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app requires access to the photo library to select documents for payment verification.</string>import 'package:flutter/material.dart';
import 'package:glomopay_sdk/glomopay_sdk.dart';
class PaymentScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Complete Payment')),
body: GlomoPayCheckout(
config: const GlomoPayConfig(
publicKey: 'test_pk_12345',
orderId: 'order_abc123',
),
onPaymentSuccess: (GlomoPayPayload payload) {
print('Payment succeeded! Payment ID: ${payload.paymentId}');
},
onPaymentFailure: (GlomoPayPayload payload) {
print('Payment failed with Order ID: ${payload.orderId}');
},
onSdkError: (List<SdkError> errors) {
print('SDK Error: ${errors.first.message}');
},
onConnectionError: (ConnectionError error) {
print('Connection error: ${error.message}');
},
onPaymentTerminate: (TerminationSource source) {
print('User cancelled checkout via $source');
Navigator.pop(context);
},
),
);
}
}To process subscription payments, pass a subscriptionId instead of an orderId in GlomoPayConfig:
GlomoPayCheckout(
config: const GlomoPayConfig(
publicKey: 'live_pk_abc123',
subscriptionId: 'sub_xyz789',
),
onPaymentSuccess: (GlomoPayPayload payload) {
print('Subscription payment success: ${payload.paymentId}');
},
onPaymentFailure: (GlomoPayPayload payload) {
print('Subscription payment failed: ${payload.orderId}');
},
onSdkError: (List<SdkError> errors) {
errors.forEach((e) => print('${e.type}: ${e.message}'));
},
onConnectionError: (ConnectionError error) {
print('Connection error: ${error.message}');
},
)When subscriptionId is provided:
- The SDK skips order detection API calls
- The
subscriptionIdmust start withsub_ - LRS-specific UI elements and flow logic are not applied
- Do not pass both
orderIdandsubscriptionId- the SDK will fireonSdkError - Existing order-based integrations remain backward compatible
- Glomo Payment Stack Support - handles standard checkout flows and overlay redirects (3DS, bank pages)
- Robust Security - built-in jailbreak and root detection
- Error Monitoring - built-in error tracking and diagnostics
- Comprehensive Error Handling - gracefully manages connection drops, DNS issues, HTTP errors, validation mistakes
- Native Support - full Android/iOS native features (camera, file pickers)
- Mock Mode - easy testing with
test_andmock_prefixed keys
The checkout widget. Place it in your widget tree to render the payment checkout.
GlomoPayCheckout(
config: config,
onPaymentSuccess: ...,
onPaymentFailure: ...,
onSdkError: ...,
onConnectionError: ...,
)| Prop | Type | Required | Description |
|---|---|---|---|
config | GlomoPayConfig | Yes | Configuration details for the checkout session |
onPaymentSuccess | Function(GlomoPayPayload) | Yes | Called when payment completes successfully |
onPaymentFailure | Function(GlomoPayPayload) | Yes | Called when transaction declines or fails |
onSdkError | Function(List<SdkError>) | Yes | Called on SDK-level errors (validation, forbidden device) |
onConnectionError | Function(ConnectionError) | Yes | Called on internet drop, DNS failure, HTTP error |
onPaymentTerminate | Function(TerminationSource)? | No | Called if user dismisses modal or hits back |
onUserRefusedDevicePermissions | Function()? | No | Called when user denies camera/storage permissions during file/document uploads or selfie verification requests |
autoCloseOnConnectionError | bool | No | Auto-call onPaymentTerminate on critical connection error. Default: true |
| Property | Type | Default | Description |
|---|---|---|---|
publicKey | String | - | Your GlomoPay public key (must start with live_, mock_, or test_) |
orderId | String | - | Unique tracking ID generated for transaction on server |
subscriptionId | String | - | Subscription checkout ID; use instead of orderId for subscriptions |
server | String? | null | Custom LRS checkout URL; leave unset to use the official environment URL |
Exactly one of orderId or subscriptionId must be provided. If both or neither are set, onSdkError fires.
class GlomoPayPayload {
final String orderId; // System ID of the order
final String? paymentId; // Transaction reference, if generated
final String? signature; // Validation signature hash for backend verification
final Map<String, dynamic>? rawResponse; // Page message exactly as it arrived
}class SdkError {
final SdkErrorType type; // Error category
final String message; // Human-readable description
final String? field; // Field name (e.g. "orderId") causing validationError
}| Value | Description |
|---|---|
validationError | Input validation failed |
deviceForbidden | Rooted or jailbroken device detected |
networkError | Network-level error |
unknown | Uncategorized error |
class ConnectionError {
final ConnectionErrorType type; // Error category
final String message; // Extracted error description or HTTP status phrase
final int? errorCode; // Internal WebKit/Android error code
final int? statusCode; // HTTP status code, if applicable
final bool isRecoverable; // Suggests if safe to offer a "Retry" button
}| Value | Description |
|---|---|
noInternet | Device is offline |
timeout | Request timed out |
dnsFailure | DNS resolution failed |
sslError | SSL/TLS handshake error |
httpClientError | HTTP 4xx response |
httpServerError | HTTP 5xx response |
webResourceError | WebView resource loading error |
unknown | Uncategorized connection error |
Use isRecoverable to decide whether to show a "Retry" button to the user.
| Value | Description |
|---|---|
userDismiss | User swiped down to dismiss the payment sheet |
backButton | User pressed the hardware/software back button |
programmatic | The checkout was closed programmatically |
connectionError | A connection error closed the checkout |
CheckoutStatus represents the current state of the checkout flow.
| Status | Description |
|---|---|
validating | Input keys and devices securely checked |
ready | Verified; loading UI |
paymentInProgress | User typing card details or authorizing |
paymentSuccessful | Payment clear |
paymentFailed | Processing declined |
paymentCancelled | User bounced |
- iOS: SDK intercepts downward swipes to dismiss the payment sheet and triggers
onPaymentTerminatewithTerminationSource.userDismiss. - Android: Overrides standard pop; checks if the Flow WebView overlay can go back. Returns
TerminationSource.backButtonuntil the modal is closed.
The SDK infers mock mode from the publicKey prefix:
| Prefix | Mode | Environment |
|---|---|---|
live_ | Live | Production |
test_ | Mock | Test/sandbox |
mock_ | Mock | Test/sandbox |
Mock mode keys route to the sandbox backend. No real transactions are created.
- Connection heuristics allow mock traffic
- Simulate fake transactions without real money movement
Ensure orderId starts with order_ and has appropriate length.
Ensure subscriptionId starts with sub_ and has appropriate length.
Provide either orderId or subscriptionId, not both. The SDK fires onSdkError if both are set.
Ensure config.publicKey is correctly set with an expected prefix (live_, mock_, or test_).
Run flutter clean and rebuild. Ensure Camera and Storage permissions are explicitly granted in the platform config.
Rooted or jailbroken devices trigger onSdkError with SdkErrorType.deviceForbidden unless testing in an emulator.
The SDK loads checkout pages in an isolated WebView. No PAN, CVV, or sensitive payment data passes through the Flutter bridge - all sensitive input is handled within the WebView's sandboxed context.
Built-in jailbreak and root detection prevents checkout on compromised devices.
To report a security vulnerability, email security@glomopay.com. Do not open a public GitHub issue for security reports.
/**
* All public exports from package:glomopay_sdk/glomopay_sdk.dart
*/
// Widget
GlomoPayCheckout
// Controller
GlomoPayController
// Configuration
GlomoPayConfig
// Payload
GlomoPayPayload
// Errors
SdkError
SdkErrorType
ConnectionError
ConnectionErrorType
// Enums
TerminationSource
CheckoutStatus- Flutter SDK v2 (Latest) - current version documentation
- Migration Guide (v1.11.x to v2.0.0) - step-by-step upgrade instructions with before/after code
- Changelog - all release notes
- Flutter SDK v0.0.15 (Deprecated)
- Flutter SDK v0.0.13 (Deprecated)
- Flutter SDK v0.0.3 (Deprecated)
- React Native SDK - GlomoPay SDK for React Native apps
- Unified SDK (Web) - GlomoPay SDK for web apps
- Checkout overview - server-side checkout integration and signature verification