Operations and Upgrades

This page summarizes the operational decisions that matter after the first successful payment. The GitHub release documentation remains the complete reference for storage migration commands, security options, and version-specific upgrade notes.

Runtime Data

The Docker bundle mounts four environment-owned directories outside the image:

Directory Contents
config/ terminal, profile, model, and authentication configuration
data/ SQLite database or JSON transaction and receipt files
logs/ operational logs and optional OPI traces
certs/ TLS certificate and private key files

New installations normally use SQLite with STORAGE=db. Existing deployments can continue with STORAGE=json. The HTTP API behaves the same for both backends.

Transaction Recovery

Treat GET /transactions/:transactionId as the source of truth after an asynchronous request.

Status Meaning Integrator action
pending The request reached the terminal and is still running. Keep polling.
succeeded, authorized, captured, refunded, reversed The financial operation completed. Continue the merchant flow.
declined, failed, aborted A final unsuccessful result is known. Show the result and retry only when operationally safe.
communication_error The request did not reach the terminal. Correct connectivity, then retry with idempotency where appropriate.
unknown The request may have reached the terminal, but the financial outcome cannot be proven. Reconcile before retrying.
reversing A reversal reached the terminal but is not final. Keep polling the original transaction.

Never resubmit an unknown payment without reconciliation; that can create a second financial transaction.

Receipts and Reprint

External receipts are stored as bundles linked to a transaction or terminal service operation. Retrieve them through:

  • GET /transactions/:transactionId/receipts
  • GET /terminals/:terminalAlias/receipts/latest
  • GET /terminals/:terminalAlias/receipts?limit=5

POST /terminals/:terminalAlias/reprint is also a recovery path. The terminal can replay the last receipt through the OPI callback channel even when it has no physical printer. When strong receipt evidence matches a previous unresolved sale, the proxy may reconcile that transaction to succeeded; otherwise it remains unknown and requires manual reconciliation.

Security Baseline

Before exposing the API beyond a trusted setup network:

  • set TLS_MODE=required
  • provide a trusted certificate and private key in certs/
  • set ALLOW_INSECURE_REMOTE_HTTP=false
  • use scoped bearer tokens instead of the bootstrap admin token
  • keep terminal IP addresses accurate because OPI pay-channel responses and callbacks are checked against the configured terminal IP
  • keep the callback port inside the trusted terminal network

Protect normal logs as operational data. Use LOG_LEVEL=extended only while diagnosing a problem and restrict access to the generated OPI traces.

Upgrade Checklist

  1. Stop or drain new terminal operations.
  2. Back up .env, config/, and data/.
  3. Read every release note between the installed and target versions.
  4. Pull the new image or load the matching offline archive.
  5. Preserve merchant-owned auth.json, terminals.json, and terminal-profiles.json.
  6. Compare .env with the new .env.example and review the release-owned terminal model catalog.
  7. Restart the service and verify the reported version through GET /health.
  8. Verify one terminal with /ping, /status, and a controlled payment and receipt flow.

Use the matching Git tag, Docker image tag, release notes, and OpenAPI description together. Do not replace environment-owned configuration with example files during an upgrade.