> ## 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.

# Payment screen

> Payment screen layout, payment methods, split actions, and completion flow.

## 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.

| Pane       | Contents                                                                       |
| ---------- | ------------------------------------------------------------------------------ |
| **Left**   | Check details, line items, totals, balance due, payment lines, Done button     |
| **Center** | Amount keypad, quick cash ($5/$10/\$20), split evenly, rewards, service charge |
| **Right**  | Payment 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.

| Rule                   | Behavior                                     |
| ---------------------- | -------------------------------------------- |
| `allow_overpay=false`  | Caps entered amount to remaining balance due |
| `allow_change=true`    | Previews and computes change due             |
| `allow_negative=false` | Method 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](/guides/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.

<Steps>
  <Step title="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.
  </Step>

  <Step title="On success">
    Local order is marked `paid`, table is freed, user is redirected to the floor plan (`backHref` preserves `/?area=...` context when present)
  </Step>

  <Step title="On failure">
    Payment screen stays open, user can retry. Table is not freed until submission succeeds.
  </Step>
</Steps>

## 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
```
