docs
集成指南

Pix 密钥出金保护机制

概述

在发送密钥出金之前,清算提供商会在 Pix 目录(DICT)中查询该密钥。该提供商限制查询次数,并可能临时封锁反复查询不存在密钥的账户。一旦发生,账户下的所有出金都会受到影响。

为避免这种情况,平台会立即用已知的结果响应,并避免会导致提供商封锁账户的重复查询。共有三种行为,可在 POST /api/pix/cash-out 的响应中看到:

情况API 响应是否创建交易是否发送 Webhook
提供商已告知不存在的密钥立即返回 422否否
提供商正在封锁查询立即返回 429,带 Retry-After否否
提供商速率限制正常返回 201,发送最多延迟 90 秒是是,与往常一致

重复使用已被否定的密钥不会封锁账户或客户:只有该密钥的结果会被保存(15 分钟;若提供商在 2 小时内再次否定则最长 30 分钟),平台返回同样的否定结果而不向提供商查询。其他密钥均正常。

该行为取决于您账户的清算提供商:在部分清算提供商中启用,在其他清算提供商中流程不变。如对您的账户有疑问,请联系您的集成经理。

密钥不存在(422)

触发时机: 针对不存在密钥的首次尝试按您账户的正常流程处理:异步接受时,API 返回 201,随后您会收到说明密钥未找到的失败 Webhook;同步接受时,错误会直接在响应中返回。如果提供商最近已答复该密钥不存在,拒绝结果在您账户的首次尝试时就可能返回。当提供商回复该密钥不存在时,平台会将该结果保存 15 分钟。在此期间,对该密钥的新出金会直接由平台返回同样的否定结果(422 PIX_KEY_NOT_FOUND,details.cached: true),不会向提供商查询。

  • 到期后,如果提供商在 2 小时内再次否定同一密钥,新的记录有效期为 30 分钟。这是上限,不会更长。
  • 由平台应答的尝试不计数,也不会延长时长。只有提供商自身的新否定才会计数。
  • 仅该密钥受影响。账户、客户和所有其他密钥均正常。这不是封锁,也不是惩罚。
  • 存在原因:当同一个不存在的密钥被反复查询时,提供商的 DICT 规则会暂停该账户所有密钥出金约 30 分钟。保存结果可保护整个账户。
  • 新注册的密钥最多可能需要等到该时长结束才会被接受。
  • 不创建交易,不预留余额,也不发送 Webhook。
  • 被拒绝的请求不会占用 externalId,可以重复使用。
{
  "code": "PIX_KEY_NOT_FOUND",
  "message": "Chave Pix não encontrada",
  "details": {
    "retryAfterSeconds": 780,
    "source": "provider-guard",
    "cached": true
  }
}

retryAfterSeconds(以及 Retry-After 头)始终给出实际剩余时间。

处理方式: 与通过 Webhook 到达的"密钥未找到"失败完全一样处理:请用户核对密钥。如果密钥刚注册,请等待 retryAfterSeconds 后重试。

密钥不存在的否定结果可能以两种方式到达。请将两者视为同一情况(密钥不存在):先更正再重新发送。

否定来源到达方式标识
提供商出金失败(Webhook)清算提供商返回的 errorCode 和 errorMessage(errorCode 因清算提供商而异,不应用于业务逻辑)
平台记录响应中的 422code 为 PIX_KEY_NOT_FOUND,details.cached: true 及 details.retryAfterSeconds

时间线示例:

10:00  向密钥 X 出金
       -> 201,随后收到失败 Webhook"密钥未找到"
10:02  再次向密钥 X 出金
       -> 由记录立即返回 422,retryAfterSeconds ~ 780,cached: true
10:15  记录到期
10:16  再次向密钥 X 出金
       -> 重新向提供商查询
       -> 若再次被否定,新记录 30 分钟(至 10:46)

已被接受的出金: 在异步受理的账户中(响应 201,结果通过 Webhook 返回),如果密钥在出金被接受之后、发送给提供商之前被记录为不存在(例如同时发送多笔向同一密钥的出金),该出金会以密钥不存在的错误结束,预留金额被释放,与提供商否定时完全一致。通知通过正常的失败 Webhook 到达。在同步受理的账户中,同样的检查会在调用本身中完成,错误直接在响应中返回。

