flutter_elavon 1.0.9
flutter_elavon: ^1.0.9 copied to clipboard
Flutter plugin for Elavon Payment Gateway SDK
Flutter Elavon Plugin #
Flutter plugin for integrating Elavon Payment Gateway SDK (Converge Commerce SDK 6.8.0) into Flutter applications.
Features #
- Account creation and management
- Device discovery and connection
- Transaction processing (Sale, Refund, Pre-Auth, etc.)
- Real-time transaction event streaming
Setup #
Android #
- Add the plugin and required dependencies to your
pubspec.yaml:
dependencies:
flutter_elavon: ^1.0.3 # or latest version from pub.dev
path_provider: ^2.1.0 # Required by Elavon SDK
Important: The path_provider plugin is required because the Elavon SDK uses it internally. Make sure to add it explicitly to your app's dependencies.
-
Add Elavon SDK Libraries: Due to size limitations, the Elavon SDK library files (JAR/AAR) are not included in the published package. You need to:
Important: When using the plugin from pub.dev (published package):
-
The plugin's Java code needs Elavon SDK classes for compilation
-
You have two options:
Option 1 (Easiest): Add files to the plugin's directory (one-time per Flutter installation):
- Copy AAR/JAR files to:
~/.pub-cache/hosted/pub.dev/flutter_elavon-1.0.5/android/libs/ - Replace
1.0.5with your installed version - This is a one-time setup that persists across projects
Option 2: Add files to your app's directory (requires Gradle property):
- Add files to:
your_project/android/app/libs/ - REQUIRED: Add this to your app's
android/gradle.propertiesfile (create it if it doesn't exist):
Or use an absolute path:flutterElavonAppLibsPath=app/libsflutterElavonAppLibsPath=/absolute/path/to/your/project/android/app/libs - Make sure your app's
android/app/build.gradlehas the repositories block (see Step 3) - Note: If Option 2 doesn't work, use Option 1 instead (more reliable and simpler)
- Copy AAR/JAR files to:
Step 1: Obtain the Elavon Commerce SDK 6.8.0 libraries from Elavon
Step 2: Copy all JAR and AAR files to your app's
android/app/libs/directory- Create the directory if it doesn't exist:
your_project/android/app/libs/ - Copy all
.jarand.aarfiles from the Elavon SDK to this directory - You do NOT need to add files to the plugin's directory when using the published package
Step 3: Update your app's
android/app/build.gradle:Add the
repositoriessection (if not already present):repositories { flatDir { dirs 'libs' // Points to android/app/libs/ directory } }Add the dependencies:
dependencies { // Include all JAR files from libs directory implementation fileTree(dir: 'libs', include: ['*.jar']) // Include required AAR files implementation(name: 'commerce-android-6.8.0', ext: 'aar') implementation(name: 'commerce-common-android-6.8.0-release', ext: 'aar') implementation(name: 'commerce-unifiedgateway-android-6.8.0-release', ext: 'aar') implementation(name: 'deckard-android-6.8.0', ext: 'aar') implementation(name: 'mpos-release-1.0.10.39', ext: 'aar') implementation(name: 'opayo-core-android-6.8.0-release', ext: 'aar') implementation(name: 'PclServiceLib-pcl-2.21.01', ext: 'aar') implementation(name: 'PclUtilities-pcl-2.21.01', ext: 'aar') implementation(name: 'rba-android-6.8.0-release', ext: 'aar') implementation(name: 'roam-rua-wrapper-java-android-6.8.0-release', ext: 'aar') implementation(name: 'roamreaderunifiedapi-2.5.2.1', ext: 'aar') implementation(name: 'rua-android-6.8.0', ext: 'aar') implementation(name: 'saf-android-aar-6.8.0-release', ext: 'aar') }Complete Example - Here's how your
android/app/build.gradleshould look:android { // ... your android configuration ... } // Add repositories BEFORE dependencies repositories { flatDir { dirs 'libs' // This points to android/app/libs/ } } dependencies { // ... other dependencies ... // JAR files implementation fileTree(dir: 'libs', include: ['*.jar']) // AAR files implementation(name: 'commerce-android-6.8.0', ext: 'aar') implementation(name: 'deckard-android-6.8.0', ext: 'aar') // ... other AAR files ... }Important:
- The
repositoriesblock withflatDirmust be at the module level (insideandroid/app/build.gradle) - The
dirs 'libs'path is relative to theandroid/app/directory - Make sure all AAR files are in
your_project/android/app/libs/directory - If you put files in
android/libs/instead, usedirs '../libs'
-
-
The plugin requires the following permissions (already included in AndroidManifest.xml):
- Bluetooth permissions (BLUETOOTH_SCAN, BLUETOOTH_CONNECT for API 31+)
- Location permission (ACCESS_FINE_LOCATION)
- Phone state permission (READ_PHONE_STATE)
- USB host feature (for USB device discovery)
-
Minimum SDK: 28
-
Target SDK: 35
Usage #
⚠️ CRITICAL: Initialization Order
You MUST call WidgetsFlutterBinding.ensureInitialized() as the very first line in your main() function, before:
- Any database initialization
- Any file system access (path_provider)
- Any plugin usage
- Any other async operations
import 'package:flutter_elavon/flutter_elavon.dart';
import 'package:flutter/widgets.dart';
// ✅ CORRECT: ensureInitialized() is the first line
void main() async {
WidgetsFlutterBinding.ensureInitialized(); // MUST be first!
// Now you can safely use plugins, databases, path_provider, etc.
runApp(MyApp());
}
// ❌ WRONG: Don't do this!
void main() async {
// This will cause path_provider channel errors!
final db = await DBHelper.openDb(); // ❌ Called before ensureInitialized()
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
// Initialize and create account
final elavon = FlutterElavon();
await elavon.createAccount(PaymentGatewayType.CONVERGE);
// Find and connect devices
final devices = await elavon.findDevices();
if (devices.isNotEmpty) {
await elavon.connectDevice(devices.first);
}
// Process a sale transaction
final result = await elavon.processSale(
amount: 10000, // Amount in cents
currencyCode: 'USD',
);
// Process a sale with transaction options (card types, entry types, etc.)
import 'package:flutter_elavon/models/transaction_options.dart';
import 'package:flutter_elavon/models/enums.dart';
final transactionOptions = TransactionOptions(
// Card account types: CREDIT, DEBIT, EBT_FOOD_STAMP, EBT_CASH_BENEFIT
allowedCardTypes: [CardType.CREDIT, CardType.DEBIT],
// Or card brands: VISA, MASTERCARD, AMEX, DISCOVER, etc.
// allowedCardTypes: [CardType.VISA, CardType.MASTERCARD],
// Card entry types (optional)
// allowedCardEntryTypes: ['SWIPE', 'EMV_CONTACT', 'EMV_PROXIMITY', 'MANUALLY_ENTERED'],
);
final result = await elavon.processSale(
amount: 10000,
currencyCode: 'USD',
transactionOptions: transactionOptions,
);
// Listen to transaction events
elavon.transactionEvents.listen((event) {
print('Transaction event: ${event.type}');
});
Troubleshooting #
Build Error: Could not find AAR files #
If you get errors like:
Could not find :commerce-android-6.8.0:.
Searched in the following locations:
- file:/Users/.../android/libs/commerce-android-6.8.0.aar
Important: If you're using the plugin from pub.dev, you should ONLY need files in your app's directory. If you're being asked to add files to the plugin's directory, something is wrong.
Solution:
-
Check file location: Make sure all AAR and JAR files are in the correct directory:
- If using
dirs 'libs'in repositories → files should be inandroid/app/libs/ - If using
dirs '../libs'→ files should be inandroid/libs/
- If using
-
Verify file names: Ensure the AAR file names match exactly (case-sensitive):
commerce-android-6.8.0.aar(notCommerce-Android-6.8.0.aar)- Check for exact matches including the
.aarextension
-
Check repositories block: Make sure the
repositoriesblock is in the correct location:// In android/app/build.gradle repositories { flatDir { dirs 'libs' // Relative to android/app/ } } -
Sync Gradle: After making changes:
cd android ./gradlew clean cd .. flutter clean flutter pub get -
Verify files exist: Check that files are actually in the directory:
ls -la android/app/libs/*.aar -
If you get "package com.elavon.commerce does not exist" error:
- This means the plugin can't find the AAR files during compilation
- Quick Fix: Use Option 1 - add files to plugin directory (one-time setup):
# Find your plugin version flutter pub deps | grep flutter_elavon # Copy files to plugin directory (replace 1.0.5 with your version) cp -r your_project/android/app/libs/* ~/.pub-cache/hosted/pub.dev/flutter_elavon-1.0.5/android/libs/ - Alternative: If using Option 2, make sure you've set the Gradle property:
- Create/edit
your_project/android/gradle.properties - Add:
flutterElavonAppLibsPath=app/libs - Run
flutter cleanand rebuild
- Create/edit
-
If you're asked to add files to the plugin's directory: This shouldn't happen when using the published package. Try:
- Run
flutter cleanandflutter pub getagain - Check that you're using the plugin from pub.dev, not a local path:
dependencies: flutter_elavon: ^1.0.4 # ✅ Correct - from pub.dev # flutter_elavon: # path: ../flutter_elavon # ❌ Wrong - this requires files in plugin directory - If using a local path dependency, you'll need files in both places (plugin's libs for compilation, app's libs for runtime)
- Run
PlatformException: Unable to establish connection on channel path_provider #
If you encounter this error:
PlatformException(channel-error, Unable to establish connection on channel: "dev.flutter.pigeon.path_provider_android.PathProviderApi.getApplicationDocumentsPath"., null, null)
Root Cause:
This error occurs when path_provider (or any plugin) is used before it's fully registered. Even if you call WidgetsFlutterBinding.ensureInitialized() first, there can be a race condition where plugin registration happens asynchronously. Common causes:
- Calling
getApplicationDocumentsDirectory()inmain()beforeensureInitialized() - Initializing databases in
main()beforeensureInitialized() - Using any Flutter plugins before
ensureInitialized() - Race condition: Even with
ensureInitialized()called first, plugins may not be fully registered yet when the SDK tries to access them
Solution:
-
Move
WidgetsFlutterBinding.ensureInitialized()to the very first line of yourmain()function:void main() async { WidgetsFlutterBinding.ensureInitialized(); // MUST be first line! // Now safe to use plugins, databases, path_provider, etc. final db = await DBHelper.openDb(); // ✅ Now safe runApp(MyApp()); } -
Ensure
path_provider: ^2.1.0is explicitly added to your app'spubspec.yamldependencies -
Run a clean rebuild:
flutter clean flutter pub get flutter run -
If you're still getting the error even after calling
ensureInitialized()first, try adding a small delay:void main() async { WidgetsFlutterBinding.ensureInitialized(); // Small delay to ensure plugins are fully registered (handles race condition) await Future.delayed(Duration(milliseconds: 200)); // Now safe to use plugins, databases, path_provider, etc. final db = await DBHelper.openDb(); runApp(MyApp()); } -
Check your code for any plugin usage before
ensureInitialized():- Search for
getApplicationDocumentsDirectory()calls - Search for database initialization
- Search for any plugin method calls in
main() - Move all of these after
WidgetsFlutterBinding.ensureInitialized()
- Search for
License #
See LICENSE file for details.