*New - Flutter ECR SDK
Use the NamiECR Lib API to integrate payment acceptance into Flutter applications. This SDK enables developers to initialize connections, send transaction requests, and process responses across Android and iOS platforms. It is intended for developers with experience in POS systems, mobile SDKs, and object‑oriented programming.
For environment setup and SDK details. refer to Flutter ECR Integration Library.
Supported Connections
| Platform | Connection Types | Notes |
|---|---|---|
| iOS | TCP/IP | Stable network integration |
| Android | TCP/IP, Bluetooth, App‑to‑App | App‑to‑App requires mada app installed |
Transaction Flow
Initialize SDK → Configure POS → Connect Device → Register (txnType 17) → Start Session (txnType 18) → Execute Transaction → Receive Response → Parse Response
Integration Steps
Step 1: Set Up Environment
Configure your Android project before integrating the Flutter ECR SDK. Ensure the application has the correct permissions, USB host support, and SDK linkage.
Add these entries to AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
Step 2: Add SDK to Project
- Use the following code for adding the SDK in
pubspec.yaml:
dev_dependencies:
ecrlib:
path: 'ecrlib'
Then import the SDK in your Dart code:
import 'package:ecrlib/ecrlib.dart';
Step 3: Initialize Services
Use the following code for initializing services:
TcpConnect tcpSocket = TcpConnect();
final AppToAppConnect _webSocketService = AppToAppConnect();
final BluetoothService _bluetoothService = BluetoothService();
ConfigModel configData = ConfigModel();
late FileService fileService;
Step 4: Establish Connection
Use the following code for connecting and disconnecting:
TCP/IP
int status = await tcpSocket.connectTCP(ip, port, cashRegiNum);
tcpSocket.disconnect();
App‑to‑App
final int? response = await _webSocketService.connect(cashRegiNum);
_webSocketService.disconnect();
Bluetooth
int? a = await _bluetoothService.connectDevice(device, cashRegiNum);
_bluetoothService.disconnectDevice();
Step 5: Manage Configuration
Use the following code for saving and retrieving configuration:
int response = await ConfigManager.setConfiguration(configData);
configData = await ConfigManager.getConfiguration();
Step 6: Configure Required Parameters
Before initiating payment, configure the following required parameters:
// Set Cash Register Number (CRN) – must be an 8-digit numeric value
static TextEditingController cashRegiNumber = TextEditingController();
// Configure Printer (_draft.printChoice)
// 0 = Disable printer
// 1 = Enable printer
int printerChoice = _draft.printChoice;
// Generate unique number
final String uniqueNumber = EncryptionUtil.getSixDigitUniqueNumber();
// Generate Signature
String signature = EncryptionUtil.getSha256Hash(uniqueNumber, config!.terminalId!);
// Generate ECR reference number
final String ecrRef = "${cashRegiNumber.text}${EncryptionUtil.getSixDigitUniqueNumber()}";
// Build request data
String reqData = "${EncryptionUtil.getFormattedDateTime()};${payAmount.text};${printerChoice}!;$ecrRef!;";
// Convert to Hex
final String hexReqData = EncryptionUtil.stringToHex(reqData);
Step 7: Initiate Payment
Once parameters are configured, initiate the payment by sending the transaction request:
// Send transaction through TCP/IP
await tcpSocket.doTransaction(
reqData: hexReqData,
txnType: _draft.transactionType,
signature: signature,
listener: this,
);
// Send transaction through Bluetooth
await bluetoothService.doTransaction(
reqData: hexReqData,
txnType: _draft.transactionType,
signature: signature,
listener: this,
);
// Send transaction through App‑to‑App
await webSocketService.doTransaction(
reqData: hexReqData,
txnType: _draft.transactionType,
signature: signature,
listener: this,
);
Step 8: Transaction Types
Use the following code formats for different transaction types:
Purchase
"${EncryptionUtil.getFormattedDateTime()};${payAmount.text};$_printTransactionType!;$ecrRef!;"
Purchase with Cashback
"${EncryptionUtil.getFormattedDateTime()};${payAmount.text};${cashbackAmount.text};$_printTransactionType!;$ecrRef!;"
Refund
"${EncryptionUtil.getFormattedDateTime()};${refundAmount.text};${rrn.text};$_printTransactionType!;${origRefundDate.text};$ecrRef!;"
Pre‑Authorization
"${EncryptionUtil.getFormattedDateTime()};${authAmount.text};$_printTransactionType!;$ecrRef!;"
Purchase Advice
"${EncryptionUtil.getFormattedDateTime()};${authAmount.text};${rrn.text};${origTransactionDate.text};${originalApprovalCode.text};$captureType;$_printTransactionType!;$ecrRef!;"
Pre‑Auth Extension
"${EncryptionUtil.getFormattedDateTime()};${rrn.text};${origTransactionDate.text};${originalApprovalCode.text};$_printTransactionType!;$ecrRef!;"
Pre‑Auth Void
"${EncryptionUtil.getFormattedDateTime()};${originalTransactionAmount.text};${rrn.text};${origTransactionDate.text};${originalApprovalCode.text};$_printTransactionType!;$ecrRef!;"
Cash Advance
"${EncryptionUtil.getFormattedDateTime()};${cashAdvanceAmount.text};$_printTransactionType!;$ecrRef!;"
Duplicate
"${EncryptionUtil.getFormattedDateTime()};${prevEcrNo.text};$_printTransactionType!;$ecrRef!;"
Reversal
"${EncryptionUtil.getFormattedDateTime()};${rrn.text};$_printTransactionType!;$ecrRef!;"
Reconciliation
"${EncryptionUtil.getFormattedDateTime()};$_printTransactionType!;$ecrRef!;"
Print Summary Report
"${EncryptionUtil.getFormattedDateTime()};$_printTransactionType!;$ecrRef!;"
Step 9: Process Response
Responses are returned in CSV format.
They contain:
- Response Code
- Approval Code
- Transaction Status
- Receipt Data
Example CSV string:
00,APPROVED,10000,140524193012,TX12345678,RECEIPT123
Parsed Output Mapping:
| Field | Example Value | Description |
|---|---|---|
| Response Code | 00 | Transaction result (00 = Approved) |
| Approval Code | APPROVED | Issuer/host approval code |
| Amount | 10000 | Transaction amount (in minor units) |
| Timestamp | 140524193012 | Date/time in ddMMyyHHmmss format |
| ECR Reference No | TX12345678 | Merchant’s transaction reference number |
| Receipt Data | RECEIPT123 | Printable receipt or structured payload |
Parsing Example (Dart):
String response = "00,APPROVED,10000,140524193012,TX12345678,RECEIPT123";
List<String> fields = response.split(",");
String responseCode = fields[0];
String approvalCode = fields[1];
String amount = fields[2];
String timestamp = fields[3];
String ecrRefNo = fields[4];
String receiptData = fields[5];
Key Rules
- Always initialize services (
TcpConnect,BluetoothService,AppToAppConnect) before transactions. - TCP/IP is the preferred priority connection.
- Bluetooth and App‑to‑App are fallback modes (Android only).
- Transaction type 6 represents the end‑to‑end payment flow.
- Other transaction types (Refund, Reversal, Reconciliation, etc.) are internal system operations.
- References must use mada app (not NamiPay) for App‑to‑App flows.
Final Integration Flow
Initialize Flutter ECR SDK
↓
Set Configuration (ConfigManager.setConfiguration)
↓
Test Connection (connectTCP, connectDevice, or connect)
↓
Select Device Priority (TCP/IP → Bluetooth → App‑to‑App)
↓
Execute Transaction (doTransaction)
↓
Receive Response (CSV string from terminal)
↓
Parse Response (split() and map fields)
Installation Notes
- Requires Flutter 3.0+ and Dart 2.17+.
- Android builds require Android Studio; iOS builds require Xcode.
- Native ECR SDKs (Android/iOS) are bundled inside the Flutter wrapper — no DLLs required.
- Cashier setup (CRN, printer configuration) must be completed at first launch.
- For App‑to‑App, ensure mada app is installed and configured on the Android device.
Updated 1 day ago
