ECR Interface Protocol
1. Encrypt the data of the protocol
1.1 Get 6 letters
When the Wonder terminal enters the pairing page, a 6-digit random uppercase string or the QR code generated by it will be displayed. The client device can obtain this string by scanning a code or manually entering it
Example:
const letters = '260880';
1.2 Generate the AES key
- JavaScript
- Java
- Golang
- C
const letters = "260880";
// AES-256 key
const key = crypto.createHash("sha256").update(letters).digest();
console.log("AES Key:", key.toString("hex"));
// AES Key: d866085b751bf6a9844da9a540d5ac8fba82b5aff408b8aefc6a76e6f61d5bdf
String letters = "260880";
MessageDigest sha = MessageDigest.getInstance("SHA-256");
byte[] keyBytes = sha.digest(letters.getBytes("UTF-8"));
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
letters := "260880"
key := sha256.Sum256([]byte(letters))
const char *letters = "260880";
unsigned char key[32];
SHA256((unsigned char*)letters, strlen(letters), key);
1.3 Encrypt the data of the protocol with AES256
- JavaScript
- Java
- Golang
- C
const crypto = require("crypto");
const r6 = "260880";
console.log("Random:", r6);
// AES-256 key
const key = crypto.createHash("sha256").update(r6).digest();
console.log("AES Key:", key.toString("hex"));
// d866085b751bf6a9844da9a540d5ac8fba82b5aff408b8aefc6a76e6f61d5bdf
// JSON 数据
const jsonStr = JSON.stringify({
header: {
requestID: "ff467f02-5b69-45f3-81aa-bffcca55fe80",
clientDeviceSN: "126498561093",
timestamp: "2025-11-12T10:11:04+00:00",
},
body: {
pairUuid: "8daf4dc0-6ad6-44b1-8556-a0f1549c0fc9",
},
});
const iv = Buffer.alloc(16, 0); // IV 全 0
// Encrypt
const cipher = crypto.createCipheriv("aes-256-cbc", key, iv);
cipher.setAutoPadding(true);
let encrypted = cipher.update(jsonStr, "utf8", "base64");
encrypted += cipher.final("base64");
console.log("Encrypted:", encrypted);
// Encrypted: G6RaFsGPTiVzAYsUTu/gY9vEIGAj+H+QS8BwEc7oeGrzV3q8VQl6BEkdruH+DJIWiVbSaqdLcYl4rvUlDuTkWb2je1ainccR2dO+cKfJhJTr99Q4/y2DFrni/QiFNzzszUP/LfFbJecLNsOSEAT9xTND1FApr3V/mZV8KAJtcFvIesHtFxFyElJ9knGXZ0f5aGAJ08LiZP23CtQQBTusFSk2QPJ3eEkYBukuUdHj7GCQ9N85v0Og0PeCR3dWhIDIY4epiPrRN8ZnS4nyRlJdOkBYJKDyAXnJOTaH5MCPdS9jEn/57NKFX9eWsXu7yWyIs9lNxdfW+YvGuWy3+jpYnLOXJPnXnE7fSQ9U89Dxr0EWW7BwuIrkO2YGCju389lngF9M3i6oYgw74Zkvlr2OlfPGxCy5qmRSXOUZluvPE36OjW4AyFU5vtqsK2RQlmrQSGje9QX7JrKpyZ9L/rBhJ8kNLsRgeaEE95tKu5M+cjrxJFegb+xXyQcBttnQEtTLx03L1Ob1P02Q3jG2PpOimsfantG9gtj6NrlClzTgqqgO1zUKxu/6lU4rucLUy1pCxoztvlpcaldpGjHxVT/6bjwptyGUH0lcDQRIU1lAYeHk/gxEJcQ8vjeyOODkEwJz79cgjNBcxYLEbSnK5uzhGqwntaprZA6zoNRjs923ZSoa6nJ1SQPs7EZvGLSBWA7pJF05psG58WA1FDsrIUeQ5txd4TpAjXPHGX1xebp8K3B4TC1rqBduIgCj4bkGyp3kIt/zR7xwhtkJ5XerLNXebrDSvKXTCzjbb1x0iMtcdC04UDxuLMauJb4Cn+aMrzuR
// Decrypt
const decipher = crypto.createDecipheriv("aes-256-cbc", key, iv);
decipher.setAutoPadding(true);
let decrypted = decipher.update(encrypted, "base64", "utf8");
decrypted += decipher.final("utf8");
console.log("Decrypted:", decrypted);
// Decrypted: {"header":{"requestID":"ff467f02-5b69-45f3-81aa-bffcca55fe80","clientDeviceSN":"126498561093","timestamp":"2025-11-12T10:11:04+00:00"},"body":{"uuid":"8daf4dc0-6ad6-44b1-8556-a0f1549c0fc9"}}
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.security.MessageDigest;
import java.util.Base64;
public class AESExample {
public static void main(String[] args) throws Exception {
String r6 = "260880";
MessageDigest sha = MessageDigest.getInstance("SHA-256");
byte[] keyBytes = sha.digest(r6.getBytes("UTF-8"));
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec iv = new IvParameterSpec(new byte[16]); // IV 全 0
String jsonStr = "{"
+ "\"header\":{\"requestID\":\"ff467f02-5b69-45f3-81aa-bffcca55fe80\",\"clientDeviceSN\":\"126498561093\",\"timestamp\":\"2025-11-12T10:11:04+00:00\"},"
+ "\"body\":{\"uuid\":\"8daf4dc0-6ad6-44b1-8556-a0f1549c0fc9\"}"
+ "}";
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// Encrypt
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
byte[] encryptedBytes = cipher.doFinal(jsonStr.getBytes("UTF-8"));
String encrypted = Base64.getEncoder().encodeToString(encryptedBytes);
System.out.println("Encrypted: " + encrypted);
// Encrypted:
// TviXv23Ee/P/LsVJ3LuhUGyAp/XLALgTVEwnPlbMZ+qy8A/bgNArwOeNOIL808jxLBQ+2wnPZMlDmrwrEefQwqfM46qDhUYMo6i+nBfHFBOQWvZEXSAdEHq2IYLif/eXrf9gCiJ9pHEct00bp+6lm4y/HccBb+iLBkoHaIUz0D3CLPZvl6zkh+TXio4M5IvUPq89gRuhxQYyEV/G0+YG31Vgg/GrZ92eCuzdZFHYI5mvB9VlY4aaDKzEs/GqHVcq
// Decrypt
cipher.init(Cipher.DECRYPT_MODE, key, iv);
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encrypted));
System.out.println("Decrypted: " + new String(decryptedBytes, "UTF-8"));
// Decrypted:
// {"header":{"requestID":"ff467f02-5b69-45f3-81aa-bffcca55fe80","clientDeviceSN":"126498561093","timestamp":"2025-11-12T10:11:04+00:00"},"body":{"uuid":"8daf4dc0-6ad6-44b1-8556-a0f1549c0fc9"}}
}
}
package main
import(
"crypto/aes"
"crypto/cipher"
"crypto/sha256"
"encoding/base64"
"fmt"
)
func pkcs7Pad(data[]byte, blockSize int)[]byte {
pad:= blockSize - len(data) % blockSize
for i := 0; i < pad; i++ {
data = append(data, byte(pad))
}
return data
}
func pkcs7Unpad(data[]byte)[]byte {
if len(data) == 0 {
return data
}
pad:= int(data[len(data) - 1])
return data[: len(data) - pad]
}
func main() {
r6:= "260880"
key:= sha256.Sum256([]byte(r6))
iv:= make([]byte, 16)
jsonStr:= `{"header":{"requestID":"ff467f02-5b69-45f3-81aa-bffcca55fe80","clientDeviceSN":"126498561093","timestamp":"2025-11-12T10:11:04+00:00"},"body":{"uuid":"8daf4dc0-6ad6-44b1-8556-a0f1549c0fc9"}}`
block, _ := aes.NewCipher(key[:])
plain:= pkcs7Pad([]byte(jsonStr), block.BlockSize())
cipherText:= make([]byte, len(plain))
mode:= cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(cipherText, plain)
encB64:= base64.StdEncoding.EncodeToString(cipherText)
fmt.Println("Encrypted:", encB64)
// Encrypted: TviXv23Ee/P/LsVJ3LuhUGyAp/XLALgTVEwnPlbMZ+qy8A/bgNArwOeNOIL808jxLBQ+2wnPZMlDmrwrEefQwqfM46qDhUYMo6i+nBfHFBOQWvZEXSAdEHq2IYLif/eXrf9gCiJ9pHEct00bp+6lm4y/HccBb+iLBkoHaIUz0D3CLPZvl6zkh+TXio4M5IvUPq89gRuhxQYyEV/G0+YG31Vgg/GrZ92eCuzdZFHYI5mvB9VlY4aaDKzEs/GqHVcq
modeDec:= cipher.NewCBCDecrypter(block, iv)
dec:= make([]byte, len(cipherText))
modeDec.CryptBlocks(dec, cipherText)
dec = pkcs7Unpad(dec)
fmt.Println("Decrypted:", string(dec))
// Decrypted: {"header":{"requestID":"ff467f02-5b69-45f3-81aa-bffcca55fe80","clientDeviceSN":"126498561093","timestamp":"2025-11-12T10:11:04+00:00"},"body":{"uuid":"8daf4dc0-6ad6-44b1-8556-a0f1549c0fc9"}}
}
#include < stdio.h >
#include < string.h >
#include < stdlib.h >
#include < openssl / evp.h >
#include < openssl / sha.h >
int main() {
const char * r6 = "260880";
unsigned char key[32];
SHA256((unsigned char *)r6, strlen(r6), key);
unsigned char iv[16] = { 0};
const char * jsonStr = "{\"header\":{\"requestID\":\"ff467f02-5b69-45f3-81aa-bffcca55fe80\",\"clientDeviceSN\":\"126498561093\",\"timestamp\":\"2025-11-12T10:11:04+00:00\"},\"body\":{\"uuid\":\"8daf4dc0-6ad6-44b1-8556-a0f1549c0fc9\"}}";
EVP_CIPHER_CTX * ctx = EVP_CIPHER_CTX_new();
EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv);
int len, cipherLen = 0;
unsigned char ciphertext[1024];
EVP_EncryptUpdate(ctx, ciphertext, & len, (unsigned char *)jsonStr, strlen(jsonStr));
cipherLen = len;
EVP_EncryptFinal_ex(ctx, ciphertext + cipherLen, & len);
cipherLen += len;
// Base64 encode
unsigned char base64Out[2048];
int outLen = EVP_EncodeBlock(base64Out, ciphertext, cipherLen);
printf("Encrypted: %s\n", base64Out);
// Encrypted: TviXv23Ee/P/LsVJ3LuhUGyAp/XLALgTVEwnPlbMZ+qy8A/bgNArwOeNOIL808jxLBQ+2wnPZMlDmrwrEefQwqfM46qDhUYMo6i+nBfHFBOQWvZEXSAdEHq2IYLif/eXrf9gCiJ9pHEct00bp+6lm4y/HccBb+iLBkoHaIUz0D3CLPZvl6zkh+TXio4M5IvUPq89gRuhxQYyEV/G0+YG31Vgg/GrZ92eCuzdZFHYI5mvB9VlY4aaDKzEs/GqHVcq
// Decrypt
unsigned char decoded[1024];
int decodedLen = EVP_DecodeBlock(decoded, base64Out, outLen);
EVP_CIPHER_CTX * dctx = EVP_CIPHER_CTX_new();
EVP_DecryptInit_ex(dctx, EVP_aes_256_cbc(), NULL, key, iv);
unsigned char plain[1024];
int p1, p2;
EVP_DecryptUpdate(dctx, plain, & p1, decoded, decodedLen);
EVP_DecryptFinal_ex(dctx, plain + p1, & p2);
plain[p1 + p2] = '\0';
printf("Decrypted: %s\n", plain);
// Decrypted: {"header":{"requestID":"ff467f02-5b69-45f3-81aa-bffcca55fe80","clientDeviceSN":"126498561093","timestamp":"2025-11-12T10:11:04+00:00"},"body":{"uuid":"8daf4dc0-6ad6-44b1-8556-a0f1549c0fc9"}}
return 0;
}
2. Request and Response Protocol Data Format
2.1 Request data structure
Request JSON
| Variable | Type | Required | Description |
|---|---|---|---|
| version | String | Y | Current communication protocol version number |
| action | enum | Y | Actions: Pair, DeviceInfo, Sale, ... |
| data | String | Y | Encrypted data |
Request "data" structure
| Variable | Type | Required | Description |
|---|---|---|---|
| header | Object | Y | Protocol header |
| body | Object | N | Protocol body |
Request "data.header" structure
| Variable | Type | Required | Description |
|---|---|---|---|
| requestID | UUID | 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 | Y | The timestamp of the current request |
Example:
/*
Encrypt the original data:
{
"header": {
"requestID": "9c07d8d7-2a43-4a29-9c6d-6b8d8f7d44e5",
"clientDeviceSN": "126498561093",
"timestamp": "2025-11-12T10:11:04+00:00"
},
"body": {
"pairUuid": "3f37e6c0-bf6e-4c00-b1fa-b2bd5e1d6a3b"
}
}
*/
{
"version": "2.0",
"action": "Pair",
"data": "WJq3v/ZX/aMMR45WFqfs9BZ2J93EtSTYQh4JOD17ldQkzXi6ohsjxCdl4mpvAOqhFyWPVuEadUubmRzfACUAQpqledyJhOdtQTMlr4KnZXBJw6g3TOFTeKe1I/DqMiEEG0X9BEelUNS+0+FpaoWN1mVkuKEpt8XMGrHyA+M4XbaMwjQ3fMeoR77FULPvM9MCkw6B3QTGONMml51X8pqXsBYTrcpS5SLFVvdL5e+1CcIuVvliyrV3MDd+cwlSjHNIoaLwDEgu9wDNjGTYe1L8Ww=="
}
2.2 Response data structure
Request JSON
| Variable | Type | Required | Description |
|---|---|---|---|
| version | String | Y | Current communication protocol version number |
| action | enum | Y | Actions: DeviceInfo, Sale, PreAuth, Abort, Void, Refund |
| data | String | Y | Encrypted data |
Response "data" structure
| Variable | Type | Required | Description |
|---|---|---|---|
| header | Object | Y | Protocol header |
| body | Object | N | Protocol body |
Response "data.header" structure
| Variable | Type | Required | Description |
|---|---|---|---|
| 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 |
Example:
/*
Encrypt the original data:
{
"header": {
"responseID": "9c07d8d7-2a43-4a29-9c6d-6b8d8f7d44e5",
"serverDeviceSN": "NEXGO-N96-1170270945",
"timestamp": "2025-11-12T10:12:04+00:00"
},
"body": {
"pairUuid": "3f37e6c0-bf6e-4c00-b1fa-b2bd5e1d6a3b",
"ackUuid": "4d366618-49cf-4f93-bd23-25388a573b0c"
}
}
*/
{
"version": 2.0,
"action": "Pair",
"data": "G6RaFsGPTiVzAYsUTu/gY1Igjv+4THb1tZ7vwXWP9f1CYRRrNKKuz4Op7ai9xCqKCdBymnO/YAQTB9egq10DIp/mxQ4pG1dGyL+Erkd91G4xYJd9S7iXNqnCwEn2wOhMIn3sP0H6vgTzoGX9ZOi59pLhuGqYTbHBPvDIkavEIweWWVQjEUdQn7HG0ymqxq4O36giOlh5NldSPwH5LjbnOamEm+Y41jIW/dRexnd7hhKkF/TrZg2lDYKOry9NflNzoMPHiB2/7YgVVmgVfBysW9dqqNRiJXxYLOD6UGoJlQqsICeiidKm6SYL4dkKHYniFEnZ0a5KGdxZs7viSahmiA=="
}
3. Interface Protocol
3.1 Pair
After the customer device acquires the 6-digit pairing code, it uses the "Pair" protocol for pairing. After the Wonder terminal receives a pairing request, it will return a UUID identifier, which will be used by the "Ack" protocol.
Action: Pair
Request "data.body" structure
| Variable | Type | Required | Description |
|---|---|---|---|
| pairUuid | UUID | Y | Pair the uuid identifier |
Example:
/*
Encrypt the original data:
{
"header": {
"requestID": "9c07d8d7-2a43-4a29-9c6d-6b8d8f7d44e5",
"clientDeviceSN": "126498561093",
"timestamp": "2025-11-12T10:11:04+00:00"
},
"body": {
"pairUuid": "3f37e6c0-bf6e-4c00-b1fa-b2bd5e1d6a3b"
}
}
*/
{
"version": "2.0",
"action": "Pair",
"data": "WJq3v/ZX/aMMR45WFqfs9BZ2J93EtSTYQh4JOD17ldQkzXi6ohsjxCdl4mpvAOqhFyWPVuEadUubmRzfACUAQpqledyJhOdtQTMlr4KnZXBJw6g3TOFTeKe1I/DqMiEEG0X9BEelUNS+0+FpaoWN1mVkuKEpt8XMGrHyA+M4XbaMwjQ3fMeoR77FULPvM9MCkw6B3QTGONMml51X8pqXsBYTrcpS5SLFVvdL5e+1CcIuVvliyrV3MDd+cwlSjHNIoaLwDEgu9wDNjGTYe1L8Ww=="
}
Response "data.body" structure
| Variable | Type | Required | Description |
|---|---|---|---|
| pairUuid | UUID | Y | Pair the uuid identifier |
| ackUuid | UUID | Y | Ack the uuid identifier |
Example:
/*
Encrypt the original data:
{
"header": {
"responseID": "9c07d8d7-2a43-4a29-9c6d-6b8d8f7d44e5",
"serverDeviceSN": "NEXGO-N96-1170270945",
"timestamp": "2025-11-12T10:12:04+00:00"
},
"body": {
"pairUuid": "3f37e6c0-bf6e-4c00-b1fa-b2bd5e1d6a3b",
"ackUuid": "4d366618-49cf-4f93-bd23-25388a573b0c"
}
}
*/
{
"version": 2.0,
"action": "Pair",
"data": "G6RaFsGPTiVzAYsUTu/gY1Igjv+4THb1tZ7vwXWP9f1CYRRrNKKuz4Op7ai9xCqKCdBymnO/YAQTB9egq10DIp/mxQ4pG1dGyL+Erkd91G4xYJd9S7iXNqnCwEn2wOhMIn3sP0H6vgTzoGX9ZOi59pLhuGqYTbHBPvDIkavEIweWWVQjEUdQn7HG0ymqxq4O36giOlh5NldSPwH5LjbnOamEm+Y41jIW/dRexnd7hhKkF/TrZg2lDYKOry9NflNzoMPHiB2/7YgVVmgVfBysW9dqqNRiJXxYLOD6UGoJlQqsICeiidKm6SYL4dkKHYniFEnZ0a5KGdxZs7viSahmiA=="
}
3.2 Ack
After the client terminal initiates the pairing, it will receive an "ackUuid" identifier. This protocol needs to carry the "ackUuid" identifier to confirm that the pairing has been successful.
Action: Ack
Request "data.body" structure
| Variable | Type | Required | Description |
|---|---|---|---|
| ackUuid | UUID | Y | The Wonder device will use this UUID to confirm whether the pairing was successful |
Example:
/*
Encrypt the original data:
{
"header": {
"requestID": "73a95cfe-b0f1-42b3-82d1-5a640f61e359",
"clientDeviceSN": "126498561093",
"timestamp": "2025-11-12T10:11:04+00:00"
},
"body": {
"ackUuid": "4d366618-49cf-4f93-bd23-25388a573b0c"
}
}
*/
{
"version": "2.0",
"action": "Ack",
"data": "WJq3v/ZX/aMMR45WFqfs9P9yP8iBOv/+QIHiUObOM9A2N/r4Erh3+K6la2u/I/9AqkSwid8LlMtWMJzhA1nPETvrU2MjYqJbiIZvJAYofdE1ImF4sJnJWojCxCIghSCy/3F0gkheUyv13y0w7ZpUnY2KjqsaxdZ5Rofnw44PBZFberO+UQ96d/x4s6IyAgqb8x2Gxfr4ypg5Jhb1U643mMJantOuY0qg73h7JdmoJLxp0OhowhVe8/hpcX+MwKFcnEMkrcWoE5vZhM7O0Utypw=="
}
Response "data.body" structure
| Variable | Type | Required | Description |
|---|---|---|---|
| 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:
/*
Encrypt the original data:
{
"header": {
"responseID": "73a95cfe-b0f1-42b3-82d1-5a640f61e359",
"serverDeviceSN": "NEXGO-N96-1170270945",
"timestamp": "2025-11-12T10:12:04+00:00"
},
"body": {
"deviceStatus": "Free",
"networkStatus": "Connected",
"softwareVersion": "1.0.0(188)",
"businessID": "ff467f02-5b69-45f3-81aa-bffcca55fe8f"
}
}
*/
{
"version": 2.0,
"action": "Ack",
"data": "G6RaFsGPTiVzAYsUTu/gYy/OriQOOARMWzAfv9FZ3+u7+iwmMj/cxrnRahw2KCO8/q6XLMAK2jV2pK17hmx3vNCwrO7dcoqx8faj+UipeweNnfY9HYZH06Bd5yuu/BYAEOBXkeoJLbfAAgj0KDOHvwEHRryK0zqW6jSQh6nOsqQIr2BhiwxLDR3IZFYVZk4T57Qkzqa/U3xsADyrw0Ou4JXlrWdshE5IAtxrCHnZzj7t3jlmlNRF2DoHbaRCqnYnI/BMNRWUJOnRbAvQqxNWbpZznywFNWR/uazYyU95lNhXJMRWol/9r0dJUa5xf/iQEybihz4cO8tJkalp7oU2w6I3mrnaCHx3qySC/pnC4+rg4AUw065uSxHee/aEJFNE"
}
3.3 Device Info
Action: DeviceInfo
Request "data.body" structure
This request has no body
Example:
/*
Encrypt the original data:
{
"header": {
"requestID": "2c7f32e1-b9e4-4b34-96cc-15c51289f69b",
"clientDeviceSN": "126498561093",
"timestamp": "2025-11-12T10:11:04+00:00"
}
}
*/
{
"version": "2.0",
"action": "DeviceInfo",
"data": "WJq3v/ZX/aMMR45WFqfs9EUXMXYXYYzSxo7SkNX80Y2hL4HhG471eXFw81ikn0cFWH05k1cMA4OcJtxDhh3OCKLA85WwmAHWp3uVBKq0nqTVS+xcPlDIQg8W8taTrfku6d8KWi4HinX80/Yksx5meN1klIjlStY4I8GBA/ElO3t/MprwU33jG68xDXixNalB"
}
Response "data.body" structure
| Variable | Type | Required | Description |
|---|---|---|---|
| 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:
/*
Encrypt the original data:
{
"header": {
"responseID": "2c7f32e1-b9e4-4b34-96cc-15c51289f69b",
"serverDeviceSN": "NEXGO-N96-1170270945",
"timestamp": "2025-11-12T10:12:04+00:00"
},
"body": {
"deviceStatus": "Free",
"networkStatus": "Connected",
"softwareVersion": "1.0.0(188)",
"businessID": "ff467f02-5b69-45f3-81aa-bffcca55fe8f"
}
}
*/
{
"version": "2.0",
"action": "DeviceInfo",
"data": "G6RaFsGPTiVzAYsUTu/gY/wIUdGoYnFoWxIXOwjoBx5bJelgkrMqYDKxicyD0ApBnxqcvr8+kcqCyI2a5oeFm4duqrKwjQdFVW29ggdvuzyMUoqmxJyM3KAkyXTWV1dSbMrDJknalfufODYpuFgV0BfxBdPVvh2EfxlegKza9DtskKZOO/uSLh9GGoMGMHZIC4HBFv6iFSE0Rp4AmhZx012RmkDHfy7lvdvbMaXe690Lytal4srXom0MQ3tpAcJ7FieiFqlS79GopPlAX2o3ZlLKOBsZwhylMvE0SgPbzu5VZXklWqTVBYotFy+GAlzA2LC9Z6MT68hdHI4RkWtlO1HPEnPuUg/VHNxoI0l1y6PWEQaOEb+E+INJmnN/sa4g"
}
3.4 Sale
Action: Sale
Request "data.body" structure
| Variable | Type | Required | Description |
|---|---|---|---|
| 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. |
| customerOrderID | String | N | The order ID of the customer's transaction |
| currency | String | Y | Example: HKD / USD / RMB |
| amount | String | Y | Sale amount |
Example:
/*
Encrypt the original data:
{
"header": {
"requestID": "5debf769-49d7-4c9b-b6f4-8a9d90e1a874",
"clientDeviceSN": "126498561093",
"timestamp": "2025-11-12T10:11:04+00:00"
},
"body": {
"referenceID": "f8b13b22-16ca-4a87-95a4-df4bebf09ee1",
"customerOrderID": "e246c1cc-02f6-4ac5-b7fb-066cb2b2f5b1",
"currency": "HKD",
"amount": "10.20"
}
}
*/
{
"version": "2.0",
"action": "Sale",
"data": "WJq3v/ZX/aMMR45WFqfs9Pf6x7dtrIlEwp8hFIRh5wM2LMFIbUxxGepCCp67NrcI212O5Sk1EMIFmQOI/+/l1X0Bm2tCLXV4VlqvexdPTqViAVWFwnuQMnifC9TXXcxgA0R3WTp3Vgi4yBqsBwDFJMpqdPW/pVBtiRQHwqLzhW6KS/UaNjUbjh20MVI83xJjorUrF1xtdyMerTOrWyd0cysiDWzIMc8kIsdb0Cmj8GBMM7C/S1UVgkY8P4ybJj62cIaxUTF1si7bB5QLjSZ200irnGSMEtGhHpbPLKO1NElG4criVkekYnE4tGT91fbBsJ6CafW7jlrnKfTKVhahoooscXjwsMpZTAYrA2EVHJEE/Ov6RuVNcBTzfUXjx9GgHxJpbI0J5hgqoDXR9QpT7g=="
}
Response "data.body" structure
| Variable | Type | Required | Description |
|---|---|---|---|
| status | String | Y | Response status: Success / Failed / Pending |
| errorCode | String | Y | |
| errorMessage | String | Y | |
| customerOrderID | String | N | The order ID of the customer's transaction |
| currency | String | N | Example: HKD / USD / RMB |
| amount | String | N | Sale amount |
| paymentMethod | String | N | Payment method |
| paymentEntryType | String | N | Payment entry type, Example: contactless |
| rrn | String | N | Receiver Reference Number |
| brn | String | N | Bindo Reference Number |
| transactionStatus | String | N | Transaction Status: Success / Failed / Pending / Voided |
| transactionTime | Datetime | N | Transaction Time |
| creditCard | Object | N | |
| creditCard.panPrefix6Digits | String | Y | First 6 digits of the credit card number |
| creditCard.panLast4Digits | String | Y | Last 4 digits of the credit card number |
| creditCard.panHash | String | Y | SHA512 |
| creditCard.panToken | String | Y |
Example 1:
When the status is Pending
/*
Encrypt the original data:
{
"header": {
"responseID": "5debf769-49d7-4c9b-b6f4-8a9d90e1a874",
"serverDeviceSN": "NEXGO-N96-1170270945",
"timestamp": "2025-11-12T10:12:04+00:00"
},
"body": {
"status": "Pending",
"errorCode": "",
"errorMessage": ""
}
}
*/
{
"version": "2.0",
"action": "Sale",
"data": "G6RaFsGPTiVzAYsUTu/gYxFoWAK/iASzF9SHjxbqRD0MMn2iTlk2EFxkPtQGqwngvLUivaenLxsUaFlYTI675dIeqAiXwTPEbr0wLFLj087eYP8lQnXuPcXd2amDzp27Km6rLhJsn9xP43ZdMLPbaiFpHgoSRzt09G5voOBxpMeeQ9L/03i4BqRMKa9D6qG6/RgZJJJP2epBbjhdmtRdD17Q+kWSgKvEEOCHB+kAXYoDL3eXK5VfjKDY1udlAGJohH8JdyllwIULEi+QyIK1Kw=="
}
Example 2:
When the status is Failed
/*
Encrypt the original data:
{
"header": {
"responseID": "5debf769-49d7-4c9b-b6f4-8a9d90e1a874",
"serverDeviceSN": "NEXGO-N96-1170270945",
"timestamp": "2025-11-12T10:12:04+00:00"
},
"body": {
"status": "Failed",
"errorCode": "5xxxx",
"errorMessage": "The equipment is being traded"
}
}
*/
{
"version": "2.0",
"action": "Sale",
"data": "G6RaFsGPTiVzAYsUTu/gYxFoWAK/iASzF9SHjxbqRD0MMn2iTlk2EFxkPtQGqwngvLUivaenLxsUaFlYTI675dIeqAiXwTPEbr0wLFLj087eYP8lQnXuPcXd2amDzp27Km6rLhJsn9xP43ZdMLPbaiFpHgoSRzt09G5voOBxpMeeQ9L/03i4BqRMKa9D6qG6/RgZJJJP2epBbjhdmtRdD1c3o/Y+4kNACYdO6mEG3Lac/Hg8IRTCMToHPj1o3DdXtA3o3CYsD3tJ2yaNAYZ+gV/PKAZgF40xHQhKUJi/FZyHjKvDwd0CEAWOqXMFIRZB"
}
Example 3:
When the status is Success
/*
Encrypt the original data:
{
"header": {
"responseID": "5debf769-49d7-4c9b-b6f4-8a9d90e1a874",
"serverDeviceSN": "NEXGO-N96-1170270945",
"timestamp": "2025-11-12T10:12:04+00:00"
},
"body": {
"status": "Success",
"errorCode": "",
"errorMessage": "",
"customerOrderID": "e246c1cc-02f6-4ac5-b7fb-066cb2b2f5b1",
"currency": "HKD",
"amount": "10.20",
"paymentMethod": "visa",
"paymentEntryType": "contactless",
"rrn": "3263492852830699521",
"brn": "3263492852495159296",
"transactionStatus": "Success",
"transactionTime": "2023-06-30T09:08:52+00:00",
"creditCard": {
"panPrefix6Digits": "555555",
"panLast4Digits": "1234",
"panHash": "xxxxxxx",
"panToken": ""
}
}
}
*/
{
"version": "2.0",
"action": "Sale",
"data": "G6RaFsGPTiVzAYsUTu/gYxFoWAK/iASzF9SHjxbqRD0MMn2iTlk2EFxkPtQGqwngvLUivaenLxsUaFlYTI675dIeqAiXwTPEbr0wLFLj087eYP8lQnXuPcXd2amDzp27Km6rLhJsn9xP43ZdMLPbaiFpHgoSRzt09G5voOBxpMeeQ9L/03i4BqRMKa9D6qG6/RgZJJJP2epBbjhdmtRdD55kdo+uYoEHqQUkCE82SpewPj0to+rL4ZjLQ33P8x/CaF/0DAA0SHUW2rXoRss+5yfOc/DhByUeCG33O3MmoRdwIRrsHU91R3LTE5SAnO6dMDglCqIT1WfOQNboikIeYF/C7lhiA9IOJjHO4ObHBo1+XT2WS4Zi53/dYrAnKcTa3d+EHW/B8u4IfzdEojAazehwO8ghEZsINwjVdlYZ0zwMMklC4OCarj71b7uTS4vzWZFqunEI4Nj4dI0ocB0wDLZcQs+GtIoqXLVE+vFEFRCd04EeGwcdNiks0fRMqCtrpntv9K7wJfHNH2AeVxqAE1ub8mHj23bWFQB08W7pNc/f8KudM4XMRtYgEg2RiOORw6F4B2GjG60N2Ei5ZlU5cme8CE9S/xoMawWWHw3vdOJL/pCpcg2ESSYDYcrKeaCggBRpYYY3UmG+2hnJzZyWaRuBx2o4Qtu0GFJCU5mnCzTHv+P8ErMAZ4e9Jv/1w3aqTpTQg6jSkNrkzuN89GOSWO+xzVfrW0aFUy7hhMi2k9SyvFRv4NNDA52t8aroDKnozljjW1ELWvByqLsP1FAp/g=="
}
3.5 Abort
Action: Abort
Request "data.body" structure
This request has no body
Example:
/*
Encrypt the original data:
{
"header": {
"requestID": "c5bf3cbe-a146-4f8c-bb8e-209c1e7b8437",
"clientDeviceSN": "126498561093",
"timestamp": "2025-11-12T10:11:04+00:00"
}
}
*/
{
"version": 2.0,
"action": "Abort",
"data": "WJq3v/ZX/aMMR45WFqfs9NfmNINDhS6jMfjiae1x0uuLyfhJ5aQziTk3o4u/gJcw2J+Nzsme4+TivtS//xsb8lN+GbgYDj38GnnQcuI1OuyVAwHS5eq/n7EBNDnz69b2reqf9bprzNq6L5Nnuu/xYV0hi552oKI4lOh4T5fLtDv+ul7gHdbJ8BsOEbQP82zE"
}
Response "data.body" structure
| Variable | Type | Required | Description |
|---|---|---|---|
| status | String | Y | Response status: Success / Failed / Pending |
| errorCode | String | Y | |
| errorMessage | String | Y |
Example:
/*
Encrypt the original data:
{
"header": {
"responseID": "c5bf3cbe-a146-4f8c-bb8e-209c1e7b8437",
"serverDeviceSN": "NEXGO-N96-1170270945",
"timestamp": "2025-11-12T10:12:04+00:00"
},
"body": {
"status": "Success",
"errorCode": "",
"errorMessage": ""
}
}
*/
{
"version": 2.0,
"action": "Abort",
"data": "G6RaFsGPTiVzAYsUTu/gYwWEaHKVOBFIR6cifm5aC/lOPZYHWq8mADm+tCmHlySZnc21ZR7sXvjMJtojcdCnMm1OM9r4gexIaa5zzfv7slCEQERE44uLV07ZvG1rn8QJ/OG5nY2KIlINAz36Y+pSVFXnh35plvhbX1pGANwv0jV2cUpoe9jZpVInYkt3NebKjIPHEMrlM+/weHgd/5BFmWZ6YJ18h5xEzacK1YQH/Z4QHMb0KKR6h8vDg87yc51dMhrbAgz+YOJgKl90JPgGXg=="
}
3.6 Void
Action: Void
Request "data.body" structure
| Variable | Type | Required | Description |
|---|---|---|---|
| orgReferenceID | String | Y | The reference ID that was carried during the transaction made at that time. |
Example:
/*
Encrypt the original data:
{
"header": {
"requestID": "8e2c77fb-ff49-4c49-82f5-ae741cb7d3d9",
"clientDeviceSN": "126498561093",
"timestamp": "2025-11-12T10:11:04+00:00"
},
"body": {
"orgReferenceID": "f8b13b22-16ca-4a87-95a4-df4bebf09ee1"
}
}
*/
{
"version": 2.0,
"action": "Void",
"data": "WJq3v/ZX/aMMR45WFqfs9Md7p/WA11XarluvtqfrO40ET05RPITLV2SXN85mPeMAYDa6g1fpCkQ9aVLejgbHJ93EmugB/POc28afZn1J2SD5FqTOlfKxBFeeL29NNXUeecEu4bvjXjgVScrJVCz+JecdQhXBy9iKj95BT/Vl/7R1xhKT1wAe7/sps4D+xgeTkP6YTIEqVAU5wkd7CS8EG8TYfJsmgwZW1P8yXwda6492lWvlMUIf3LXDGItMGbx+LYcuUcdZkGFRGDIFnoLyCA=="
}
Response "data.body" structure
| Variable | Type | Required | Description |
|---|---|---|---|
| status | String | Y | Response status: Success / Failed / Pending |
| errorCode | String | Y | |
| errorMessage | String | Y |
Example:
/*
Encrypt the original data:
{
"header": {
"responseID": "8e2c77fb-ff49-4c49-82f5-ae741cb7d3d9",
"serverDeviceSN": "NEXGO-N96-1170270945",
"timestamp": "2025-11-12T10:12:04+00:00"
},
"body": {
"status": "Success",
"errorCode": "",
"errorMessage": ""
}
}
*/
{
"version": 2.0,
"action": "Void",
"data": "G6RaFsGPTiVzAYsUTu/gY0kKWwxCZzx9XNP8TZz61iQ5xwi/UXLUU0NsfRm5kwstCH+RyvZo8WQAJ5J1HfNq2zKCeKqvwAn79DEFr0NuH+IECMmsWW9UeUMSlLo3SkNZqRwstqTOkwE0r7fDfD6+KjPlNxW6impHrf54iAWdGFWOYEkmXhb79lG6zPmtsfzW2JBYcnZUxmH/DERUyD6rCke2fH7Q7P6c7Uug+Fl9RuxjxpQnBjBoPReIvkonzyMPzDkqs0cEnZuZu+PQT2d+sA=="
}
3.7 Refund
Action: Refund
Request "data.body" structure
| Variable | Type | Required | Description |
|---|---|---|---|
| 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 |
Example:
/*
Encrypt the original data:
{
"header": {
"requestID": "0f7d24de-76fc-46f8-861b-2d0d31a2dd9e",
"clientDeviceSN": "126498561093",
"timestamp": "2025-11-12T10:11:04+00:00"
},
"body": {
"referenceID": "97cc8c76-65e0-4bd2-9e16-9b9e09f65c42",
"orgReferenceID": "4b02c099-4dc9-4b30-bd2c-27bf3223df6b",
"currency": "HKD",
"amount": "10.20"
}
}
*/
{
"version": 2.0,
"action": "Refund",
"data": "WJq3v/ZX/aMMR45WFqfs9GzNHvhJRs83Ew46fDlVcvpHw1zUFJYPQ9XhptGTILDTRdnX2gFVBpO/eaq+htMhS2565R9J9zgryR1ZBCxWXmA5DdEjoOdyZpQOgfVozTxeRXGvYeOdI+Cv+xeOks/Izfgs83KTHwCI33HLuYZEXYGbqRZiZZ8SqplhqKKKe6ZmN/qqc5mofqUaDrmKNzSF1nrvjF24bBJKpEJdmXB6dsom1jAE6oPB1VUmHIHyt0OG68+oQbFDjfF+kZW6pTgdWOmhVZ7tzx74dcxRsKKLuTKNM/DkeB2KnSA9IK6ZiytqJ35IrWsgMxK/9/4PbwyHmwrJif5YhfCtdD4FpgmhmMIQhnMKQM0wLERJZnyXSVNV"
}
Response "data.body" structure
| Variable | Type | Required | Description |
|---|---|---|---|
| status | String | Y | Response status: Success / Failed / Pending |
| errorCode | String | Y | |
| errorMessage | String | Y |
Example:
/*
Encrypt the original data:
{
"header": {
"responseID": "0f7d24de-76fc-46f8-861b-2d0d31a2dd9e",
"serverDeviceSN": "NEXGO-N96-1170270945",
"timestamp": "2025-11-12T10:12:04+00:00"
},
"body": {
"status": "Success",
"errorCode": "",
"errorMessage": ""
}
}
*/
{
"version": 2.0,
"action": "Refund",
"data": "G6RaFsGPTiVzAYsUTu/gY9HNXCyk05Sa1B0RQLuXZ8ElUp/OsCdaQq70JroARxmq5PtZqtls46kxQKI/cL3McoQ8QD0fkAaFNXEjgkOtKP1h5lDIRcFkxft8HYwC38WjqAunykK8hrIHhdxA7naqcUshYaOoKUFO6zOxrkHBW6YoKdOSLZgqPY7KHNT9EOOyfPaScSWzfR5G84bZ9CfSoe4kBsWnbqvyIbB09qk7LhlGMosoTmZ4DEThkexDC/1DR8atATgMc0D8OeKNp0RrYQ=="
}
3.8 Query Transaction Status
Action: TransactionStatus
Request "data.body" structure
| Variable | Type | Required | Description |
|---|---|---|---|
| targetReferenceID | String | Y | The reference ID that was carried during the transaction made at that time. |
Example:
/*
Encrypt the original data:
{
"header": {
"action": "TransactionStatus",
"requestID": "18fd2b62-6f65-40f2-8b94-88ef32f07a3f",
"clientDeviceSN": "126498561093",
"timestamp": "2025-11-12T10:11:04+00:00"
},
"body": {
"targetReferenceID": "f8b13b22-16ca-4a87-95a4-df4bebf09ee1"
}
}
*/
{
"version": 2.0,
"action": "TransactionStatus",
"data": "c0newW5J8LHyihFFZyXity9fW0sMGLKeANTZJpeGvEhkANMem9OjBRCZ48mSU491oYsB1HUvJx2fLaHRlvCtyiIkHknwitHW7Xb/hgCqQaPn/a+BLCnMJ8Xo5QUsNZ5jFOjwHOSACqsXlvR0EqlWOeVMnhplmWRewit5ePvvJWRUoz8BcXD5O8ulhQ7wYWMtVAryS8uOFgGlXClEW25WJnjiw0T6uqRUqUWZ/J6LEdzSFzpg3hBdh9KC7DWTu7g26mzyaEq7KASIs96LBelehGZnFJG0VxUwPbVP9+LEvcZgUPMEzEFiiGBzlzJ99IMr"
}
Response "data.body" structure
| Variable | Type | Required | Description |
|---|---|---|---|
| status | String | Y | Response status: Success / Failed / Pending |
| errorCode | String | Y | |
| errorMessage | String | Y | |
| ... | Any | Y | It is consistent with the returned information of the current query transaction type |
Example:
/*
Encrypt the original data:
{
"header": {
"responseID": "18fd2b62-6f65-40f2-8b94-88ef32f07a3f",
"serverDeviceSN": "NEXGO-N96-1170270945",
"timestamp": "2025-11-12T10:12:04+00:00"
},
"body": {
"status": "Success",
"errorCode": "",
"errorMessage": "",
"customerOrderID": "e246c1cc-02f6-4ac5-b7fb-066cb2b2f5b1",
"currency": "HKD",
"amount": "10.20",
"paymentMethod": "visa",
"paymentEntryType": "contactless",
"rrn": "3263492852830699521",
"brn": "3263492852495159296",
"transactionStatus": "Success",
"transactionTime": "2023-06-30T09:08:52+00:00",
"creditCard": {
"panPrefix6Digits": "555555",
"panLast4Digits": "1234",
"panHash": "xxxxxxx",
"panToken": ""
}
}
}
*/
{
"version": 2.0,
"action": "TransactionStatus",
"data": "G6RaFsGPTiVzAYsUTu/gY9vEIGAj+H+QS8BwEc7oeGrzV3q8VQl6BEkdruH+DJIWiVbSaqdLcYl4rvUlDuTkWb2je1ainccR2dO+cKfJhJTr99Q4/y2DFrni/QiFNzzszUP/LfFbJecLNsOSEAT9xTND1FApr3V/mZV8KAJtcFvIesHtFxFyElJ9knGXZ0f5aGAJ08LiZP23CtQQBTusFSk2QPJ3eEkYBukuUdHj7GCQ9N85v0Og0PeCR3dWhIDIjWF+uSel+EdLGaKDMVoxY0taNQfedt32VkbRCs8yznlcX3nDgO5gI6SAR78ohnXj8TQT4lzdHz185urs2hV43e7exFkaS9q61fejxD7Zfzp06lBiovYO4ElIsOrUt99xudP9zXJmniEBfj++kDUQLMIeyiwQbEqn5QU1sWCzFMVS6w+PBMADHIwMbosXRRgz0ZwUcVHlWUrTnyBMhEKPEZ/zGYpqujeROw0wh3WnMBbTGy8CEAtOFpxl05djkx38yQWPPm7ODF8Sy02OgjBHNuY+2C85O1ObNsCncBOPIFiDE/sv6fjm0MY95mve+CJ8NimBDhf16gPEngso6Y52l2Z6A5NRaoktoBn1xeFHmc4cSOVFnT91jCtzWhDWhJMnuJBJ2R5Zn2Jr/aFhijMgyzDLX/thzTk5H7EQvr4C+3OeZUoM1Eavka/NrGhJLQ1cTSlUmjlJkKO0S1jlUmq0TwSaIKzRwMdBPNMLqlu7v5kUN6fkUTDsbHf6Y+sbeFSRbn1ArXirjbcvv5FPMhMEng=="
}