> ## Documentation Index
> Fetch the complete documentation index at: https://waffo.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# 单卡购买限额 API

> 如何通过带签名的 transactionlimit create / update / inquiry 接口，限制单张卡对某个产品或产品类目最多可购买的数量：请求字段、两组互斥的限额配置、幂等、生效窗口，以及规则命中时买家会看到什么。

> [!WARNING]
>
> 该能力必须先在你的账户上开通，接口才会响应。如果调用返回权限错误，请联系你的 Waffo 对接人，而不是去排查自己的请求。

如果你销售数字商品、游戏币、活动门票或其他任何转售者喜欢批量购买的东西，你可以限制**单个支付工具最多可购买多少件**——按产品，或按产品类目。Waffo 在支付时执行该限制，超出时拒绝支付。

本页介绍让你从自己的系统中管理这些规则的三个带签名接口。它不涉及金额上限：支付方式的最小/最大订单金额，以及账户级的单笔和单日金额限额，见
[限额、币种与配置类错误](/docs/zh/support/error-codes-and-limits-supplement)。
签名、密钥和请求头的用法与其他所有 API 完全一致——见
[认证与签名](/docs/zh/support/auth-signature-faq)。

## 我到底能限制什么？规则命中后会发生什么？

你为以下二者之一登记一个**每个支付工具的最大数量**：

* 一个特定产品——你提供产品标识和允许购买的最大数量，或者
* 一个产品类目——你提供类目和该类目下所有产品合计允许的最大数量。

此后，你在创建订单时传入商品信息和购买数量。如果该订单会让该支付工具超过登记的最大值，支付会被**拒绝**——买家无法完成支付。订单不会以减少的数量静默成功，也不存在部分接受。

有两个后果值得在设计时考虑：

* 该规则是**硬拒绝**，不是审核队列。如果你想要更柔和的结果（警告、人工审核、按客户的额度），你必须在调用订单创建之前在自己这边实现。
* 被拒绝的尝试是订单上一次正常的风控拒绝。给买家展示中性的提示，不要自动重试同一订单——重试会命中同样的规则。

## 有哪些接口？各自能做什么？

| 接口 | 作用 |
| - | - |
| `POST /api/v1/risk/transactionlimit/create` | 登记一条新规则 |
| `POST /api/v1/risk/transactionlimit/update` | 修改现有规则，或终止它 |
| `POST /api/v1/risk/transactionlimit/inquiry` | 读取一条规则 |

三个接口都是同一主机上的带签名接口，使用与订单创建相同的请求头和签名算法。它们属于 API 密钥的 **payin** 范围，所以仅为提现或付款签发的密钥无法调用它们。

## 创建时要传什么？

| 字段 | 说明 |
| - | - |
| `merchantInfo.merchantId` | 必填。必须与你的 API 密钥所签发的商户 ID 一致——见下一个问题。 |
| `merchantInfo.subMerchantId` | 选填。传入时必须是属于该商户 ID 的子商户。 |
| `merchantRequestId` | 必填。你自己对这条规则的引用，同时也是幂等键。 |
| `goodsInfoLimitConfig.goodsId` + `maxGoodsQuantity` | 产品级配置组。两者一起传。 |
| `goodsInfoLimitConfig.goodsCategory` + `maxCategoryQuantity` | 类目级配置组。两者一起传。 |
| `startTime` | 必填。规则开始生效的时间，ISO 8601（例如 `2026-09-01T03:00:00.000Z`）。 |
| `endTime` | 规则停止生效的时间，格式相同。 |
| `extendInfo` | 选填透传字段，JSON 字符串。 |

两个最大数量的值都必须**大于等于 1**。最大值为零并不是直接屏蔽某个产品的方式——如果你想让某个产品不可购买，就不要上架它。

## 我能在同一个请求里同时设产品限额和类目限额吗？

不能。两组配置在**同一请求内互斥**：

* `goodsId` 和 `maxGoodsQuantity` 必须一起提供。
* `goodsCategory` 和 `maxCategoryQuantity` 必须一起提供。
* 单次 create 调用中只能出现这两组中的**一组**。

如果你既要按产品限额又要按类目限额，创建两条规则。

## 为什么我收到了提到商户 ID 的参数错误？

