POS Gateway - Serializers

Location: api/nextango/apps/pos_gateway/serializers.py Last Updated: 2026-07-09

Overview

Every POS Gateway serializer subclasses plain DRF serializers.Serializer, not ModelSerializer. None of them expose a Django model directly; they validate the request or shape the response for a specific endpoint in Views.


Request Serializers

TerminalLoginSerializer validates a terminal login request for POST /pos/auth/terminal-login/: employee_id, pin_code (write-only, must be 4-6 numeric digits), store_id, terminal_id, all required.

TransactionCreateSerializer validates POST /pos/transactions/create/: store_id and employee_id required; line_items (a list of dicts, defaulting to empty), subtotal, tax_amount, total_amount, payment_method, tendered_amount, and change_due all optional.

SaleLineItemSerializer describes the shape of an individual line item dict inside line_items: product_variant_id, sku, quantity (1-999), unit_price, line_discount (default 0.00), total_price.

PaymentSerializer validates POST /pos/transactions/<transaction_id>/payment/ and supports two input patterns. The current pattern is payment_method_id (UUID) plus tendered_amount, with metadata and processor_transaction_id optional; a legacy pattern of method plus amount is also accepted for compatibility, with change_due and payment_data as optional legacy fields. The serializer's validate() requires either payment_method_id + tendered_amount or method + amount; for the legacy cash path it checks tendered_amount >= amount and computes change_due.

InventoryLookupSerializer (sku, barcode) and InventoryReservationSerializer (product_variant_id, sku, quantity, transaction_id) are defined but not wired to any current view. The inventory/lookup/ and inventory/reserve/ endpoints were removed during the gateway refactor; the POS frontend now calls the products API directly for barcode and SKU lookups.

ManagerApprovalRequestSerializer validates POST /pos/approvals/request/: request_type (one of discount, void, return, price_override, cash_drawer, refund), reason (required, max 500 chars), amount and details optional.

CashDrawerOperationSerializer validates POST /pos/cash-drawer/: operation (one of open, close, count, deposit), with amount, reason, and denominations optional. Only open is currently implemented by the view; the other three choices return 501 Not Implemented.


Response Serializers

TerminalSessionResponseSerializer shapes the login response: success required, with token, expires_at, session_id, user, store, employee, and message all optional. user, store, and employee accept null.

TransactionResponseSerializer shapes transaction creation and payment responses: success required, transaction, transaction_id, and error optional.

InventoryResponseSerializer, ReservationResponseSerializer, and ApprovalResponseSerializer follow the same success + optional payload/error pattern for the inventory (unused), reservation (unused), and approval-request flows respectively.

ApprovalStatusSerializer shapes the approval status poll response: request_id and status required, approved_by, approved_at, approval_reason, and error optional.

CashDrawerResponseSerializer shapes the cash drawer response: success required, drawer_operation and error optional.

ErrorResponseSerializer is a generic error shape: success (default False), error required, error_code and details optional. Not currently instantiated by any view; views build error dicts inline instead.

HealthCheckResponseSerializer shapes the health check response: status, timestamp, version, and services required; service_name, service_type, replaces, and performance_metrics optional.


Validation Notes

The PIN validator on TerminalLoginSerializer rejects non-digit input and enforces a 4-6 character length before the request ever reaches the authentication client. The payment serializer's cross-field validate() is the only other custom validation in the module; every other serializer relies on DRF's built-in field validators (min_value/max_value, max_length, choices, decimal precision).

pin_code on TerminalLoginSerializer is write_only, so it never appears in a serialized response even if echoed back accidentally.


  • Models: TerminalSession, ManagerApprovalRequest
  • Views: endpoints that use these serializers
  • Services: business logic that consumes validated data
  • Authentication: JWT-based terminal authentication

Was this page helpful?