# 定金全额支付独立链路实施文档

## 目标

本次改动把“定金全额支付”和“整单全额支付”拆成两个独立结果。定金订单在定金阶段完成支付后，后端同步仍按整单口径提交 `partially_paid`，UI 通过独立 effect 展示“定金全额支付 $xx”的结果弹窗，并关闭 PaymentModal 触发外层刷新。

## 改动内容

### OS 同步结果

`OrderModule.syncPaymentsToOrder` 不再用 deposit-aware target 直接决定整单 `payment_status`。它新增 `getPaymentCompletion`，同时返回：

- `isOrderFullyPaid`：已付净额是否覆盖整单 `expect_amount`。
- `isDepositFullyPaid`：已付净额是否覆盖 `deposit_amount`。
- `paymentStage`：当前支付阶段。
- `depositAmount` / `orderExpectedAmount`：供 UI 展示和调试。

`isFullyPaid` 字段保留，但现在与 `isOrderFullyPaid` 对齐，避免旧 UI 把定金完成误当整单完成。

### BaseSales effect

`BaseSales` 仍然发送 `onPaymentSyncEnd`，并在 `isDepositFullyPaid && !isOrderFullyPaid` 时额外发送 `onDepositPaymentSyncEnd`。PaymentModal 只用新 effect 展示定金完成弹窗，普通 `onPaymentSyncEnd` 会跳过这个场景。

### PaymentModal 展示

PaymentModal 新增 `handleBaseSalesDepositPaymentSyncSuccess`，复用现有支付结果弹窗展示链路，但传入 `resultKind: 'deposit_paid'` 和 `depositAmount`。展示完成后沿用当前支付成功关弹窗路径，让外层拿到刷新信号。

### 现金找零

`CashPaymentModule` 的找零基准改为当前阶段待付金额 `balanceDueAmount`。定金阶段 `balanceDueAmount` 就是定金待付金额，因此：

- 整单 999
- 定金 499.5
- 用户现金输入 500

最终支付项记录 `amount=499.5`，`metadata.actual_paid_amount=500`，`metadata.change_given_amount=0.5`。

### 支付结果文案

支付结果文案从 `PaymentResultToastUtils` 的硬编码 switch 收敛到 `payment-result-flow.ts` 的 `paymentResultPresets`。新增 `deposit_paid` 类型：

- 标题沿用支付成功。
- 副标题为 `定金全额支付 $xx`。
- 有找零时追加 `找零 $xx`。
- 自动关闭策略与全额支付一致。

### toast-close 回调

PaymentResultToast 关闭时不再把上一次支付结果回放给 PaymentModal 外层 callback，只发送 `type: 'toast-close'`，并明确 `shouldRefreshOrder=false`、`shouldCloseCaller=false`。原调用方针对 `toast-close` 的早返回因此不再需要。

## 设计原因

- 定金完成是订单支付流程中的阶段完成，不等价于整单完成，所以后端订单状态必须保持 `partially_paid`。
- 独立 effect 能避免 PaymentModal 在一个 `onPaymentSyncEnd` 中靠复杂条件猜测 UI 行为，也让后续定金阶段继续扩展更清晰。
- 现金找零必须以用户当前支付阶段为基准，否则定金阶段输入整钱不会产生找零。
- 文案配置化后，新增支付结果类型不需要继续修改多处 switch。
