# 付款关联与金额不一致

本节介绍服务把入账链上交易关联到已开收款单的规则、金额不同时会发生什么，以及商户此时可以做什么。

收款单的状态、期限和状态流转见[收款单生命周期](./invoice-lifecycle.md)。

## 金额匹配规则

创建收款单时，服务把法币金额换算成加密货币，并为收款单锁定这些金额。它们就成了付款的标识：买家在支付表单上看到的是这些金额，服务在链上找的也是金额恰好如此的交易。

**付款金额必须与收款单金额完全一致，没有任何容差**。应付金额对稳定币 USDT 和 USDC 取 2 位小数，对其他加密货币取 8 位小数，入账付款与之精确比对。任何偏差——无论多小的少付或多付——都意味着不会发生自动关联。

**示例**。开出一张 100.00 USD 的收款单，锁定金额为 100.12 USDT。

| 入账付款金额 | 结果                     |
| ------------ | ------------------------ |
| 100.12 USDT  | 收款单自动转为已支付     |
| 100.11 USDT  | 不自动关联               |
| 100.50 USDT  | 不自动关联               |

如果同一地址同时开出多张相同法币金额的收款单，服务会给每张分配略有不同的加密货币金额。唯一性在该钱包上所有待支付收款单范围内检查，因此同一地址可以放心用于自己的多个项目——金额不会冲突。

金额不一致最常见的原因：买家手动取整了金额，或从交易所提现时被扣了网络手续费。请提醒买家严格按支付表单显示的金额转账。

## 金额不一致时会发生什么

服务会记录资金已到达，但不对收款单做任何操作：

* **收款单状态不变**。在支付期限之前保持待支付。检索窗口开放期间，买家仍可用正确的金额关闭它。
* **不发送 Webhook**。发往 Webhook URL 的通知只在收款单转为已支付的那一刻发出。
* **不跟踪部分付款**。服务不识别少付，也不为收款单记欠款余额。
* **付款不累加**。买家少付后又补转差额的话，两笔付款不会相加，都作为独立的未关联付款保留。
* **多付不自动退款**。资金直接进入商户的钱包；把差额退给买家在服务之外处理。

服务中没有“部分支付”或“多付”之类的中间状态。

## 商户如何得知问题

如果项目设置中启用了通知，每笔入账付款商户都会收到邮件和 Telegram 机器人消息——无论它是否关联到了收款单。

由此得到一条简单的诊断规则：收到了入账付款通知，却没有随后的收款单已支付通知，说明付款因金额不一致而未关联，需要人工处理。

这条规则只在检索窗口内有效。只有当至少还有一张收款单在检索中时，服务才监控钱包。如果买家付款时已没有这样的收款单，这笔付款根本不会进入系统——没有通知，也无法手动关联。

也可以用程序查找未关联的付款。`payments/list` 方法返回所有钱包上的付款，未关联到收款单的付款在响应中没有 `invoice` 块。它们就是手动关联的候选：把金额和时间与预期的收款单对比，然后调用 `invoices/bindPayment`。

## 手动关联付款

确定哪笔付款对应哪张收款单时，可以手动关联——在控制台的收款单页面或付款列表中，或通过 API 的 `invoices/bindPayment` 方法。

### 关联条件

只有同时满足所有条件才能关联：

1. **收款单处于待支付或已过期状态**。已取消和已支付的收款单无法关联。
2. **付款尚未关联到其他收款单**。一笔付款只能绑定一张收款单。
3. **付款到达的是该收款单涉及的钱包。**
4. **付款落在可用的付款窗口内**——收款单创建前 24 小时到创建后 24 小时。

这个窗口比收款单的有效期更宽，由此带来两种可能：可以把付款关联到已过期的收款单，也可以把收款单关联到在其创建之前到达的付款。后者在买家主动转账、收款单在资金到达后才开出时很实用。

### 关联之后会发生什么

* **收款单转为已支付**——与自动关联时一样。
* **Webhook 一定会发送**。每次转为已支付都会发出通知，无论关联以哪种方式完成。
* **收款单的 USD 金额按实际付款重算**。`amountFiatUSD` 字段被实际收到的金额覆盖，按关联时的汇率折算。`amountFiat` 中的原始金额不变。
* **服务费按实际金额重算**。按项目费率对实际收到的金额收取。
