The developer portal listed this API with no reference documentation: catalog was the only domain that had a spec anywhere in the tree. Generated from the backend's own drf-spectacular schema (/classic-models/api/schema/, version 4.7.0), filtered to the operations this domain's gateway actually exposes — derived from the Kong routes and their request-transformer rewrites in Konnect, not from guesswork. Every route resolved to a backend operation; the counts match one for one. Paths and server are the **gateway's**, not the backend's. A portal reader calls https://payments-dev.sttlab.local/payments/v1/..., and the gateway rewrites that onto /classic-models/api/v1/... upstream. Path parameters are renamed to the gateway's capture names where the backend used a different case. Components are pruned to what these paths transitively reference. Note: catalog-api/openapi.yaml does NOT follow this convention — it documents the backend paths and http://localhost:8000 as its server, so its operations cannot be called as written from the portal. Left alone here; worth aligning separately. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
payments-api
Kong routing/policy layer for the payments slice of
classic-models-api (see /Users/stephanetailland/git/classic-models-api),
split out per the DDD decomposition in ../kong-konnect-deployment-strategy.md.
The backend itself stays a single monolith — only Kong does the domain
split. Structure mirrors ../customers-api, not ../catalog-api — see
../STATUS.md section 18 for why (catalog-api's two-route MCP pattern
has a latent bug; customers-api's single-route pattern is the corrected
one to copy going forward).
Two exposure surfaces, both proxying to the real classic-models-api
backend:
- REST (
kong/rest/) — 6 routes overPayment, which uses a composite key (customernumber+checknumber, not a single id likeCustomer/Product) — both URI segments are captured and passed through to the backend's own composite-key URL pattern. - MCP (
kong/mcp/) —list-payments/get-payment(all 5 roles) andcreate-payment(admin only — verified againstPaymentPermission's actual logic inauthentication/permissions.py, not guessed: writes are admin-only in practice,customercan only write their own via the REST API directly, not exposed as an MCP tool). OneKongRoutefor all three MCP HTTP methods, oneai-mcp-proxybinding — see../STATUS.mdsection 18 for why this matters (a second route + binding for the same plugin creates a duplicate-tool-name bug, found and fixed oncustomers-mcp, built correctly here from the start).
| Route | Method | Backend path |
|---|---|---|
/payments/v1/payments/ |
GET, POST | /classic-models/api/v1/payments/ |
/payments/v1/payments/{customernumber}/{checknumber}/ |
GET, PUT, PATCH, DELETE | /classic-models/api/v1/payments/{customernumber}/{checknumber}/ |
/payments-mcp |
GET, POST, DELETE | MCP streamable-http (tools call into the REST routes above) |
Auth
openid-connect on both surfaces, distinct audience each (payments-api
for REST, mcp-payments for MCP) with a real RFC 8693 exchange chain:
MCP → payments-api → classic-models-api, same pattern as
catalog-api/customers-api. IdP is the local Keycloak
(https://keycloak.sttlab.local/realms/classic-models) — see
../STATUS.md sections 15/16. payments-api-audience and
mcp-payments-audience client scopes + payments-api/mcp-payments
resource clients created on the local Keycloak, attached to
kong-token-exchange-broker's default scopes (REST audience) and to
librechat's optional scopes (MCP audience) respectively — no dedicated
protocol mappers on either new client itself, same practice as every
other domain built this session. mcp-payments's OAuth callback added to
librechat's redirectUris, and a payments-mcp server entry added to
LibreChat's librechat.yaml (infra-librechat repo).
Other policies
Per-consumer rate limiting, response caching (GET/HEAD), audit log
(http-log, endpoint still a placeholder — no real log collector in this
lab, same caveat as the other domains).
Structure
Same dev/ + kong/rest/ layout as customers-api. Deploy key
(kong-v2/payments-api/git-deploy-key) is a copy of catalog-api's,
not a freshly generated one — per the user's explicit instruction this
session ("no reason a working key for catalog-api wouldn't work for
customers-api"), the same reused key is used here too rather than minting
yet another one per domain.