Integration via Cloud POS Connector
The Cloud POS Connector lets an ERP or POS backend start payments on a MineSec Pay 7 terminal from anywhere on the internet — no VPN, no local network required. You call a REST API hosted by MineSec; MineSec routes each request to the terminal over a secure MQTT channel and returns the terminal's response.
The request and response body contract is identical to the Local PayServer. The only difference is the transport: instead of calling the terminal directly on port 8000, you call the MineSec Glue API.
Your backend ──HTTPS──► MineSec Glue ──MQTT/TLS──► MineSec Pay 7Prerequisites
Before any call will succeed, the terminal must meet all three conditions:
| Condition | How to set it |
|---|---|
| Activated — bound to a merchant account | TMS Portal or POST /api/v1/activation |
Kiosk mode — operatingMode = kiosk | TMS Terminal Profile |
Cloud connection — connectionMode = cloud | TMS Terminal Profile |
A 403 DEVICE_NOT_ACTIVATED or DEVICE_NOT_CLOUD_ENABLED means one of these
is not set. Merchant mode, Kiosk + Local, and an unactivated terminal are all
intentionally blocked.
You also need:
- An activation code (12 digits, e.g.
052129972106) — the terminal's MineSec routing identity. Customer-side aliases are not accepted. - A Bearer token issued by MineSec for your environment.
Base URL and authentication
All endpoints share the same base URL provided by MineSec for your environment.
Every request requires a Bearer token in the Authorization header:
Authorization: Bearer <token>Replace BASE_URL in all examples below with the URL for your environment
(staging or production), provided by MineSec during onboarding.
Request ID header
Every request must carry a unique x-minesec-request-id header:
x-minesec-request-id: req_<ULID>The Glue service treats a reused request ID as a duplicate (409 DUPLICATE_REQUEST) rather than a second payment. Generate a fresh ID per
call — a ULID (opens in a new tab) (prefixed with req_) works
well and is the format used in the Postman collection.
// Postman pre-request script — generates a fresh ID automatically
function ulid() {
const ENC = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
let t = Date.now(), ts = "";
for (let i = 9; i >= 0; i--) { ts = ENC[t % 32] + ts; t = Math.floor(t / 32); }
let r = "";
for (let i = 0; i < 16; i++) r += ENC[Math.floor(Math.random() * 32)];
return ts + r;
}
pm.variables.set("requestId", "req_" + ulid());Endpoints
All paths follow this pattern:
BASE_URL/api/v1/pos/cloud/devices/{activationCode}/payserver/api/v1/{operation}| Category | Method | Path | Description |
|---|---|---|---|
| Readiness | GET | /status | Is the terminal ready? |
| Readiness | GET | /warmup | Warm up the terminal before the first payment |
| Readiness | GET | /reload | Pick up configuration changes without a restart |
| Readiness | GET | /cancel | Cancel the operation in progress |
| Activation | POST | /activation | Activate the terminal |
| Transactions | POST | /trans | SALE, AUTH, AUTH_COMP, VOID, REFUND |
| Settlement | POST | /settlement | Settle the open batch |
| Lookups | GET | /trans/{transactionId} | Look up a transaction by its ID |
| Lookups | GET | /trans/status/{posMessageId} | Look up by the posMessageId you sent (504 recovery) |
1. Readiness
Status
Checks whether the terminal is up and ready.
GET BASE_URL/api/v1/pos/cloud/devices/{activationCode}/payserver/api/v1/status
Authorization: Bearer <token>
x-minesec-request-id: req_<ULID>Warm up
Prepares the terminal so the first payment of a session is not slowed by initialisation. Call once when the app starts.
GET BASE_URL/api/v1/pos/cloud/devices/{activationCode}/payserver/api/v1/warmup
Authorization: Bearer <token>
x-minesec-request-id: req_<ULID>Reload configuration
Forces the terminal to reload EMV configurations and payment keys. Use after a TMS configuration change without restarting the app.
GET BASE_URL/api/v1/pos/cloud/devices/{activationCode}/payserver/api/v1/reload
Authorization: Bearer <token>
x-minesec-request-id: req_<ULID>Cancel in-progress transaction
Cancels whatever the terminal is currently working on. "Nothing to cancel" is a success — the caller learns the terminal is idle.
GET BASE_URL/api/v1/pos/cloud/devices/{activationCode}/payserver/api/v1/cancel
Authorization: Bearer <token>
x-minesec-request-id: req_<ULID>2. Activation
Activates the terminal with its activation code. Normally done once on first launch, but can be re-sent.
POST BASE_URL/api/v1/pos/cloud/devices/{activationCode}/payserver/api/v1/activation
Authorization: Bearer <token>
x-minesec-request-id: req_<ULID>
Content-Type: application/json
{
"activationCode": "052129972106"
}3. Transactions
All transaction types go to the same endpoint. The name field selects the
operation.
POST BASE_URL/api/v1/pos/cloud/devices/{activationCode}/payserver/api/v1/trans
Authorization: Bearer <token>
x-minesec-request-id: req_<ULID>
Content-Type: application/jsonAlways include posMessageId in transaction requests. It is the only
handle for finding out what happened when a call times out (see
Handling 504s), and re-sending the same value prevents
a duplicate charge.
Card sale. The payment screen appears on the terminal; the cardholder taps their card.
{
"name": "SALE",
"amount": "10.50",
"description": "Order #1234",
"preferredInstrument": "CARD",
"posMessageId": "POS-ORDER-1234",
"autoDismissResult": true
}| Field | Type | Required | Notes |
|---|---|---|---|
name | string | Yes | "SALE" |
amount | string | Yes | Decimal, e.g. "10.50". Currency from terminal config. |
description | string | No | Shown on receipt |
posMessageId | string | Recommended | Your unique reference |
autoDismissResult | boolean | No | true — result screen auto-dismisses |
preferredInstrument | string | No | "CARD", "QR_GUEST_SCAN", "QR_MERCHANT_SCAN" |
Transaction response
A successful transaction returns rspCode: "0" with a data object:
{
"rspCode": "0",
"rspMsg": "Approved",
"data": {
"transactionId": "txn_...",
"tranType": "SALE",
"tranStatus": "Approved",
"approvalCode": "123456",
"paymentMethod": "Visa",
"maskedAccount": "**** **** **** 1234",
"posMessageId": "POS-ORDER-1234",
"totalAmount": 10.50,
"currencyText": "HKD"
}
}4. Settlement
Settles the open batch. Leave batchId empty to settle all open batches.
POST BASE_URL/api/v1/pos/cloud/devices/{activationCode}/payserver/api/v1/settlement
Authorization: Bearer <token>
x-minesec-request-id: req_<ULID>
Content-Type: application/json
{
"posMessageId": "POS-SETTLE-20241029",
"batchId": ""
}5. Lookups
Use these to confirm a transaction outcome, especially after a 504.
By transaction ID
GET BASE_URL/api/v1/pos/cloud/devices/{activationCode}/payserver/api/v1/trans/{transactionId}
Authorization: Bearer <token>
x-minesec-request-id: req_<ULID>By posMessageId (504 recovery)
GET BASE_URL/api/v1/pos/cloud/devices/{activationCode}/payserver/api/v1/trans/status/{posMessageId}
Authorization: Bearer <token>
x-minesec-request-id: req_<ULID>Response envelope
Every endpoint returns a PosResponse JSON envelope:
{ "rspCode": "0", "rspMsg": "Approved", "data": { … } }
{ "rspCode": "-1", "rspMsg": "Declined", "tranId": "txn_…" }| Field | Type | When present |
|---|---|---|
rspCode | string | Always. "0" = success. See Response codes. |
rspMsg | string | Always |
data | object | Success only — TransactionResponse / SettlementResponse / empty object |
tranId | string | Failure that created a transaction |
HTTP error codes
| HTTP status | title | Meaning |
|---|---|---|
400 | INVALID_REQUEST | Activation code not 12 digits, unknown name, or missing required field |
401 | — | Token invalid or expired |
403 | INSUFFICIENT_SCOPE / DEVICE_NOT_FOUND / DEVICE_NOT_ACTIVATED / DEVICE_NOT_CLOUD_ENABLED | Read the title field in the error body |
409 | DUPLICATE_REQUEST | This x-minesec-request-id is already in flight — resolve the first one, do not re-send |
502 | DEVICE_UNAVAILABLE | Terminal unreachable. Nothing was started on the device. |
504 | — | Gateway timeout. Not proof the payment failed — see below. |
The error body follows this shape:
{ "title": "DEVICE_NOT_ACTIVATED", "status": 403, "message": "…" }Handling 504s
A 504 Gateway Timeout means Glue did not receive a response from the
terminal within the allowed window. It is not proof the payment failed —
the terminal may have completed the transaction just as the gateway gave up.
Do not re-send the transaction
Re-sending risks a duplicate charge if the original completed.
Look up by posMessageId
GET BASE_URL/api/v1/pos/cloud/devices/{activationCode}/payserver/api/v1/trans/status/{posMessageId}The terminal returns "TERMINAL_BUSY" while it is still processing,
and the final result once it is done.
Decide based on the result
rspCode: "0"— transaction completed. Use thedataobject.- A declined / error code — transaction did not complete. Safe to retry with a new
posMessageIdand a newx-minesec-request-id. 404— transaction not found. Safe to retry.