Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.laportenard.com/llms.txt

Use this file to discover all available pages before exploring further.

Trigger flow

The Pay button lives in the order summary panel (OrderSummary in order-panel.tsx). Tapping it calls onPay in CartScreen, which opens PaymentScreen. Payment completion is centralized in CartScreen.handlePaymentConfirm.

Layout

Full-screen overlay (fixed inset-0) with a three-pane desktop layout. Panes stack vertically on smaller breakpoints.
PaneContents
LeftCheck details, line items, totals, balance due, payment lines, Done button
CenterAmount keypad, quick cash (5/5/10/$20), split evenly, rewards, service charge
RightPayment methods (loaded dynamically from Odoo)

Payment methods

On open, the screen calls POST /pos-react/api/payments/methods with pos_config_id, is_refund, and amount_total. Methods are sorted by sequence and rendered as buttons.
RuleBehavior
allow_overpay=falseCaps entered amount to remaining balance due
allow_change=truePreviews and computes change due
allow_negative=falseMethod disabled in refund/negative contexts
Payment lines append to a local list for in-screen visibility. On Done, they are translated to Odoo statement_ids entries using method-provided statement_id, account_id, and journal_id.

Credit payments

When a customer with a credit limit is assigned to the order, a credit payment button appears in the tender grid. Tapping it verifies eligibility via the backend before adding a credit line. Credit lines are filtered from statement_ids during order submission — they do not create journal entries. See Credit payments for the full flow and API details.

Split and extra actions

  • Split evenly — Opens SplitEvenlyDialog, sets amount tendered to per-guest amount
  • Rewards — Extension point (currently shows a placeholder toast)
  • Service charge — Extension point (currently shows a placeholder toast)

Completion

Done is enabled only when balance due reaches zero. Payment completion is handled by CartScreen.handlePaymentConfirm, which routes through the hub or direct API.
1

Submit order

When hub sync is active, order finalization goes through transport.finalizeOrder() with a full order snapshot including payment lines. If the hub fails, the system falls back to the direct API (/orders/create or /orders/update) automatically.
2

On success

Local order is marked paid, table is freed, user is redirected to the floor plan (backHref preserves /?area=... context when present)
3

On failure

Payment screen stays open, user can retry. Table is not freed until submission succeeds.

Keypad input

The amount keypad uses a pure function applyKeypadInput(current, key) in types.ts for all input handling. It enforces a single decimal point and a maximum of two decimal places. Keys: digits 0-9, ., C (clear to zero), BACK (delete last character).

Source files

src/features/sales/components/payment/
├── payment-screen.tsx        # Main screen (PaymentScreen)
├── check-summary-pane.tsx    # Left pane
├── amount-keypad.tsx         # Center numpad
├── tender-grid.tsx           # Right payment methods
├── split-evenly-dialog.tsx   # Split evenly modal
├── types.ts                  # PaymentLine, parseCurrencyInput, applyKeypadInput
└── types.test.ts             # Tests for applyKeypadInput and parseCurrencyInput