MineSec Pay 7
API Reference
Quickstart (Cloud POS Connector)

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 7

Prerequisites

Before any call will succeed, the terminal must meet all three conditions:

ConditionHow to set it
Activated — bound to a merchant accountTMS Portal or POST /api/v1/activation
Kiosk mode — operatingMode = kioskTMS Terminal Profile
Cloud connection — connectionMode = cloudTMS 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}
CategoryMethodPathDescription
ReadinessGET/statusIs the terminal ready?
ReadinessGET/warmupWarm up the terminal before the first payment
ReadinessGET/reloadPick up configuration changes without a restart
ReadinessGET/cancelCancel the operation in progress
ActivationPOST/activationActivate the terminal
TransactionsPOST/transSALE, AUTH, AUTH_COMP, VOID, REFUND
SettlementPOST/settlementSettle the open batch
LookupsGET/trans/{transactionId}Look up a transaction by its ID
LookupsGET/trans/status/{posMessageId}Look up by the posMessageId you sent (504 recovery)

1. Readiness

These operations are non-interactive — they never wait for a cardholder. Run them first to confirm connectivity.

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/json

Always 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
}
FieldTypeRequiredNotes
namestringYes"SALE"
amountstringYesDecimal, e.g. "10.50". Currency from terminal config.
descriptionstringNoShown on receipt
posMessageIdstringRecommendedYour unique reference
autoDismissResultbooleanNotrue — result screen auto-dismisses
preferredInstrumentstringNo"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_…" }
FieldTypeWhen present
rspCodestringAlways. "0" = success. See Response codes.
rspMsgstringAlways
dataobjectSuccess only — TransactionResponse / SettlementResponse / empty object
tranIdstringFailure that created a transaction

HTTP error codes

HTTP statustitleMeaning
400INVALID_REQUESTActivation code not 12 digits, unknown name, or missing required field
401—Token invalid or expired
403INSUFFICIENT_SCOPE / DEVICE_NOT_FOUND / DEVICE_NOT_ACTIVATED / DEVICE_NOT_CLOUD_ENABLEDRead the title field in the error body
409DUPLICATE_REQUESTThis x-minesec-request-id is already in flight — resolve the first one, do not re-send
502DEVICE_UNAVAILABLETerminal 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 the data object.
  • A declined / error code — transaction did not complete. Safe to retry with a new posMessageId and a new x-minesec-request-id.
  • 404 — transaction not found. Safe to retry.