Atom NEXT API Reference
Version History
| Version | Date | Author | Notes |
|---|---|---|---|
v1.0.0 | 2026-03-23 | Tim LIN | Initial version. |
v1.0.1 | 2026-05-09 | chengxi | Add restful method and change connectionType method. |
Table of Contents
- Atom NEXT API Reference
- Version History
- Table of Contents
- Overview
- Quick Start (Recommended:
AtomNext) - API Methods (Recommended Layer:
AtomNext) - API Methods (AIDL Layer)
- Bundle Keys (
KeyConst) transNameValues (InvokeTransName)- Validation Matrix (Current Implementation)
- Result Callback Fields
- Error Codes (
Errors) - Kotlin Example
- Best Practices
- External Call Examples (Non-AIDL)
Overview
Atom NEXT provides threeintegration layers:
- Recommended: use the
AtomNexthelper class (AIDL by default, with optional NET socket mode or restful mode) - Low-level: bind directly to
IAtomNext.aidl
All requests and results use Android Bundle. Results are returned asynchronously through callbacks.
Quick Start (Recommended: AtomNext)
1) Initialize
AtomNext.me(context).init(param, listener)
- Success callback:
AtomNextListener.onSuccess() - Failure callback:
AtomNextListener.onError(errorCode)
2) Start a transaction
AtomNext.me(context).transact(params, transactionListener)
- Completion callback:
TransactionListener.onTransactionResult(resultBundle) - Interactive callback:
TransactionListener.onInteractiveCallback(callbackBundle)(optional)
3) Release
AtomNext.me(context).release()
API Methods (Recommended Layer: AtomNext)
init(param: Bundle?, listener: AtomNextListener): Unit
Initializes Atom NEXT connectivity.
Syntax
AtomNext.me(context).init(param, listener)
Parameters
param(Bundle?): optional initialization bundle.connectionType(Int):0(AIDL, default) or1(Socket) or2(Restful)remoteIp(String): required whenconnectionType=1orconnectionType=2remotePort(Int): optional whenconnectionType=1orconnectionType=2, default5000
listener(AtomNextListener): initialization callbacks.
Returns
Unit(asynchronous result via callbacks).
Throws
- No direct exception is exposed by this helper method.
Callbacks
onSuccess(): initialization completed.onError(error: Int): initialization failed or service disconnected.
Notes
- In AIDL mode, service binding target is
atomnext-api-servicein packagecom.landiglobal.atomnext. - In NET mode, connectivity errors are reported through
onError.
transact(params: Bundle, listener: TransactionListener): Unit
Starts a transaction request.
Syntax
AtomNext.me(context).transact(params, listener)
Parameters
params(Bundle): transaction input bundle; must includetransName.listener(TransactionListener): transaction callbacks.
Returns
Unit(asynchronous result viaonTransactionResult).
Throws
- No direct exception is exposed by this helper method.
Callbacks
onTransactionResult(result: Bundle): final transaction result.onInteractiveCallback(result: Bundle): Bundle?: optional interactive callback for two-way interaction.
Notes
- If initialization is not completed, callback returns
result = ERROR_INITIALIZE. - AIDL mode forwards to remote
IAtomNext.transact(...). - NET mode converts
Bundleto JSON and sends via socket.
release(): Unit
Releases resources.
Syntax
AtomNext.me(context).release()
Parameters
- None.
Returns
Unit.
Throws
- No direct exception is exposed by this helper method.
Notes
- In AIDL mode, the client calls remote
finalize(Bundle()). - The client unbinds the service and clears local service reference state.
API Methods (AIDL Layer)
initialize(in Bundle bundle, IBinder appBinder, TransactionListener listener): void
Initializes the remote Atom NEXT service.
Syntax
void initialize(in Bundle bundle, IBinder appBinder, TransactionListener listener)
Parameters
bundle: initialization bundleappBinder: caller binder tokenlistener: AIDL transaction listeneronTransactionFinished(in Bundle result): init result callbackonInteractiveCallback(in Bundle callback): Bundle: optional interactive callback
Returns
void(asynchronous initialization result is returned throughonTransactionFinished).
Throws
RemoteException(at caller side, as part of Binder IPC contract).
finalize(in Bundle bundle): void
Finalizes and releases service-side resources for the caller.
Syntax
void finalize(in Bundle bundle)
Parameters
bundle: finalize options bundle (currently not consumed by implementation).
Returns
void.
Throws
RemoteException(at caller side, as part of Binder IPC contract).
transact(in Bundle bundle, TransactionListener listener): void
Starts a transaction on service side and returns asynchronous result through listener.
Syntax
void transact(in Bundle bundle, TransactionListener listener)
Parameters
bundle: transaction request bundle.listener: callback listener for final/interactive responses.
Returns
void(transaction result is asynchronous).
Throws
RemoteException(at caller side, as part of Binder IPC contract).
Service binding info (AIDL):
- action:
atomnext-api-service - package:
com.landiglobal.atomnext
Bundle Keys (KeyConst)
All keys below are literal values used in Android Bundle.
Init Bundle
| Key | Type | Required | Description |
|---|---|---|---|
connectionType | Int | No | Connection type: 0=AIDL (default), 1=SOCKET, 2=RESTFUL |
remoteIp | String | Conditional | Required when connectionType=1 or connectionType=2 |
remotePort | Int | No | server port, default 5000 when connectionType=1 or 9000 when connectionType=2 |
Transaction Request Bundle
| Key | Type | Required | Description |
|---|---|---|---|
transName | String | Yes | Transaction name; see InvokeTransName values below |
amount | String | Conditional | Transaction amount (usually 12-digit numeric string). Validation depends on transaction type |
customizedTraceNo | String | No | Third-party custom trace number |
additionalPrintData | String | No | Additional print data |
merchantId | String | No | Merchant ID; if absent/invalid, implementation selects first available merchant |
maskedCardNo | Boolean | No | Whether PAN in callback should be masked; default true |
oldTraceNo | String | Conditional | Original trace number (used by void-related flows) |
oldReferenceNo | String | Conditional | Original reference number (used by refund flow) |
oldAuthCode | String | Conditional | Original authorization code |
oldDate | String | Conditional | Original transaction date (MMdd) |
oldVoucherNo | String | Conditional | Original voucher number |
needManagerPwd | Boolean | No | Whether manager password is required for invoke transaction |
Result Bundle
| Key | Type | Always Present | Description |
|---|---|---|---|
result | Int | Yes | Result code; see Error Codes |
errorMsg | String | No | Error description when failed |
amount | String | No | Transaction amount |
traceNo | String | No | Transaction trace number |
voucherNo | String | No | Voucher number |
referenceNo | String | No | Reference number |
authCode | String | No | Authorization code |
cardNo | String | No | Card number (masked/unmasked based on maskedCardNo) |
cardOrg | String | No | Card organization |
acquirerIdentifier | String | No | Acquirer identifier |
batchNo | String | No | Batch number |
terminalId | String | No | Terminal ID |
merchantId | String | No | Merchant ID |
merchantName | String | No | Merchant name |
date | String | No | Date (MMdd) |
time | String | No | Time (HHmmss) |
balance | String | No | Balance result (for balance inquiry) |
merchantInfoList | ArrayList<Bundle> | No | Merchant info list (for TRANS_GET_MERCHANT_INFO_LIST) |
transName Values (InvokeTransName)
Use the exact string values below:
| Value | Meaning | Typical Required Keys |
|---|---|---|
CONSUME | Sale | transName, amount |
VOID | Void sale | transName, oldTraceNo (typical) |
BALANCE | Balance inquiry | transName |
SETTLE | Settlement | transName |
MANAGE | Management menu | transName |
REFUND | Refund | transName (often with one of amount / oldReferenceNo / oldDate) |
LOGIN | Sign-in | transName |
REPRINT | Reprint | transName |
INIT_PRINT | Printer initialization | transName |
PARAMETER | Terminal parameters | transName |
SYSTEM_PASSWORD | System administrator password | transName |
QUERY_MENU | Transaction query menu | transName |
SCAN_SALE | Scan sale | transName, amount |
SCAN_VOID | Scan void | transName |
SCAN_REFUND | Scan refund | transName (often with amount) |
AUTH | Pre-authorization | transName, amount |
AUTH_VOID | Pre-auth void | transName |
AUTH_COMPLETE | Pre-auth completion (request) | transName |
AUTH_SETTLEMENT | Pre-auth settlement (notification) | transName |
AUTH_COMPLETE_VOID | Pre-auth completion void | transName, oldTraceNo (typical) |
SCAN_AUTH_VOID | Scan pre-auth void | transName |
SCAN_AUTH_COMPLETE_VOID | Scan pre-auth completion void | transName |
TRANS_GET_MERCHANT_INFO_LIST | Get merchant info list | transName |
Validation Matrix (Current Implementation)
Validation rules are implemented in InvokeController.checkOnBeforeStartTrans().
| Rule Item | Applies To | Validation Rule | Error Code on Failure |
|---|---|---|---|
transName | All transactions | Must be non-empty and in supported InvokeTransName list | ERROR_OTHER |
amount format | CONSUME, AUTH, SCAN_SALE, REFUND, SCAN_REFUND (when present) | Must match ^[0-9]{12}$ | ERROR_INVALID_AMOUNT |
amount > 0 | CONSUME, AUTH, SCAN_SALE, REFUND, SCAN_REFUND (when present) | Must be greater than zero | ERROR_INVALID_AMOUNT |
amount max limit | Any transaction with amount present | Must pass checkAmountValid | ERROR_INVALID_AMOUNT |
oldTraceNo format | VOID, AUTH_COMPLETE_VOID (when present) | Must match ^[0-9]{6}$ | ERROR_ORIGINAL_TRANS_NOT_EXIST |
oldReferenceNo format | REFUND (when present) | Must match `^[0-9 | a-z |
oldDate format | REFUND (when present) | Must match ^[0-9]{4}$ (MMdd) | ERROR_INVALID_OLD_DATE |
oldDate validity | REFUND (when present) | Must be a valid calendar date in MMdd | ERROR_INVALID_OLD_DATE |
Implementation notes:
- Most key validations are validate-if-present; transaction business flow may still require additional fields.
TRANS_GET_MERCHANT_INFO_LISTreturnsmerchantInfoListon success.
Result Callback Fields
Common
Always check:
result: result codeerrorMsg: error description on failure (may be empty)
Error Codes (Errors)
| Name | Value |
|---|---|
SUCCESS | 0 |
ERROR_OTHER | -1 |
ERROR_INITIALIZE | -2 |
ERROR_SELF_DETECTING | -3 |
ERROR_CANCELLED | -4 |
ERROR_TIMEOUT | -5 |
ERROR_PARAM | -6 |
ERROR_SAVING_DATA | -7 |
ERROR_COMMUNICATION | -8 |
ERROR_ORIGINAL_TRANS_NOT_EXIST | -9 |
ERROR_REFUND_AMOUNT_EXCEED | -10 |
ERROR_INVALID_AMOUNT | -11 |
ERROR_INVALID_OLD_REF_NO | -12 |
ERROR_INVALID_OLD_DATE | -13 |
ERROR_INVALID_OUT_TRACE_NO | -14 |
ERROR_BIND_FAIL | 0x01 |
ERROR_SERVICE_DIED | 0x02 |
ERROR_REMOTE_EXCEPTION | 0x03 |
ERROR_SERVER_CONNECTION | 0x04 |
ERROR_SERVER_DISCONNECTED | 0x05 |
Kotlin Example
val initBundle = Bundle().apply {
putInt("connectionType", 0) // 0:AIDL, 1:NET
}
AtomNext.me(context).init(initBundle, object : AtomNextListener {
override fun onSuccess() {
val params = Bundle().apply {
putString("transName", "CONSUME")
putString("amount", "000000001000")
putBoolean("maskedCardNo", true)
}
AtomNext.me(context).transact(params, object : TransactionListener {
override fun onTransactionResult(result: Bundle) {
val code = result.getInt("result")
val error = result.getString("errorMsg")
// handle by result code
}
})
}
override fun onError(error: Int) {
// initialization failure handling
}
})
Best Practices
- Wait for
init()success callback before callingtransact() - Always check
result; never assume success - Pass only fields required by the current transaction
- Keep masked PAN by default (
maskedCardNo=true) - Call
release()when your component is destroyed or no longer needs Atom NEXT
External Call Examples (Non-AIDL)
These examples demonstrate how external clients (e.g., a Windows PC or another Android device) can interact with Atom NEXT services over the network.
1. RESTful API Example (CURL)
The RESTful service listens for POST requests. In Windows CMD, you must escape double quotes with a backslash \".
Transaction Request (Consume)
- URL:
http://{DEVICE_IP}:5000/api/v1/transact - Method:
POST - Body: JSON
curl -X POST http://172.26.110.38:9000/api/v1/transact ^
-H "Content-Type: application/json" ^
-d "{\"transName\": \"CONSUME\", \"amount\": \"000000001000\"}"
Initialization
- URL:
http://{DEVICE_IP}:5000/api/v1/init
curl -X POST http://172.26.110.38:9000/api/v1/init -H "Content-Type: application/json" -d "{}"
2. Socket Example (Kotlin/JVM)
The Socket service expects a JSON string. The connection is typically closed by the server after the response is sent.
import java.net.Socket
import java.io.InputStream
import java.io.OutputStream
fun callSocketTransaction(ip: String, port: Int) {
try {
Socket(ip, port).use { socket ->
val output: OutputStream = socket.getOutputStream()
val input: InputStream = socket.getInputStream()
// 1. Prepare Request JSON
val requestJson = """
{
"transName": "CONSUME",
"amount": "000000001000",
"maskedCardNo": true
}
""".trimIndent()
// 2. Send Data
output.write(requestJson.toByteArray(Charsets.UTF_8))
output.flush()
// 3. Read Response
val buffer = ByteArray(4096)
val bytesRead = input.read(buffer)
if (bytesRead != -1) {
val responseJson = String(buffer, 0, bytesRead, Charsets.UTF_8)
println("Response from POS: ${responseJson}")
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
3. RESTful Example (Android/Kotlin)
This standard implementation uses HttpURLConnection. In a real production app, consider using libraries like OkHttp or Retrofit.
import java.io.OutputStreamWriter
import java.net.HttpURLConnection
import java.net.URL
import java.util.Scanner
fun callRestApi(ip: String, port: Int, transName: String, amount: String) {
Thread {
try {
val url = URL("http://${ip}:${port}/api/v1/transact")
val conn = url.openConnection() as HttpURLConnection
conn.requestMethod = "POST"
conn.setRequestProperty("Content-Type", "application/json")
conn.doOutput = true
conn.connectTimeout = 5000
conn.readTimeout = 65000 // Transactions may take time
// 1. Send Request
val jsonInput = "{\"transName\": \"${transName}\", \"amount\": \"${amount}\"}"
conn.outputStream.use { os ->
OutputStreamWriter(os, "UTF-8").use { writer ->
writer.write(jsonInput)
writer.flush()
}
}
// 2. Read Response
val responseCode = conn.responseCode
val responseStream = if (responseCode == HttpURLConnection.HTTP_OK) {
conn.inputStream
} else {
conn.errorStream
}
Scanner(responseStream, "UTF-8").useDelimiter("\\A").use { s ->
val result = if (s.hasNext()) s.next() else ""
println("HTTP Response (${responseCode}): ${result}")
}
} catch (e: Exception) {
e.printStackTrace()
}
}.start()
}
Protocol Notes
- Encoding: All JSON strings should be encoded in
UTF-8. - Port Management: Default ports are configured via
ThirdPartyApiServer. Standard is5000. - Timeouts: Ensure your client has a sufficient timeout (at least 60 seconds) as financial transactions involve hardware interaction and user input.