ECR via RS232 (Retail)
1. Communication Interaction Protocol Data Format
When communicating via serial ports, communication must be adhere to protocol data format defined below. Failure to do so will result in the device being unable to recognize the data
| Start symbol (1Byte) | CMD (2Bytes) | Data Size (2Bytes) | Type (1Byte) | Header CRC (4Bytes) | Data (n Bytes) | Data CRC (4Bytes) |
|---|---|---|---|---|---|---|
| 0x55 | 0xXXXX | 0xXXXX | 0x02 | 0xXXXXXXXX | 0xXXXXXXXX |
- Start symbol:
Fixed value: 0x55. It occupies one byte. The end bit of an entire instruction is determined by the start byte, along with the data structure and length. - CMD:
Occupies two bytes. The command code is defined in the protocol document. - Data Size:
Occupies two bytes. It represents the length of the data field. - Type:
Fixed value: 0x02. It occupies one byte and specifies the type of the current protocol. - Header CRC:
Occupies four bytes. The Header CRC is calculated based on the start symbol, CMD, Data Size, and Type. - Data:
The data field, which occupies n bytes. The content of the data field is defined in the protocol document. - Data CRC:
Occupies four bytes. The Data CRC is calculated from the data field.
2. Request and Response Protocol Data Format
2.1 Request Class
| Variable | Type | Required | Description |
|---|---|---|---|
| version | String | Y | Current communication protocol version number |
| header | Object | Y | Protocol header |
| action | enum | Y | Actions: DeviceInfo, Sale, PreAuth, Abort, Void, Refund |
| requestID | String | Y | Request ID: Every time communication takes place, it is crucial to ensure that the Request ID is a unique UUID. In the event of a response, the corresponding identifier will be returned in the response header as the "responseID". |
| clientDeviceSN | String | Y | Client device serial number |
| timestamp | datetime | N | The timestamp of the current request |
| body | Object | N | Protocol header |
Example:
{
"version": "2.0",
"header": {
"action": "DeviceInfo",
"requestID": "ff467f02-5b69-45f3-81aa-bffcca55fe80",
"clientDeviceSN": "126498561093",
"timestamp": "2025-11-12T10:11:04+00:00"
},
"body": {
...
}
}
2.2 Response Class
| Variable | Type | Required | Description |
|---|---|---|---|
| version | String | Y | Current communication protocol version number |
| header | Object | Y | Protocol header |
| action | enum | Y | Actions: DeviceInfo, Sale, PreAuth, Abort, Void, Refund |
| responseID | String | Y | The response ID in the response Header is derived from the request ID in the request header. |
| serverDeviceSN | String | Y | The serial number of the terminal payment device |
| timestamp | datetime | N | The timestamp of the current request |
| body | Object | N | Protocol header |
Example:
{
"version": 2.0,
"header": {
"action": "DeviceInfo",
"responseID": "ff467f02-5b69-45f3-81aa-bffcca55fe80",
"serverDeviceSN": "NEXGO-N96-1170270945",
"timestamp": "2025-11-12T10:11:04+00:00"
},
"body": {
...
}
}
3. Business Function Communication Interface
3.0 Generate Serial Port Data
The CMD command for functional interface communication is consistently set to 0x0006 and remains static.
// 1. Obtain the JSON data object
const deviceInfoRequestBodyJson = {
"version": 2.0,
"header": {
"action": "DeviceInfo",
"requestID": "ff467f02-5b69-45f3-81aa-bffcca55fe80",
"clientDeviceSN": "126498561093",
"timestamp": "2025-11-12T10:11:04+00:00"
}
};
// Convert JSON data to String
const deviceInfoRequestBodyString = '{"version":2.0,"header":{"action":"DeviceInfo","requestID":"ff467f02-5b69-45f3-81aa-bffcca55fe80","clientDeviceSN":"126498561093","timestamp":"2025-11-12T10:11:04+00:00"}}'';
// 2. Convert String data to Hex
const deviceInfoRequestBodyHex = "7B 22 76 65 72 73 69 6F 6E 22 3A 32 2E 30 2C 22 68 65 61 64 65 72 22 3A 7B 22 61 63 74 69 6F 6E 22 3A 22 44 65 76 69 63 65 49 6E 66 6F 22 2C 22 72 65 71 75 65 73 74 49 44 22 3A 22 66 66 34 36 37 66 30 32 2D 35 62 36 39 2D 34 35 66 33 2D 38 31 61 61 2D 62 66 66 63 63 61 35 35 66 65 38 30 22 2C 22 63 6C 69 65 6E 74 44 65 76 69 63 65 53 4E 22 3A 22 31 32 36 34 39 38 35 36 31 30 39 33 22 2C 22 74 69 6D 65 73 74 61 6D 70 22 3A 22 32 30 32 35 2D 31 31 2D 31 32 54 31 30 3A 31 31 3A 30 34 2B 30 30 3A 30 30 22 7D 7D";
// 3. Header Section
const headerHex = "55 00 06 00 AB 02"
// 4. CRC of the Header
const headerCRC = "6B 17 63 35";
// 5. CRC of the data
const dataCRC = "F5 C2 01 67";
// 6. The entire data finally transmitted through the serial port
const data = "55 00 06 00 AB 02 6B 17 63 35 7B 22 76 65 72 73 69 6F 6E 22 3A 32 2E 30 2C 22 68 65 61 64 65 72 22 3A 7B 22 61 63 74 69 6F 6E 22 3A 22 44 65 76 69 63 65 49 6E 66 6F 22 2C 22 72 65 71 75 65 73 74 49 44 22 3A 22 66 66 34 36 37 66 30 32 2D 35 62 36 39 2D 34 35 66 33 2D 38 31 61 61 2D 62 66 66 63 63 61 35 35 66 65 38 30 22 2C 22 63 6C 69 65 6E 74 44 65 76 69 63 65 53 4E 22 3A 22 31 32 36 34 39 38 35 36 31 30 39 33 22 2C 22 74 69 6D 65 73 74 61 6D 70 22 3A 22 32 30 32 35 2D 31 31 2D 31 32 54 31 30 3A 31 31 3A 30 34 2B 30 30 3A 30 30 22 7D 7D F5 C2 01 67";
3.1 Device Info
Request body class
| Variable | Type | Required | Description |
|---|---|---|---|
| header.action | enum | Y | DeviceInfo |
Example:
{
"version": 2.0,
"header": {
"action": "DeviceInfo",
"requestID": "ff467f02-5b69-45f3-81aa-bffcca55fe80",
"clientDeviceSN": "126498561093",
"timestamp": "2025-11-12T10:11:04+00:00"
}
}
Response body class
| Variable | Type | Required | Description |
|---|---|---|---|
| header.action | enum | Y | DeviceInfo |
| deviceStatus | String | Y | Payment device transaction status: Free / Busy Free: The current device is idle and available for new transactions; Busy: The current device is occupied with an ongoing transaction and is not available for other transactions at the moment. |
| networkStatus | String | Y | The current network connection status of the payment device: Connected / Disconnected |
| softwareVersion | String | Y | The software version of the payment device |
| businessID | String | Y | The response ID in the response Header is derived from the request ID in the request header. |
Example:
{
"version": 2.0,
"header": {
"action": "DeviceInfo",
"responseID": "ff467f02-5b69-45f3-81aa-bffcca55fe80",
"serverDeviceSN": "NEXGO-N96-1170270945",
"timestamp": "2025-11-12T10:11:04+00:00"
},
"body": {
"deviceStatus": "Free", // Free | Busy
"networkStatus": "Connected", // Connected | Disconnected
"softwareVersion": "1.0.0(188)", // Software version
"businessID": "ff467f02-5b69-45f3-81aa-bffcca55fe8f"
}
}
3.2 Sale
Request body class
| Variable | Type | Required | Description |
|---|---|---|---|
| header.action | enum | Y | Sale |
| referenceID | String | Y | Reference ID: Every time a transaction request is initiated, it is crucial to ensure the uniqueness of this ID. Failure to do so will render any subsequent operations on the transaction invalid. |
| currency | String | Y | Example: HKD / USD / RMB |
| amount | String | Y | Sale amount |
| webhookUrl | String | N | Notify the server of the sale status via this URL |
Example:
{
"version": 2.0,
"header": {
"action": "Sale",
"requestID": "ff467f02-5b69-45f3-81aa-bffcca55fe81",
"clientDeviceSN": "126498561093",
"timestamp": "2025-11-12T10:11:04+00:00"
},
"body": {
"referenceID": "8daf4dc0-6ad6-44b1-8256-a0f1549c0fa6",
"currency": "HKD",
"amount": "10.20",
"webhookUrl": "https://www.baidu.com/transactionID=27908"
}
}
Response body class
| Variable | Type | Required | Description |
|---|---|---|---|
| header.action | enum | Y | Sale |
| status | String | Y | Response status: Success / Failed / Pending |
| referenceID | String | Y | Response reference ID: The reference ID derived from the request Header |
| errorCode | String | Y | |
| errorMessage | String | Y | |
| currency | String | Y | Example: HKD / USD / RMB |
| amount | String | Y | Sale amount |
| paymentMethod | String | Y | Payment method |
| paymentEntryType | String | Y | Payment entry type, Example: contactless |
| rrn | String | Y | Receiver Reference Number |
| brn | String | Y | Bindo Reference Number |
| transactionTime | Datetime | Y | Transaction Time |
| creditCard | Object | N | |
| creditCard.panPrefix6Digits | String | Y | |
| creditCard.panLast4Digits | String | Y | |
| creditCard.panHash | String | Y | |
| creditCard.panToken | String | Y |
Example:
{
"version": 2.0,
"header": {
"action": "Sale",
"responseID": "ff467f02-5b69-45f3-81aa-bffcca55fe81",
"serverDeviceSN": "NEXGO-N96-1170270945",
"timestamp": "2025-11-12T10:11:04+00:00"
},
"body": {
"status": "Success", // Success or Failed or Pending
"referenceID": "8daf4dc0-6ad6-44b1-8256-a0f1549c0fa6",
"errorCode": "", // Error Code
"errorMessage": "", // Error message
"currency": "HKD",
"amount": "10.20",
"paymentMethod": "visa",
"paymentEntryType": "contactless",
"rrn": "3263492852830699521",
"brn": "3263492852495159296",
"transactionTime": "2023-06-30T09:08:52+00:00",
"creditCard": {
"panPrefix6Digits": "555555", // First 6 digits of the credit card number
"panLast4Digits": "1234", // Last 4 digits of the credit card number
"panHash": "xxxxxxx", // SHA512
"panToken": ""
}
}
}
3.3 Pre Auth
Request body class
| Variable | Type | Required | Description |
|---|---|---|---|
| header.action | enum | Y | PreAuth |
| referenceID | String | Y | Reference ID: Every time a transaction request is initiated, it is crucial to ensure the uniqueness of this ID. Failure to do so will render any subsequent operations on the transaction invalid. |
| currency | String | Y | Example: HKD / USD / RMB |
| amount | String | Y | preAuth amount |
| webhookUrl | String | N | Notify the server of the preAuth status via this URL |
Example:
{
"version": 2.0,
"header": {
"action": "PreAuth",
"requestID": "ff467f02-5b69-45f3-81aa-bffcca55fe82",
"clientDeviceSN": "126498561093",
"timestamp": "2025-11-12T10:11:04+00:00"
},
"body": {
"referenceID": "8daf4dc0-6ad6-44b1-8256-a0f1549c0fa1",
"currency": "HKD",
"amount": "10.20",
"webhookUrl": "https://www.baidu.com/transactionID=27908"
}
}
Response body class
| Variable | Type | Required | Description |
|---|---|---|---|
| header.action | enum | Y | PreAuth |
| status | String | Y | Response status: Success / Failed / Pending |
| referenceID | String | Y | Response reference ID: The reference ID derived from the request Header |
| errorCode | String | Y | |
| errorMessage | String | Y | |
| currency | String | Y | Example: HKD / USD / RMB |
| amount | String | Y | preAuth amount |
| paymentMethod | String | Y | Payment method |
| paymentEntryType | String | Y | Payment entry type, Example: contactless |
| rrn | String | Y | Receiver Reference Number |
| brn | String | Y | Bindo Reference Number |
| transactionTime | Datetime | Y | Transaction Time |
| creditCard | Object | N | |
| creditCard.panPrefix6Digits | String | Y | |
| creditCard.panLast4Digits | String | Y | |
| creditCard.panHash | String | Y | |
| creditCard.panToken | String | Y |
Example:
{
"version": 2.0,
"header": {
"action": "PreAuth",
"responseID": "ff467f02-5b69-45f3-81aa-bffcca55fe82",
"serverDeviceSN": "NEXGO-N96-1170270945",
"timestamp": "2025-11-12T10:11:04+00:00"
},
"body": {
"status": "Success", // Success or Failed or Pending
"referenceID": "8daf4dc0-6ad6-44b1-8256-a0f1549c0fa1",
"errorCode": "", // Error Code
"errorMessage": "", // Error message
"currency": "HKD",
"amount": "10.20",
"paymentMethod": "visa",
"paymentEntryType": "contactless",
"rrn": "3263492852830699521",
"brn": "3263492852495159296",
"transactionTime": "2023-06-30T09:08:52+00:00",
"creditCard": {
"panPrefix6Digits": "555555", // First 6 digits of the credit card number
"panLast4Digits": "1234", // Last 4 digits of the credit card number
"panHash": "xxxxxxx", // SHA512
"panToken": ""
}
}
}
3.4 Abort
Request body class
| Variable | Type | Required | Description |
|---|---|---|---|
| header.action | enum | Y | Abort |
Example:
{
"version": 2.0,
"header": {
"action": "Abort",
"requestID": "ff467f02-5b69-45f3-81aa-bffcca55fe83",
"clientDeviceSN": "126498561093",
"timestamp": "2025-11-12T10:11:04+00:00"
}
}
Response body class
| Variable | Type | Required | Description |
|---|---|---|---|
| header.action | enum | Y | Abort |
| status | String | Y | Response status: Success / Failed |
| errorCode | String | Y | |
| errorMessage | String | Y |
Example:
{
"version": 2.0,
"header": {
"action": "Abort",
"responseID": "ff467f02-5b69-45f3-81aa-bffcca55fe83",
"serverDeviceSN": "NEXGO-N96-1170270945",
"timestamp": "2025-11-12T10:11:04+00:00"
},
"body": {
"status": "Success", // Success or Failed or Pending
"errorCode": "", // Error Code
"errorMessage": "" // Error message
}
}
3.5 Void
Request body class
| Variable | Type | Required | Description |
|---|---|---|---|
| header.action | enum | Y | Void |
| referenceID | String | Y | Reference ID: Every time a transaction request is initiated, it is crucial to ensure the uniqueness of this ID. Failure to do so will render any subsequent operations on the transaction invalid. |
| orgReferenceID | String | Y | The reference ID that was carried during the transaction made at that time. |
| webhookUrl | String | N | Notify the server of the void status via this URL |
Example:
{
"version": 2.0,
"header": {
"action": "Void",
"requestID": "ff467f02-5b69-45f3-81aa-bffcca55fe84",
"clientDeviceSN": "126498561093",
"timestamp": "2025-11-12T10:11:04+00:00"
},
"body": {
"referenceID": "8daf4dc1-6ad6-44b3-8256-a0f1549c0fa2",
"orgReferenceID": "8daf4dc0-6ad6-44b1-8256-a0f1549c0fa1",
"webhookUrl": "https://www.baidu.com/transactionID=27908"
}
}
Response body class
| Variable | Type | Required | Description |
|---|---|---|---|
| header.action | enum | Y | Void |
| status | String | Y | Response status: Success / Failed / Pending |
| referenceID | String | Y | Response reference ID: The reference ID derived from the request Header |
| errorCode | String | Y | |
| errorMessage | String | Y |
Example:
{
"version": 2.0,
"header": {
"action": "Void",
"responseID": "ff467f02-5b69-45f3-81aa-bffcca55fe84",
"serverDeviceSN": "NEXGO-N96-1170270945",
"timestamp": "2025-11-12T10:11:04+00:00"
},
"body": {
"status": "Success", // Success or Failed or Pending
"referenceID": "8daf4dc1-6ad6-44b3-8256-a0f1549c0fa2",
"errorCode": "", // Error Code
"errorMessage": "" // Error message
}
}
3.6 Refund
Request body class
| Variable | Type | Required | Description |
|---|---|---|---|
| header.action | enum | Y | Refund |
| referenceID | String | Y | Reference ID: Every time a transaction request is initiated, it is crucial to ensure the uniqueness of this ID. Failure to do so will render any subsequent operations on the transaction invalid. |
| orgReferenceID | String | Y | The reference ID that was carried during the transaction made at that time. |
| currency | String | Y | Example: HKD / USD / RMB |
| amount | String | Y | preAuth amount |
| webhookUrl | String | N | Notify the server of the refund status via this URL |
Example:
{
"version": 2.0,
"header": {
"action": "Refund",
"requestID": "ff467f02-5b69-45f3-81aa-bffcca55fe85",
"clientDeviceSN": "126498561093",
"timestamp": "2025-11-12T10:11:04+00:00"
},
"body": {
"referenceID": "8daf4dc1-6ad6-44b3-8256-a0f1549c0fa2",
"orgReferenceID": "8daf4dc0-6ad6-44b1-8256-a0f1549c0fa1",
"currency": "HKD",
"amount": "10.20",
"webhookUrl": "https://www.baidu.com/transactionID=27908"
}
}
Response body class
| Variable | Type | Required | Description |
|---|---|---|---|
| header.action | enum | Y | Refund |
| status | String | Y | Response status: Success / Failed / Pending |
| referenceID | String | Y | Response reference ID: The reference ID derived from the request Header |
| errorCode | String | Y | |
| errorMessage | String | Y |
Example:
{
"version": 2.0,
"header": {
"action": "Refund",
"responseID": "ff467f02-5b69-45f3-81aa-bffcca55fe85",
"serverDeviceSN": "NEXGO-N96-1170270945",
"timestamp": "2025-11-12T10:11:04+00:00"
},
"body": {
"status": "Success", // Success or Failed or Pending
"referenceID": "8daf4dc1-6ad6-44b3-8256-a0f1549c0fa2",
"errorCode": "", // Error Code
"errorMessage": "" // Error message
}
}