# 更新日志

## 2026 年 9 月

### 9 月 10 日

**HTML 表单改为提交签名容器**。不再是分散的收款单字段，而是 `data`（JSON 的 base64url）和 `signature`（`data` 字符串的 HMAC-SHA256）。端点由 `invoices/createFromForm` 改为 `invoices/form`。旧表单不再工作，必须重做：见 [HTML 表单签名](./creating-invoices/html-forms/form-signature.md)。

### 9 月 8 日

**Webhook 请求体中的数值字段改为数字**。过去以字符串发送的六个字段现在以数字发送：`project.commissionRate`、`invoice.commissionFiatUSD`、`invoice.amountFiatUSD`、`invoice.amountFiat`、`invoice.calcAmountFiat`、`payment.amount`。字段的集合、名称和顺序没有变化。

注意：末尾的零会被去掉，金额 10.00 送达时是 10。低于 0.0001 的金额以科学计数法送达，例如 1.0e-6——标准 JSON 解析会得到正确的数字，只有手动按字符串解析才会出错。

上线前生成、尚未送达的通知按旧格式到达。在队列清空之前，接收端要同时接受两种格式——这最多需要两天。

### 9 月 6 日

**API 响应中的数值字段改为数字**。涉及 `invoices/list`、`payments/list` 和 `invoices/create`。

| 字段                | 之前             | 之后   |
| ------------------- | ---------------- | ------ |
| `commissionFiatUSD` | `"0.10"`         | `0.1`  |
| `amountFiatUSD`     | `"10.00"`        | `10`   |
| `amountFiat`        | `"1000.00"`      | `1000` |
| `views`             | `"0"`            | `0`    |
| `payment.amount`    | `"10.500000000"` | `10.5` |

**限定到项目的密钥现在在所有方法中生效**。过去部分方法忽略项目。现在它在列表方法中是过滤器，请求其他项目的收款单或钱包会被拒绝并返回 `Restricted project`。无法遵守项目限制的方法对这类密钥关闭。详见《密钥权限范围》一节。

**付款列表现在返回未关联的付款**。过去 `payments/list` 只返回绑定到收款单的付款。现在结果包含所有钱包上的全部付款；未关联的没有 `invoice` 块。它们正是通过 `invoices/bindPayment` 手动关联所需要的付款。

**取消收款单现在区分拒绝原因**。过去收款单不存在和条件不满足都返回同一个 `Invoice not found`。现在 `Invoice not found` 只表示收款单不存在，条件不满足则返回 `Invoice cannot be canceled`。

**格式错误的标识现在会被拒绝**。`invoices/list` 校验 `invoiceId`、`invoiceUid` 和 `projectId`；`payments/list`——`walletId` 和 `invoiceId`。不符合格式的值返回带字段名的 `Parameter is filled in incorrectly`。过去这样的参数会被悄悄丢弃，结果不做过滤地返回。

**时间段边界现在包含整个指定日**。`startDate` 和 `endDate` 按 `00:00:00` 到 `23:59:59` 解释。过去结束日被整天砍掉，查询单日只返回恰好在午夜创建的记录。涉及 `invoices/list`、`payments/list`、`statistics/invoices` 和 `statistics/payments`。

**余额历史增加了项目字段**。`billing/history` 方法中的每笔操作现在都带 `projectId` 字段。账户级操作——充值和赠金——为 `null`。

### 9 月 4 日

**描述和服务数据按原样返回**。`description` 和 `serviceData` 字段过去以编码形式存储，API 响应中引号到达时是 `&quot;`，小于号是 `<`。现在返回的正是商户提交的内容。在 HTML 中渲染时，请在自己一侧转义。

**HTML 表单只接受 POST**。通过地址栏带参数的链接创建收款单不再可行——参数只从请求体读取。此前用链接的话，请换成带 `method="post"` 的表单。

### 9 月 3 日

**Webhook 通知现在带签名**。新增 `X-Timestamp` 和 `X-Signature` 请求头；签名用 Webhook 密钥以 HMAC-SHA256 计算。验证签名就能把真实通知和伪造的区分开。机制和示例见《Webhook 签名验证》一节。

这项变更向后兼容：不加检查，处理程序也照常工作。
