POS Gateway - Views

Location: api/nextango/apps/pos_gateway/views.py Last Updated: 2026-07-09 URL configuration: api/nextango/apps/pos_gateway/urls.py Mount: /pos/ (see api/nextango/urls.py)

Overview

Every POS Gateway endpoint is a plain DRF APIView, not a ViewSet. Views are thin: they validate the request with a serializer, delegate to a gateway service, and return the result. Eight view classes back nine URL patterns (ManagerApprovalView handles both the request and status-poll routes).

Two authentication patterns are in use. TerminalAuthenticationView, HealthCheckView, and AuditEventView are public (AllowAny). Every other view sets authentication_classes = [PosGatewayAuthentication] and does not declare permission_classes, so DRF falls back to DEFAULT_PERMISSION_CLASSES: IsActiveUser in production, AllowAny under DEBUG (nextango/settings/base.py:251-253). In practice this means the JWT check in PosGatewayAuthentication.authenticate() is the gate: an unauthenticated request is rejected there with 401 before permission checks run.


Endpoint Summary

EndpointMethodAuthView
/pos/auth/terminal-login/POSTNoneTerminalAuthenticationView
/pos/auth/terminal-logout/POSTPosGatewayAuthenticationTerminalLogoutView
/pos/transactions/create/POSTPosGatewayAuthenticationTransactionCreateView
/pos/transactions/<transaction_id>/payment/POSTPosGatewayAuthenticationTransactionPaymentView
/pos/approvals/request/POSTPosGatewayAuthenticationManagerApprovalView
/pos/approvals/status/<request_id>/GETPosGatewayAuthenticationManagerApprovalView
/pos/cash-drawer/POSTPosGatewayAuthenticationCashDrawerView
/pos/health/GETNoneHealthCheckView
/pos/audit/auth-event/POSTNoneAuditEventView

TerminalAuthenticationView

POST /pos/auth/terminal-login/, AllowAny, CSRF-exempt.

Authenticates a terminal by employee PIN and creates the session. The request body is validated by TerminalLoginSerializer (employee_id, pin_code, store_id, terminal_id). On success this view creates two sessions: the POS gateway JWT (via PosGatewayAuthenticationClient.authenticate_terminal) and a dashboard WebSession cookie (via web_auth's SessionService.create_session), so the same login also grants browser-based dashboard access for that user.

Returns 200 with {success, token, expires_at, session_id, user, store, employee} on success, 401 with {success: false, ...} on invalid credentials, 400 on invalid request data.

TerminalLogoutView

POST /pos/auth/terminal-logout/, requires PosGatewayAuthentication.

Invalidates the terminal session identified by terminal_id in the validated JWT (request.auth). No request body is needed. Returns 200 with {success: true, message: "Logged out successfully"}, 400 if the session data has no terminal_id, 401 if unauthenticated, 500 if the underlying logout call fails.

TransactionCreateView

POST /pos/transactions/create/, requires PosGatewayAuthentication.

Creates a new sale transaction for the authenticated terminal session. The request is validated by TransactionCreateSerializer; the terminal session is resolved from request.auth['session_id'], not from the request body. Delegates to TransactionGatewayService.create_transaction. Returns 201 on success, 400 on a service-level failure, 401 if the session ID doesn't resolve to a TerminalSession, 500 on an unexpected error.

TransactionPaymentView

POST /pos/transactions/<transaction_id>/payment/, requires PosGatewayAuthentication.

Applies a payment to an existing transaction. transaction_id comes from the URL path. The request is validated by PaymentSerializer (see Serializers for the dual input pattern). Delegates to TransactionGatewayService.process_payment. Returns 202 Accepted on success, not 200, because inventory commitment and the Sanity sync happen after this response is returned. Returns 400 on a service-level failure, 401 on an invalid session, 500 on an unexpected error.

ManagerApprovalView

Handles both approval creation and status polling.

POST /pos/approvals/request/, requires PosGatewayAuthentication. Validated by ManagerApprovalRequestSerializer. Delegates to ManagerApprovalGatewayService.request_approval. Returns 201 on success, 400 on failure, 401 on an invalid session.

GET /pos/approvals/status/<request_id>/, requires PosGatewayAuthentication. Delegates to ManagerApprovalGatewayService.check_approval_status. Returns 200 with {request_id, status, approved_by, approved_at, approval_reason}.

CashDrawerView

POST /pos/cash-drawer/, requires PosGatewayAuthentication.

Request validated by CashDrawerOperationSerializer. Only the open operation is implemented; close, count, and deposit return 501 Not Implemented with {"error": "Operation '<op>' not yet implemented"}. For open, delegates to CashDrawerGatewayService.open_drawer. Returns 200 on success, 400 on failure, 401 if unauthenticated or the session doesn't resolve. This view triggers the hardware drawer pop for the terminal; full register lifecycle management (close with variance, till count) lives in transactions' CashDrawerViewSet, not here.

HealthCheckView

GET /pos/health/, AllowAny.

Reports service availability (database, cache, users_service, transactions_service, inventory_service, each a lightweight importability check rather than a live connectivity probe) and performance metrics. active_sessions is a real count of TerminalSession rows with status=active; cache_hit_rate and avg_response_time are static placeholder values, not measured metrics. Returns 200 with status: "healthy" when every service check passes, "degraded" otherwise, 500 with status: "unhealthy" on an unexpected error.

AuditEventView

POST /pos/audit/auth-event/, AllowAny.

Accepts a client-emitted audit event (event_type, details, terminal_id, timestamp) and writes it to the application log. No session is required, so events can be logged even after a session has expired or failed to validate. Returns 201 with {success: true, message, timestamp}, 500 on an unexpected error. There is no database record of these events beyond the log line.


  • Models: TerminalSession, ManagerApprovalRequest
  • Authentication: JWT-based terminal authentication
  • Services: business logic these views delegate to
  • Serializers: request/response validation
  • Consumers: WebSocket counterpart for real-time updates

Was this page helpful?