因为请求体中的 `merchantId` 与你的 API 密钥所签发的商户 ID 不一致。三个接口在做任何其他事情之前都会先断言二者一致，不一致时以 `A0003` **Parameter validation failed** 拒绝调用，详情为 `mid in params is inconsistent with apiKey`。

同样的检查也适用于 `subMerchantId`：如果你传了，它必须存在且属于请求中的商户 ID。否则你会得到 `A0003`，详情为 `subMerchantId is invalid or does not belong to the provided merchantId`。

这是这里最常见的对接错误，而且几乎总是两种情况之一：用了另一个账户的密钥（拿 sandbox 密钥打生产环境，或用了子账户的密钥），或是从复制的示例里遗留了写死的商户 ID。

## 返回什么？`ruleStatus` 是什么意思？

create 和 update 都返回标识符加规则状态：

| 字段 | 说明 |
| - | - |
| `ruleId` | Waffo 为规则分配的标识符。请保存——它是稳定的句柄。 |
| `merchantRequestId` | 原样回传，便于你把响应与请求对应起来。 |
| `ruleStatus` | `ACTIVE`——规则存在，并将在其生效窗口内被评估。`TERMINATED`——规则不再适用。 |

注意 `ACTIVE` 描述的是规则自身的生命周期，而不是它当前是否正在生效：`startTime` 在未来的规则也是 `ACTIVE`，只是尚未开始。

## 如果我的 create 调用超时，幂等是怎么工作的？

`merchantRequestId` 是幂等键。用相同的 `merchantRequestId` 重发完全相同的请求，你会拿回已有的规则而不是产生第二条——这正是超时后你需要的，因为超时时你无法判断规则是否已创建。

由此得出两条规则：

* **为每条意图创建的规则生成一个 `merchantRequestId`**，而不是每次尝试一个。如果你在重试时生成新的，最终会得到两条规则。
* **不要把一个 `merchantRequestId` 复用于另一条不同的规则。** 用不同内容复用幂等键，正是 `A0011` **Idempotent param mismatch error** 所针对的情况。

## 怎么修改或停止一条规则？

调用 `update`，用 `merchantRequestId` **或** `ruleId` 之一来标识规则——二者必须提供其一，`ruleId` 是更安全的选择，因为它没有歧义。

更新时，限额字段是选填的，并遵循与创建时相同的配对规则：传 `goodsId` 时就要传 `maxGoodsQuantity`，传 `goodsCategory` 时就要传 `maxCategoryQuantity`。你也可以调整 `startTime` 和 `endTime`。

要停止一条规则，把 `ruleStatus` 设为 `TERMINATED`。没有删除操作：已终止的规则仍可通过 `inquiry` 读取，这在你需要解释某次历史拒绝时很有用。

## 怎么读取一条规则？

调用 `inquiry`，传 `merchantInfo` 加 `merchantRequestId` **或** `ruleId` 之一。响应按 Waffo 持有的状态重述该规则——标识符、`ruleStatus`、限额配置和生效窗口。

用它做三件事：

* **超时后对账**，再决定是创建还是更新。
* **在售卖前核实实际生效的内容**，而不是信任你自己保存的配置副本。
* 向你的支持团队**解释一次拒绝**，展示当时生效的规则。

## 我的订单创建需要改什么吗？

需要——规则只能作用于你实际传入的信息。仅登记规则本身不起任何作用：在订单创建时你必须传入规则所登记的商品标识和/或商品类目，以及购买数量。不带商品信息的订单无法与数量规则匹配。

两点实操提示：

* **两边使用相同的标识符。** 你登记为 `goodsId` 的值必须与订单创建时传的值逐字一致。大小写不一致或使用了另一套内部 SKU 编码，是规则「不起作用」的常见原因。
* **类目规则需要订单上有类目。** 如果你的目录目前没有类目概念，按产品的规则是成本更低的起点。

商品字段的字段级细节见
[订单创建字段指南](/docs/zh/support/order-create-field-guide)。

## 我能一次调用列出我所有的规则吗？

不能。`inquiry` 是按标识符——`ruleId` 或 `merchantRequestId`——查找，而不是你所登记全部规则的分页列表。所以请自行维护一份已创建规则的登记表，把 `ruleId` 与它所覆盖的产品或类目一起保存。

这份登记表就是你上线前审计的依据：通过 `inquiry` 逐条读回并比对，而不是假定你的配置存储与 Waffo 一致。

## 修改多快生效？

