*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

PlatformConnection TypesNotes
iOSTCP/IPStable network integration
AndroidTCP/IP, Bluetooth, App‑to‑AppApp‑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:

FieldExample ValueDescription
Response Code00Transaction result (00 = Approved)
Approval CodeAPPROVEDIssuer/host approval code
Amount10000Transaction amount (in minor units)
Timestamp140524193012Date/time in ddMMyyHHmmss format
ECR Reference NoTX12345678Merchant’s transaction reference number
Receipt DataRECEIPT123Printable 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.