Access Gateway Outbound Host API
Getting Started
Security & Conventions

Security & Conventions

These rules apply to every endpoint, card and QR.

Transport

  • MineSec calls your adapter over HTTPS only. Plain HTTP is not accepted outside local development.
  • All requests are POST with a JSON body, Content-Type: application/json, UTF-8.
  • Endpoints sit under the base URL you register, for example https://api.your-host.com/api/v1/transactions.

Request headers

POST /api/v1/transactions HTTP/1.1
Host: api.your-host.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer <your-credential>
x-minesec-request-id: 01JKF44HP0VYHTB0SNC0Y6VJQE
x-request-time: 2025-02-07T02:34:33Z
x-signature: HmacSHA256 9f07909a151f50bb3280f955e4be659a4d081275428fa2bae6b9e07510056edb
HeaderMeaning
AuthorizationThe credential you issued to MineSec during onboarding (opaque token or JWT).
x-minesec-request-idID (ULID) of the POS request behind this message. A card reversal and a batch upload carry the same ID as the original transaction.
x-request-timeSigning time, ISO 8601 UTC to the second.
x-signatureHMAC-SHA256 signature of the request. See Message signing.

Authorization, x-request-time and x-signature are sent on signed requests only:

  • QR requests are always signed.
  • Card requests are signed when MineSec has enabled signing for your account. Ask your MineSec integration contact to enable it during onboarding. An unsigned card request carries only x-minesec-request-id, so protect your endpoint by other means, such as allow-listing MineSec's source IPs.

Message signing

Signed requests use a shared HMAC key (hex encoded) agreed during onboarding. The signed string joins four parts with two dots (..):

{HTTP_METHOD}..{PATH}..{x-request-time}..{BODY}

Example:

POST../api/v1/transactions..2025-02-07T02:34:33Z..{"enbrTranId":"tran_01JKF44JBWRNH1AG0GMMKA1M1B","trace":"044883",...}

The header value is HmacSHA256 followed by the lower-case hex digest.

To verify on your side:

  1. Hex-decode the HMAC key to bytes.
  2. Rebuild the string from the method, the full request path as received (base path included, query excluded), the x-request-time header and the raw body bytes as received. Do not re-serialize the JSON.
  3. Compute HMAC-SHA256 and compare it with the header in constant time.
  4. Reject requests whose x-request-time is too far from your clock (we suggest 5 minutes).
Node.js example
import crypto from "node:crypto"
 
function verify(req, rawBody, hmacKeyHex) {
  const time = req.headers["x-request-time"]
  // full path: req.path is relative to the mount point in Express
  const path = req.originalUrl.split("?")[0]
  const data = `${req.method}..${path}..${time}..${rawBody}`
  const expected = crypto.createHmac("sha256", Buffer.from(hmacKeyHex, "hex")).update(data).digest("hex")
  const received = (req.headers["x-signature"] || "").replace(/^HmacSHA256 /, "")
  return received.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected))
}

QR notifies that you send to MineSec are signed the same way with a separate key. See QR notify.

Idempotency

MineSec may resend a request after a network error. Your adapter must not process the same operation twice.

  • Card: do not de-duplicate on x-minesec-request-id alone. A reversal reuses the ID of the transaction it reverses, so it would be mistaken for a repeat. Use these keys instead:

    EndpointIdempotency key
    /transactionsenbrTranId + actionType + isReversal
    /batch-uploadsenbrTranId + batchId
    /settlementsbatchId + isSecond
  • QR: enbrTranId is the idempotency key. A repeated create must return the result of the first one and must not create a second order. A repeated cancellation carries the same enbrActionId.

Responses

Always answer with HTTP 200 and a JSON body, including declines. MineSec reads the outcome from the body only; the HTTP status code is not used to decide it:

  • Card: respCode: "00" means approved or successful. Any other value is a decline or rejection.
  • QR: status decides the outcome. respCode is kept for diagnostics and must be 00 when status is PENDING or SUCCESS.

If no response arrives in time, MineSec starts its recovery flow: a reversal for card, inquiries and a cancellation for QR. A body that cannot be parsed is treated as a decline, with no recovery. See Timeout and reversal and QR Payments.

Formatting

ItemFormat
CurrencyISO 4217 alpha-3, e.g. USD, HKD
AmountDecimal string with the currency's ISO decimal places: "1.00" for USD, "1000" for JPY
TimestampISO 8601 with offset, e.g. 2025-02-11T02:37:57.311Z. Parse the offset; do not assume UTC
CountryISO 3166-1 alpha-2
Extra dataposExtra / extra: flat key-value map of strings. posExtra carries data from the POS and your own keys from the acceptance's extraParams
NullNull fields are omitted from requests

Sensitive card data

  • MineSec never sends clear PIN. PIN blocks are translated inside an HSM under your PIN key before they are sent.
  • With a Track2 key (recommended), Track2 is sent encrypted under your DUKPT key in track2Data. Without one, Track2 is not sent. EMV tags 99 and 57 are never sent in cardData.
  • PIN and Track2 keys are exchanged through a key ceremony with MineSec, never by email or in this portal.

See PIN and Track2 for details.

⚠️

Treat the HMAC key, notify key and your bearer credential as secrets. Store them in a secrets manager, rotate them with MineSec if they are exposed, and never log them.