# Payments Foundation v19

## Purpose

Payments are separate from Sales.

Checkout creates a pending-payment Sale.
Payments then settle that Sale.

## Supported tender types

- cash
- card
- external

Multiple payment records may settle one sale, enabling split tender.

## Payment states

- pending
- captured
- failed
- unknown
- reversed

`unknown` is first-class. It represents a payment whose final provider/terminal result
cannot safely be determined yet, commonly because the client lost connectivity after
submitting the transaction.

The POS must not blindly retry with a new idempotency key when a payment is UNKNOWN.

## Sale payment states

- unpaid
- partial
- paid
- unknown
- refunded
- partially_refunded

If any payment is UNKNOWN, the sale remains pending_payment with payment_status=unknown.
When the unknown payment is resolved:
- succeeded -> captured
- failed -> failed

Sale totals are recalculated from captured payment records.

## Idempotency

Collection:
- `idempotency_key` unique per tenant

Resolution:
- `resolution_key` unique per tenant through payment attempts

Retrying the same operation returns the original payment state rather than duplicating
the tender.

## Split tender

Captured payments are summed.

Example:

Sale total: 100
Cash: 60 -> sale payment_status=partial
Card: 40 captured -> sale payment_status=paid, sale.status=completed

## Foundation boundary

v19 records card/external outcomes presented to the application boundary.
Actual terminal integrations, acquiring APIs, polling, webhook reconciliation and
provider-specific adapters come later.

Cash is captured synchronously.

## APIs

- GET  /api/v1/sales/{saleId}/payments
- POST /api/v1/sales/{saleId}/payments
- PATCH /api/v1/payments/{paymentId}/resolve

## Permissions

- payments.view
- payments.collect
- payments.resolve

## Audit

- payments.payment.collected
- payments.payment.resolved

## Next

Inventory movement foundation should consume completed Sale snapshots, not carts.
Payment reversal/refund orchestration will be added with Returns/Refunds.
