easymerchantsdk 1.4.0
easymerchantsdk: ^1.4.0 copied to clipboard
Lyfecycle Payments SDK for Flutter — native mobile checkout (card, ACH, 3DS). Pub package easymerchantsdk.
Lyfecycle Payments SDK for Flutter #
The Lyfecycle Payments SDK (Flutter) provides a Flutter interface for Lyfecycle native mobile checkout on Android and iOS.
- Card and ACH payments
- 3D Secure, recurring payments, saved cards/accounts
makePayment— API key + secret keymakePaymentV2— client token from your backend
Pub package name:
easymerchantsdk— use this inpubspec.yamlandimport 'package:easymerchantsdk/easymerchantsdk.dart';. The product name is Lyfecycle Payments SDK.
Pub.dev: pub.flutter-io.cn/packages/easymerchantsdk
Sample app: em-MobileCheckoutSDK-Flutter / local flutter-sdk-demo-app
Requirements #
| Platform | Minimum |
|---|---|
| Flutter | 3.3+ |
| Dart | 3.5+ (sdk: ">=3.5.0 <4.0.0") |
| Android | minSdk 24+ |
| iOS | 16.0+, Xcode 14+, CocoaPods |
You need Lyfecycle credentials (sandbox / staging / production) from your account team.
1. Add the Lyfecycle Payments SDK #
In your app pubspec.yaml (package id easymerchantsdk):
dependencies:
easymerchantsdk: ^1.4.0
flutter pub get
For local development against this repo:
dependencies:
easymerchantsdk:
path: ../em-MobileCheckoutSDK-Flutter
2. Android setup #
The plugin depends on the native Android SDK com.app:paysdk hosted on GitHub Packages. Your app must expose Maven credentials at build time.
android/build.gradle or android/build.gradle.kts #
Add the GitHub Maven repository (example Kotlin DSL):
// android/build.gradle.kts
val githubMavenUrl = System.getenv("GITHUB_MAVEN_URL")
?: "https://maven.pkg.github.com/EasyMerchant/em-MobileCheckoutSDK-Android"
val githubReadActor = System.getenv("GITHUB_READ_ACTOR") ?: ""
val githubReadToken = System.getenv("GITHUB_READ_TOKEN") ?: ""
allprojects {
repositories {
google()
mavenCentral()
maven { url = uri("https://jitpack.io") }
maven {
url = uri(githubMavenUrl)
credentials {
username = githubReadActor
password = githubReadToken
}
}
}
}
Groovy build.gradle equivalent:
def githubMavenUrl = System.getenv("GITHUB_MAVEN_URL") ?: "https://maven.pkg.github.com/EasyMerchant/em-MobileCheckoutSDK-Android"
def githubReadActor = System.getenv("GITHUB_READ_ACTOR") ?: ""
def githubReadToken = System.getenv("GITHUB_READ_TOKEN") ?: ""
allprojects {
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
maven {
url = uri(githubMavenUrl)
credentials {
username = githubReadActor
password = githubReadToken
}
}
}
}
Environment variables (required for CI and local builds) #
export GITHUB_READ_ACTOR="your-github-username-or-bot"
export GITHUB_READ_TOKEN="ghp_xxxxxxxx" # PAT with read:packages
Optional override:
export GITHUB_MAVEN_URL="https://maven.pkg.github.com/EasyMerchant/em-MobileCheckoutSDK-Android"
AndroidManifest #
<uses-permission android:name="android.permission.INTERNET" />
3. iOS setup #
Native UI sources are bundled in the plugin (no separate XCFramework download for Flutter).
cd ios
pod install
cd ..
Open ios/Runner.xcworkspace in Xcode (not .xcodeproj).
Info.plist (network) #
If you need cleartext HTTP in dev:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
AppDelegate (GrailPay / ACH deep links — optional) #
Forward custom URL schemes to the plugin from ios/Runner/AppDelegate.swift:
import Flutter
import UIKit
@main
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
override func application(
_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any] = [:]
) -> Bool {
if EasymerchantSdkPlugin.handleDeepLink(url: url) {
return true
}
return super.application(app, open: url, options: options)
}
}
Register your URL schemes in Info.plist (CFBundleURLTypes) as required by GrailPay / your bank flow.
4. Basic usage #
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:easymerchantsdk/easymerchantsdk.dart';
// Lyfecycle Payments SDK entry point (class name matches pub package)
final lyfecyclePaymentsSdk = Easymerchantsdk();
Event listeners (recommended) #
The native SDK also pushes events on a broadcast channel. Set this up once (e.g. in initState):
lyfecyclePaymentsSdk.setupEventListeners(
onPaymentSuccess: (jsonString) {
final data = jsonDecode(jsonString);
debugPrint('Success: $data');
},
onPaymentStatusError: (jsonString) {
final data = jsonDecode(jsonString);
debugPrint('Error/cancel: $data');
},
onPaymentPending: (jsonString) {
// iOS only: initial hosted form load (status pending in chargeData)
debugPrint('Pending: $jsonString');
},
);
Flow A — makePayment (API key + secret) #
Step 1 — Configure environment (once per session):
await lyfecyclePaymentsSdk.configureEnvironment(
'sandbox', // 'sandbox' | 'staging' | 'production'
'your-api-key',
'your-secret-key',
);
Step 2 — Build config JSON and pay:
final config = {
'environment': 'sandbox',
'amount': '10.00',
'currency': 'usd',
'paymentMethods': ['card', 'ach'],
'saveCard': true,
'saveAccount': true,
'secureAuthentication': true,
'authenticatedACH': false,
'showReceipt': true,
'showTotal': true,
'showSubmitButton': true,
'submitButtonText': 'Pay now',
'email': 'user@example.com',
'name': 'Jane Doe',
'fields': {
'visibility': {'billing': true, 'additional': true},
'billing': [
{'name': 'address', 'required': true, 'value': '123 Main St'},
{'name': 'country', 'required': true, 'value': 'United States'},
{'name': 'state', 'required': true, 'value': 'California'},
{'name': 'city', 'required': false, 'value': 'San Francisco'},
{'name': 'postal_code', 'required': false, 'value': '94105'},
],
'additional': [
{'name': 'phone_number', 'required': false, 'value': '+1-555-123-4567'},
{'name': 'description', 'required': false, 'value': 'Order #123'},
],
},
'appearanceSettings': {
'theme': 'light',
'bodyBackgroundColor': '#FFFFFF',
'primaryButtonBackgroundColor': '#2563EB',
},
};
final result = await lyfecyclePaymentsSdk.makePayment(jsonEncode(config));
if (result != null) {
final response = jsonDecode(result);
// Handle response (see format below)
}
apiKey / secretKey may be included in the JSON for makePayment on some setups; configuring via configureEnvironment is required for the native layer.
Flow B — makePaymentV2 (client token) #
Obtain a client_token from your backend (Payment Intent / hosted checkout API), then:
final config = {
'environment': 'sandbox',
'amount': '25.00',
'currency': 'usd',
'clientToken': clientTokenFromYourBackend,
'paymentMethods': ['card', 'ach'],
'saveCard': false,
'saveAccount': false,
'secureAuthentication': true,
'fields': { /* same shape as makePayment */ },
};
final result = await lyfecyclePaymentsSdk.makePaymentV2(jsonEncode(config));
You do not need configureEnvironment for V2 if the token already encodes the session (demo app still sets keys for token generation on the server side).
Payment reference (3DS / follow-up) #
After 3DS or certain flows you may receive a referenceToken in the response. Resume payment with:
final result = await lyfecyclePaymentsSdk.paymentReference(referenceToken);
5. Payment result format #
Aligned with the React Native SDK (iOS native bridge). Parse the JSON string returned by makePayment / makePaymentV2 / events.
Success #
{
"status": "success",
"chargeData": { },
"billingInfo": { },
"additionalInfo": { },
"referenceToken": "optional-from-3ds"
}
Error #
{
"status": "error",
"message": "Human-readable error"
}
Cancelled #
{
"status": "cancelled",
"message": "Payment cancelled"
}
Android may still return legacy shapes in some paths ("status": true boolean). Prefer checking both during migration:
bool isSuccess(dynamic status) =>
status == 'success' || status == true;
6. Configuration reference (common keys) #
| Key | Type | Description |
|---|---|---|
environment |
String |
sandbox, staging, production |
amount |
String |
Decimal amount as string, e.g. "10.00" |
currency |
String |
e.g. usd |
paymentMethods |
List<String> |
card, ach |
clientToken |
String |
Required for makePaymentV2 |
tokenOnly |
bool |
Tokenize without charge |
saveCard / saveAccount |
bool |
Save payment methods |
secureAuthentication |
bool |
3DS when supported |
authenticatedACH |
bool |
GrailPay / verified ACH |
showReceipt / showTotal / showSubmitButton |
bool |
UI toggles |
fields |
Object |
Billing & additional field visibility/values |
appearanceSettings |
Object |
Theme colors, fonts, radius |
grailPayParams |
Object |
role, timeout (min 11), brandingName, etc. |
is_recurring |
bool |
Recurring payment |
recurringIntervals |
List<String> |
daily, weekly, monthly, … |
metadata |
Object |
Custom metadata |
See the demo app buildPaymentConfiguration() in MainPaymentView.dart / ClientPaymentView.dart for a full working example.
7. API summary #
| Method | Description |
|---|---|
configureEnvironment(env, apiKey, secretKey) |
Set native API environment (for makePayment) |
makePayment(configJson) |
Hosted checkout with API credentials |
makePaymentV2(configJson) |
Hosted checkout with clientToken |
paymentReference(referenceToken) |
Continue after 3DS / reference flow |
setViewController() |
iOS: bind root VC (usually optional) |
getPlatformVersion() |
Debug helper |
setupEventListeners(...) |
Subscribe to PaymentSuccess / PaymentStatusError / PaymentPending |
8. Troubleshooting #
| Issue | What to check |
|---|---|
Android: failed to resolve com.app:paysdk |
GITHUB_READ_ACTOR / GITHUB_READ_TOKEN on app android/build.gradle |
| iOS: pod errors | cd ios && pod install, use .xcworkspace |
| iOS: presentation errors | Call payment from a visible screen; avoid presenting from a modal host |
| Empty / parse errors | Pass JSON string via jsonEncode(map), not a raw Map |
| Gradle Kotlin mismatch | Plugin uses Kotlin 2.0.21 and paysdk 2.0.9 (aligned with RN SDK) |
9. Version & support #
- Changelog: CHANGELOG.md
- Issues: GitHub Issues
- Homepage: lyfecycletech.com
For credential and backend Payment Intent setup, contact Lyfecycle Payments support.