未提供 details.document 的出金由提供商异步校验:拒绝结果稍后通过 Webhook 到达,通常不说明原因。因此密钥主要通过带证件的出金进入记录;一旦被记录,保存的结果对发往该密钥的任何出金都有效,无论是否带证件。请尽可能传入收款方证件:错误会立即返回并附带原因。

提供商正在封锁查询(429)

触发时机: 提供商临时封锁了密钥查询。只要封锁持续,提供了收款方证件的密钥出金中,大部分会被立即拒绝,不创建交易、不预留余额,也不发送 Webhook。

  • 仅在提供商封锁期间持续。
  • 每 30 秒最多放行一笔出金,用来测试提供商是否恢复。该出金会被正常受理(201),如果封锁仍在持续,会通过 Webhook 以错误结束,预留金额退回。测试成功后,保护机制结束。
  • 该封锁来自提供商(其 DICT 查询规则),不是平台的惩罚。该保护机制正是为了避免它发生。

响应包含 Retry-After 头和 details.retryAfterSeconds(60)。

HTTP/1.1 429 Too Many Requests
Retry-After: 60
Content-Type: application/json
{
  "code": "TOO_MANY_PIX_KEYS_NOT_FOUND",
  "message": "Muitas tentativas com chaves Pix inexistentes. Saque por chave bloqueado temporariamente; tente novamente em instantes.",
  "details": {
    "retryAfterSeconds": 60,
    "source": "provider-guard"
  }
}

处理方式: 等待 Retry-After 指定的时间后重试,若仍被拒绝请使用退避策略。没有创建或预留任何内容。

10:00  提供商封锁密钥查询
10:00  带证件的密钥出金 -> 立即 429,Retry-After: 60
10:00:30  放行一笔出金作为测试 -> 201,若提供商仍封锁,则返回失败 Webhook
10:01  再次尝试 -> 429(仍被封锁)
10:03  提供商放开;平台自动检测到
10:03  再次尝试 -> 201,正常流程

提供商速率限制(发送变慢)

触发时机: 查询量接近提供商的限制。

API 的响应: 出金被正常接受(201),发送给提供商可能最多延迟 90 秒。结果仍通过 Webhook 送达。该等待仅适用于已提供收款方证件的出金,且仅限异步接受的账户;未带证件的出金不会被延迟。

处理方式: 无需任何操作。请勿因延迟而重复发送出金,请先查询其状态(参见状态监控)。

10:00:00  出金被接受 -> 201 (PENDING)
10:01:20  发送给提供商(最多延迟 90 秒)
10:01:23  Webhook 返回结果

对集成方的变化

之前现在
重复使用不存在的密钥每次尝试都返回 201 并收到失败 Webhook密钥记录有效期间立即 422,无交易,无 Webhook
提供商正在封锁查询201,数分钟后收到失败 Webhook立即 429,无交易,无 Webhook,几乎所有出金如此。每 30 秒放行一笔出金作为测试,可能通过 Webhook 失败
速率限制201 和 Webhook201 和 Webhook,发送最多延迟 90 秒

您必须在请求响应中直接处理同步拒绝(422 和 429)。对于 422 和 429 拒绝,不会发送任何 Webhook,请勿等待。封锁期间收到的 201 是一笔真实出金(提供商测试),按正常流程处理,包括 Webhook。

最佳实践

  • 将带 cached: true 的 PIX_KEY_NOT_FOUND 与通过 Webhook 到达的"密钥未找到"失败完全一样处理:请用户核对密钥。
  • 收到 PIX_KEY_NOT_FOUND 时,请先更正密钥再重新发送。不要对同一密钥自动重试,并遵守 retryAfterSeconds。
  • 不要循环重复同一个无效密钥:在时长结束前,响应都不会变。
  • 遵守 Retry-After 和 details.retryAfterSeconds,若仍被拒绝请使用退避策略。
  • 只要知道收款方证件,就传入 details.document:错误会立即返回,而不是数分钟后才通过 Webhook 到达。
  • 未确认状态前不要重复发送同一笔出金。幂等性基于 externalId,参见 PIX Cash-Out。

常见问题

本页目录