nexgo_flutter 0.1.0
nexgo_flutter: ^0.1.0 copied to clipboard
Free, open Flutter plugin for NEXGO SmartPOS Android terminals — card reader, EMV transactions, PIN pad, and receipt printer.
nexgo_flutter #
Free (MIT) Flutter plugin wrapping the NEXGO SmartPOS SDK v3.08.014 (Android) for NEXGO smart POS terminals (N86, N96, N82, N6, UN20, …).
It bridges Dart to the terminal's onboard hardware and payment stack — card readers, EMV kernels, PIN pad, printer, and more.
⚠️ These APIs only function on genuine NEXGO POS hardware. On a phone or emulator the native calls fail — there is no NEXGO device engine to talk to.
Features #
- Card reader — mag-stripe, contact chip, and contactless, as a stream (
searchCard) - EMV transactions — full
EmvHandler2flow for contact & contactless (startTransaction), with aTransTypefor purchase / cash / cash-back / refund / pre-auth / balance-inquiry - Manual entry — secure hand-keyed PAN/expiry/CVV for card-not-present (
inputManualCard) - QR / barcode scanner — camera scan-to-pay for bill payments (
scanBarcode) - AID / CAPK management — load terminal apps and CA keys (
setAidList,setCapkList) - PIN pad — online PIN entry and TMK/TPK key loading (
inputOnlinePin,writeMasterKey,writePinKey) - Receipt printer — text and QR blocks with alignment and sizing (
printReceipt) - Device — buzzer (
beep), status LEDs (setLed), and terminal info (getDeviceInfo)
This plugin is the terminal layer — it captures the card, EMV cryptogram, PIN block, and prints. Transaction types (refund, void/reversal, pre-auth completion, balance inquiry, settlement, bill/airtime, reporting) are host messages you build on top and send to your payment switch (e.g. LakiPay); they are not terminal SDK features.
Not yet wrapped: the less common card kernels (Mifare/Desfire/NTAG) and MDB/serial APIs — all straightforward to add on the same pattern.
Usage #
import 'package:nexgo_flutter/nexgo_flutter.dart';
final pos = NexgoPos.instance;
await pos.initialize(); // required first — no license key
final info = await pos.getDeviceInfo(); // model, SN, versions
await pos.beep();
await pos.setLed(LedColor.green, on: true);
await pos.printReceipt([
PrintBlock.text('DEMO STORE', fontSize: 32, bold: true, align: PrintAlign.center),
PrintBlock.text('Total: 250.00 ETB', fontSize: 28, bold: true),
PrintBlock.qr('https://example.com/receipt/1001'),
]);
// Card read (stream; cancel to stop)
final sub = pos.searchCard().listen((card) {
print('Card in ${card.slot}, masked ${card.maskCardNo}, ICC=${card.isIcc}');
});
EMV transaction #
The EMV kernel is a state machine: it streams steps, and some steps need a reply. Load your AIDs/CAPKs once, then drive a transaction:
await pos.setAidList([{'aid': 'A0000000031010', 'tacDefault': '...', /* … */}]);
await pos.setCapkList([{'rid': 'A000000003', 'index': 92, 'modulus': '...', 'exponent': '03'}]);
pos.startTransaction(EmvConfig(amount: '25000', forceOnline: true)).listen((event) async {
switch (event) {
case EmvSelectApp(:final apps): await pos.emvSelectApp(0);
case EmvConfirmCard(:final card): await pos.emvConfirmCard(true);
case EmvOnlineRequest(:final field55, :final pinBlock, :final ksn):
// authorize with your host, then:
await pos.emvSubmitOnline(OnlineDecision.approve(authCode: '123456', field55Hex: field55));
case EmvFinish(:final code): print('done: $code');
default: break; // PIN, tap-again, remove-card, prompts are auto-handled
}
});
Online PIN is captured natively when EmvConfig.pinKeyIndex is set (otherwise
bypassed) and surfaced as pinBlock / ksn on EmvOnlineRequest. For
standalone PIN entry outside EMV, use pos.inputOnlinePin(...).
See example/lib/main.dart for a runnable demo.
Setup — add the NEXGO SDK #
This plugin does not include or redistribute NEXGO's SDK — it is NEXGO's proprietary software and not ours to ship. Your app supplies it. This is a one-time, three-step setup.
1. Drop the .aar into your app #
Obtain the .aar from NEXGO and place it in your app under this exact path and
name (create the folders — it's a tiny local Maven repo):
android/nexgo-repo/com/nexgo/smartpos-sdk/3.08.014/smartpos-sdk-3.08.014.aar
# e.g. if NEXGO gave you nexgo-smartpos-sdk-v3.08.014_20260522.aar
mkdir -p android/nexgo-repo/com/nexgo/smartpos-sdk/3.08.014
cp /path/to/nexgo-smartpos-sdk-v3.08.014_20260522.aar \
android/nexgo-repo/com/nexgo/smartpos-sdk/3.08.014/smartpos-sdk-3.08.014.aar
Alongside it, add a smartpos-sdk-3.08.014.pom declaring the coordinates (no
NEXGO code — just Maven metadata). Copy the one from
example/android/nexgo-repo/…,
or paste:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>com.nexgo</groupId>
<artifactId>smartpos-sdk</artifactId>
<version>3.08.014</version>
<packaging>aar</packaging>
</project>
2. Register the repo — android/build.gradle.kts #
allprojects {
repositories {
google()
mavenCentral()
maven { url = uri("${rootDir}/nexgo-repo") } // ← add
}
}
It must be in
allprojects, not just:app— the:nexgo_fluttermodule compiles against the SDK and needs to resolve it too.If your app enforces
dependencyResolutionManagement { repositoriesMode = FAIL_ON_PROJECT_REPOS }, put the samemaven { … }line insettings.gradle.ktsunderdependencyResolutionManagement { repositories { … } }instead.
3. Depend on it — android/app/build.gradle.kts #
dependencies {
implementation("com.nexgo:smartpos-sdk:3.08.014@aar") // ← add
}
That's it. If something's missing, Gradle says exactly what and where it looked:
Could not find com.nexgo:smartpos-sdk:3.08.014.
Searched in the following locations:
- file:.../android/nexgo-repo/com/nexgo/smartpos-sdk/3.08.014/smartpos-sdk-3.08.014.pom
The example/ app is wired exactly this way — copy it verbatim.
How it's wired (for the curious) #
The plugin declares compileOnly("com.nexgo:smartpos-sdk:3.08.014@aar"): it
compiles against the SDK's classes but never bundles them. Your app's
implementation puts them on the runtime classpath, so they land in the APK
exactly once. That split is what lets this plugin be published to pub.flutter-io.cn
without redistributing a byte of NEXGO's code.
The .aar is served as a Maven module rather than a libs/*.aar file
dependency because the Android Gradle Plugin refuses to bundle a local .aar
inside another AAR — which is what a Flutter plugin is.
Requirements #
- Android
minSdk24 (terminal OS is Android 5.1.1+; higher is fine) - A NEXGO POS terminal for any real testing
License #
This wrapper is MIT licensed — see LICENSE. The NEXGO SmartPOS SDK
is not distributed with this package; it remains the property of Shenzhen
Xinguodu Technology and is governed by NEXGO's own terms. The MIT license does
not extend to it. See NOTICE.md.