Supported Terminal Models
- Landi A8 / A8S — All payment methods supported
- PAX A920 — QR code payments only
1. POS-KEY
POS-KEY is a secret key used to encrypt transaction data. It is generated via the Haojin App.
Encryption is enabled by default. Merchchants may toggle encryption on/off or regenerate the POS-KEY from the Merchant Portal (MMS). After changes, the POS device must refresh via the Haojin App.
Refresh POS-KEY
Haojin App → My → Settings → POS-Key → Generate
Check POS-KEY
Merchant Portal → Settings → Device Settings → POS Key Mgmt
2. Encryption
- Algorithm: AES
- Key: POS-KEY
- IV:
qfpay202306_hjsh
- Output: Base64 encoded
| Attribute | Mandatory | Type | Description |
|---|
amt | Yes | Double | Transaction amount (e.g. 10.1 = HKD $10.10) |
func_type | Yes | String | Instruction code |
channel | Yes | String | Wallet/payment method |
out_trade_no | No | String | Merchant reference ID |
camera_id | No | Integer | 0 = back camera (default), 1 = front camera |
payment_timeout | No | Integer | Payment timeout (seconds) |
wait_card_timeout | No | Integer | Card input timeout (default 120s) |
3.1 Payment
QR Mode
- MPM / CPM auto-selected based on last usage
CameraTimeout
- Card: time to tap/swipe
- Wallet/QR: time to confirm
- PayMe max timeout: 120 seconds
Scan TypeReturn to Home
0 stay on result screen (default)
1 return to home after transaction
{
"content": {
"amt": 100,
"camera_id": 0,
"channel": "card_payment",
"func_type": 1001,
"moveToBack": 1,
"out_trade_no": "456799999999",
"wait_card_timeout": 120,
"scan_type": "SCAN_PAY"
},
"digest": "76b9186077cdc2bc5d78ae921309811d"
}
3.2 Refund / Void
| Attribute | Mandatory | Type | Description |
|---|
orderId | Yes | String | QFPay transaction ID |
refund_amount | No | String | Partial refund supported |
allow_modify_flag | No | Integer | 0 fixed, 1 allow change |
For Visa, Mastercard, UnionPay Card, and Amex, same-day refunds must be full amount.
{
"content": {
"allow_modify_flag": 1,
"func_type": 1002,
"orderId": "order_id",
"refund_amount": "0.05",
"moveToBack": 1
},
"digest": "9C8E9FB05C7C24B6CA04EBFA1263EF41"
}
3.3 Print Receipt
{
"content": {"orderId": "12345678","func_type": 3001},
"digest":"79fd145311d54d03e4e685d50f15dd7f"
}
3.4 Print Summary
{
"content": {"func_type": 3002},
"digest":"79fd145311d54d03e4e685d50f15dd7f"
}
3.5 Transaction Inquiry
{
"content": {"orderId": "1234567890","func_type": 4001},
"digest":"99CE8BF9C7304AC964522D10F51660B4"
}
3.6 Cancel Request
{
"content": {"func_type": 5001},
"digest": "99CE8BF9C7304AC964522D10F51660B4"
}
4. Signature Generation
// original payload
content={"amt":100,"channel":"card_payment","func_type":1001,"out_trade_no":"456799999999"}
// sort keys alphabetically
format_content={amt=100,channel='card_payment',func_type=1001,out_trade_no='456799999999'}
// generate digest
digest=md5(format_content + pos_key)
If encryption is enabled:
- Encrypt
content using AES
- Generate digest from encrypted payload
5. Field Definitions
func_type
| Value | Description |
|---|
| 1001 | Payment |
| 1002 | Refund |
| 3001 | Print receipt |
| 3002 | Print summary |
| 4001 | Inquiry |
| 5001 | Cancel |
channel (Payment Method)
| Value | Description |
|---|
| card_payment | Credit card |
| wx | WeChat Pay |
| alipay | Alipay |
| payme | PayMe |
| union | UnionPay |
| fps | FPS |
| octopus | Octopus |
| unionpay_card | UnionPay Card |
| amex_card | American Express |
{"respcd":"6000","data":"{...}","respmsg":"OK","resperr":""}
Response Codes
| Code | Meaning |
|---|
| 6000 | Success |
| 6001 | Cancelled |
| 6002 | Error |
| 4003 | Denied |
| 5001 | Decryption failed |
7. Communication Methods
USB
Connect POS to register via USB. Payload must be AES encrypted and parsed according to protocol.
HTTP
- Default port:
9001
- POST JSON payload
- AES encrypted
Endpoints:
| Operation | Path |
|---|
| Trade | /api/pos/trade |
| Refund | /api/pos/cancel |
| Print receipt | /api/pos/print_receipt |
| Print summary | /api/pos/transaction_info |
| Inquiry | /api/pos/query_transaction |
TCP
- Default port:
9002
- Socket communication
- AES encrypted
8. USB Protocol Overview
Start indicator: 0x2f6e
Payload max: 65536 bytes
Recommended: ≤ 1024 bytes
0x2f6e represents the ASCII string “/n” — not a newline.
9. AES Encryption
- AES-128 CBC
- PKCS5 padding
- 16-byte key
- Required for request & response
10. Serial Port Settings
| Setting | Value |
|---|
| Baud rate | 9600 |
| Stop bit | 1 |
| Parity | 0 |
| Data bits | 8 |
| Flow control | Off |
11. USB-Serial Chip Support
| Chip | Supported |
|---|
| PL2303 HXD | Yes |
| CH340 | No |
| FT232 | No |
Chip support applies only to USB communication mode. HTTP and TCP integrations are unaffected.