规则按其自身的生效窗口被评估，因此：

* `startTime` 在过去的规则，对下一笔订单即刻生效。
* `startTime` 在未来的规则在此之前不起作用，这是为上新或限时抢购提前布防的干净做法。
* 终止规则会使其停止适用；已经成功的支付不受影响。

一个容易被忽略的后果：**你在布防规则之前创建的订单，如果买家之后才支付，仍会按该规则评估。** 筛查发生在实际尝试支付时，而不是订单创建时，所以你布防限额时停留在收银台页面上的订单，会在支付时被拒绝。只有已经成功的支付不受新规则影响。

不要把规则安排在开售的那一秒精确开始。提前从容布防，并用 `inquiry` 核实读回的内容符合预期。

## 我的规则触发时，买家的支付会收到哪个错误？

一次**风控拒绝**，而不是规则专属的错误码：支付以 `D0001`（风控拒绝）或 `D0002`（风控交易限额）失败，HTTP `406`，与其他任何风控决策完全一样。没有任何错误码表示「商户自己的规则拒绝了这笔」。

由此有两点：

* **自己保留你所限制内容的记录。** 在订单查询和支付通知中，该失败以通用的拒绝类别上报，所以你事后无法把一次拒绝归因到自己的规则。
* **给买家有用的提示。** 由于错误码无法区分你设的限额和其他拒绝，你界面上的措辞必须来自你对规则的了解，而不是来自响应。

两个错误码在各个界面上的表现见[风控拒绝与 3D Secure](/docs/zh/support/risk-declines-and-3ds-faq)。

## 我应该显式处理哪些错误？

以下是值得分支处理的错误码。通用错误族见
[常见错误排查](/docs/zh/support/errors-troubleshooting-guide)。

| 错误码 | 含义 | 该怎么做 |
| - | - | - |
| `A0001` | Invalid API secret key | 密钥错误或已吊销，或环境不对。 |
| `A0002` | Invalid signature | 签名问题——见签名 FAQ。 |
| `A0003` | Parameter validation failed | 详情文本会指出字段。涵盖商户 ID 不一致、子商户检查和字段配对规则。 |
| `A0004` | Permission denied | 你的密钥没有该调用的权限范围，或账户未开通该能力。 |
| `A0011` | Idempotent param mismatch | 你用不同内容复用了 `merchantRequestId`。 |
| `C0001` | System error | 用相同的 `merchantRequestId` 重试；幂等会保护你。 |

在**支付**侧，触发已登记规则的订单会被作为风控拒绝而非参数错误拒绝。对该订单而言把它当作终态处理。

## 规则对子商户适用吗？

规则登记在请求中的商户 ID 上，可选地收窄到一个子商户。如果你运营多个子商户并希望各处使用同样的限额，请按子商户逐个登记规则——限定到某个子商户的规则不覆盖其他子商户，并且接口会校验你指定的子商户确实属于你。

如果你对子商户模型还不熟悉，先看
[多品牌与子商户设置](/docs/zh/support/multi-brand-and-sub-merchant-faq)。

## 这和我已有的金额限额有什么区别？

它们是互不相关的检查，失败方式也不同，这在排查拒绝原因时很重要：

| 检查 | 衡量什么 | 在哪里配置 |
| - | - | - |
| 单卡购买限额（本页） | 单个支付工具购买某产品或类目的**数量** | 由你通过这些接口配置 |
| 支付方式金额范围 | 订单**金额**相对于该支付方式和币种的最小/最大值 | 合同配置 |
| 账户单笔和单日限额 | 订单金额，以及按订单币种的当日累计金额 | 账户配置 |

数量规则挡不住一笔金额巨大的订单，金额限额挡不住一百笔小额订单。如果你的问题是批量囤购，你需要的是数量规则。

## 接下来看哪里？

* [订单创建字段指南](/docs/zh/support/order-create-field-guide)——你在订单创建时传的商品字段。
* [限额、币种与配置类错误](/docs/zh/support/error-codes-and-limits-supplement)
  ——基于金额的上限，以及哪个错误码对应什么。
* [确认支付结果](/docs/zh/support/payment-results-faq)——被拒绝的支付如何上报给你。

仍不清楚某次拒绝是否来自你自己的规则？带上订单 ID 和 `ruleId` [联系支持](mailto:support@waffo.com)。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.