Payment Gateway SPI

POST Initiate a sale or pre-authorization payment

POST /api/v1/payment

Operation ID: initiatePayment. Tags: Payment. Security: hmacAuth.

Sends a payment request to the specified terminal via the configured gateway. The proxy forwards the request to the terminal, waits for the cardholder interaction, and returns the authorization result.

When the client uses the WebSocket channel, it opens a connection to WSS /events?transactionId={transactionId} before calling this endpoint to receive real-time terminal events (card inserted, PIN entry, authorization progress). The WebSocket channel is optional — support clients that skip it and rely on the REST response alone.

HMAC signed: Yes (with amount)

Parameters

  • X-HMAC (header, string, required) HMAC-SHA256 hex digest computed over the pipe-delimited message string using the pre-shared secret. See the Security section for the exact message format.
  • X-Nonce (header, string, required) Unique single-use token for replay protection. The server SHOULD reject requests with previously seen nonces. Format: UUID string or equivalent unique token.
  • X-Store-ID (header, string, required) Identifier of the store making the request. Included as a component of the HMAC message to scope signatures to a specific store.
  • X-Register-ID (header, string, required) Identifier of the POS register/device making the request. Included as a component of the HMAC message to scope signatures to a specific register within the store.

Request body (required)

Media type: application/json. Schema: PaymentRequest.

Example

{
  "transactionId": "550e8400-e29b-41d4-a716-446655440000",
  "amount": 49.99,
  "currency": "USD",
  "gateway": "worldpay",
  "terminalId": "T-001",
  "paymentType": "sale",
  "metadata": {
    "orderId": "ORD-12345",
    "cashierId": "C-42"
  },
  "timestamp": "2026-03-12T14:04:06.000Z"
}

Responses

  • 200 Payment processed successfully

    Headers:

    • X-HMAC (string) HMAC-SHA256 signature of the response body for integrity verification

    Media type: application/json. Schema: PaymentResponse.

    Example

    {
      "transactionId": "550e8400-e29b-41d4-a716-446655440000",
      "status": "APPROVED",
      "authCode": "AUTH123456",
      "requestId": "PSP-REF-789",
      "alternateRequestId": "TX-REF-456",
      "gatewayContext": {
        "pspReference": "8535516979155668",
        "merchantAccount": "PSRetailUS"
      },
      "receiptData": {
        "merchantCopy": [
          {
            "key": "pan",
            "display": "Card Number",
            "value": "****1234"
          },
          {
            "key": "authCode",
            "display": "Auth Code",
            "value": "AUTH123456"
          }
        ],
        "customerCopy": [
          {
            "key": "pan",
            "display": "Card Number",
            "value": "****1234"
          }
        ]
      },
      "cardDetails": {
        "maskedPan": "****1234",
        "cardBrand": "VISA",
        "entryMethod": "CHIP",
        "fundingSource": "CREDIT"
      },
      "timestamp": "2026-03-12T14:04:12.206Z"
    }
  • 401

    401 Authentication Failed

    The client certificate was rejected or missing (mTLS failure), or HMAC credentials are invalid.

    Media type: application/json. Schema: ErrorResponse.

    Example

    {
      "error": "AUTHENTICATION_FAILED",
      "message": "Client certificate rejected or missing"
    }
  • 409

    409 HMAC Validation Failed

    The HMAC signature in the X-HMAC header does not match the expected value computed from the request body and headers. This may indicate a replay attack, clock skew, or misconfigured shared secret.

    Media type: application/json. Schema: ErrorResponse.

    Example

    {
      "error": "HMAC_VALIDATION_FAILED",
      "message": "Request signature validation failed"
    }
  • 502

    502 Terminal Offline

    The proxy cannot reach the payment terminal. The terminal may be powered off, disconnected from the network, or unresponsive.

    Media type: application/json. Schema: ErrorResponse.

    Example

    {
      "error": "TERMINAL_OFFLINE",
      "message": "Payment terminal is offline or unreachable"
    }
  • 503

    503 Proxy Unavailable

    The SPI server itself is not available (e.g., starting up, shutting down, or experiencing an internal error).

    Media type: application/json. Schema: ErrorResponse.

    Example

    {
      "error": "SPI_UNAVAILABLE",
      "message": "Payment SPI server is unavailable"
    }
  • 504

    504 Gateway Timeout

    The SPI server did not receive a response from the payment gateway or terminal within the expected time window.

    Media type: application/json. Schema: ErrorResponse.

    Example

    {
      "error": "GATEWAY_TIMEOUT",
      "message": "Payment gateway did not respond in time"
    }