Middleware service that routes ATM and POS transactions between terminals and core banking systems, with API-key auth, per-IP rate limiting, and structured logging.
Terminals shouldn't talk to a core banking system directly: every device would need credentials, and one misbehaving terminal could flood the core. This gateway is the layer in between: an ASP.NET Core API that authenticates each terminal, applies rate limits, routes transactions to the core banking system, and logs every request with its timing. The walkthrough below covers every endpoint and the safety net around them.
The service boots as a standard ASP.NET Core API and exposes a test endpoint that monitoring can hit to confirm the gateway and its core banking connection are alive, answering in milliseconds.
A withdrawal or purchase arrives at the fin endpoint with the terminal's API key. The gateway validates the key, identifies the terminal, routes the transaction to the core banking system, and returns the result with the whole round trip logged and timed.
When a transaction has to be undone, the finrev endpoint locates the original transaction and posts the reversal through the same authenticated pipeline, so a failed dispense or a cancelled purchase is squared with the core in one call.
Letter-of-reference transactions between banks flow through dedicated loro and lororev endpoints, giving inter-bank movements the same authentication, logging, and reversal story as everyday card traffic.
Depending on the client, a transaction is either processed locally through SQL Server stored procedures or forwarded to the client's remote core banking endpoint. The routing decision is configuration, so onboarding a new institution does not mean new code.
Requests without a valid X-API-KEY header are rejected with a 401 before they ever reach the core. A fixed-window rate limiter caps each IP at a configurable requests-per-minute and answers overruns with a 429, so a runaway terminal is throttled instead of degrading the system for everyone.
Every response carries a locked-down header set: content sniffing off, framing denied, a default-deny content security policy, HSTS, no-store caching, and a strict referrer policy. The middleware applies them globally, so no endpoint can forget.
Serilog records every request and response with timing, a health endpoint verifies database connectivity for load balancers and monitors, and Swagger UI documents the API in development.
The gateway ships as a container: one docker compose command brings it up listening for terminals, with the health endpoint confirming the service and its core banking connection before traffic hits it.