跳到主要内容

静态二维码指南

本指南说明如何通过 API 生成 PIX 静态二维码,以及为什么这是推荐的收款方式。

概览

静态二维码是可重复使用的代码:同一个 BR Code 可以接受多笔付款,来自不同付款 人、在不同时间。金额可以固定,也可以开放(由付款人在银行 App 中输入)。它适用于:

  • 收银场景 —— 柜台上的牌子或贴纸、自助终端、餐桌
  • 非正式的周期性收款 —— 月费、租金、会费
  • 捐赠与小费 —— 开放金额,由付款人决定
  • 固定支付链接 —— 不随订单变化的"在此付款"页面

如果您需要的是一次性收款,带有确定金额、有效期,并与订单一一对账,请使用 动态二维码

请通过 API 生成二维码,不要自行拼装 BR Code

按照 PIX 规范、仅凭您的密钥自行拼装静态 EMV/BR Code 字符串在技术上是可行的。款项 确实会入账,入账通知也会送达——但您将失去把付款与收款单据串联起来的那根线,也没有 查询、没有取消、没有策略。下一节会具体说明失去的是什么。

为什么要通过 API 生成

通过 API 创建的静态二维码天生带有属于您的 identifier,它在我们这里经过校验, 并登记在清算行。该标识符是把整笔付款串起来的那根线:它会出现在 webhook、对账单和 查询结果中。

在外部拼装的 BR Code 没有在任何地方登记这根线。款项会入账,webhook 也会发出,但其中 携带的标识符只取决于您在代码里嵌入了什么——如果确实嵌入了的话;除了钱本身,该二维码 在我们这边不存在任何记录。

通过 API 创建的二维码您自行拼装的 BR Code
qrcode.paid webhook会收到,带有您的 identifier会收到,带有您嵌入的 txid——或者该字段为空
pix.in.completed webhook会收到,带有您的 identifier同上
对账单流水条目带 identifier只有嵌入过 txid 才会带标识符
二维码查询GET .../pix/qr-code/lookup?identifier= 可用根本不存在可查询的二维码
取消DELETE 让该代码停止流通无法通过 API 取消
策略创建时评估 qrCode 板块的规则不评估任何规则
标识符冲突identifier 经过校验并登记txid 完全自由,可能与您某笔收款单据的标识符冲突

标识符成了一场赌博

清算行会把 BR Code 中嵌入的 txid 作为该笔付款的 identifier 回传。如果您在拼装时 放入了自己的 txid,它确实会出现在 webhook 和对账单中,这根线也确实能用。问题在于, 这个值从未经过我们的校验(38 个字符、[A-Za-z0-9._-] 字符集、保留前缀 fee-),在 我们这边也不对应任何二维码。一旦它恰好与同一账户下某个动态二维码的 identifier 相同,这笔付款就会被归到那笔收款单据上,导致该单据显示为已支付。

不过更常见的情形是:静态 BR Code 的 txid 字段填的是 ***——规范中为"无标识符"预留的 占位符。此时付款到达时根本不带任何标识符。两个 webhook 依然会发出,只是 identifier 为空,而唯一的对账方式只能是靠金额、时间和付款人做近似匹配。

我们这边不存在的东西

由于该二维码从未在我们这里创建,也就没有任何记录。按 identifier 查询什么都找不到, DELETE 也没有可取消的对象——想让代码停止流通,只能去把印刷的牌子收回来。qrCode 策略板块的规则同样不会被评估,因为根本没有"创建"这个动作可供评估。而且没有人会核对 嵌入的密钥是否属于该账户、EMV 是否拼装正确:格式有误的代码只会在付款人的银行 App 中 失败,而您要等到客户来投诉才会知道。

没有用于登记外部 BR Code 的端点

API 无法"接管"在外部生成的代码。 POST /v1/accounts/{accountId}/pix/out/qr-code/decode 可以解码 BR Code,但它的用途 是支付他人的二维码,而不是登记您自己的收款二维码。如果二维码已经在外部拼装并 印刷流通,唯一的出路是通过 API 生成新的并予以替换。

选静态还是动态?

静态动态
路由POST .../pix/qr-code/staticPOST .../pix/qr-code/dynamic
金额可选(省略即为开放金额)必填,且大于零
有效期永不过期expirationDate(清算行默认:1 天)
付款次数同一代码可多次一次
限定付款人allowedPayerTaxNumber
过期 webhook不适用qrcode.expired
典型用途柜台、捐赠、月费结账、发票、订单

第一步:创建静态二维码

请求

curl -X POST "https://tenant.api.corpx.com/v1/accounts/{accountId}/pix/qr-code/static" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: {tenant_id}" \
-H "Content-Type: application/json" \
-d '{
"pixKey": "your-pix-key-here",
"value": 49.90,
"identifier": "store-downtown-register-01"
}'

请求体参数

字段类型必填描述
pixKeystring收款账户的 PIX 密钥(必须已注册)
valuenumber固定金额(BRL)。省略或填 0 会创建开放金额二维码,由付款人输入金额
identifierstring建议填写您为该二维码指定的标识符(最多 38 个字符,字符集 [A-Za-z0-9._-],不能以 fee- 开头)。省略时由 API 生成不含连字符的 UUID
messagestring最多 140 个字符的消息。请参见下方提示
message 不会进入静态 BR Code

该字段会被接收并校验,但目前在创建静态二维码时不会转发给清算行——付款人看不 到它,响应中的 message/description 也不会被填充。如果您需要在收款中显示文字, 请使用会转发该消息的动态二维码

选一个有含义的 identifier

该标识符是您的对账键,并会在该二维码的每一笔付款中回传。在静态二维码中,它标识的 是收款点而非某一笔交易:store-downtown-register-01table-14website-donation。这样当三笔付款到账时,您能分清各自来自哪块牌子。

成功响应 (201 Created)

{
"txid": "store-downtown-register-01",
"emv": "00020126580014br.gov.bcb.pix0136d2e1c0a4-8f5b-4c7e-9a1d-6b3f2e8c7a5052040000530398654049.905802BR5912YOUR COMPANY6004Lins62070503***6304A1B2",
"type": "static",
"status": "ACTIVE",
"value": 49.90,
"identifier": "store-downtown-register-01",
"accountId": "{accountId}",
"pixKey": "8026ff12-cb4a-4d19-9638-08bb15d450e2",
"allowChange": false,
"createdAt": "2026-02-10T12:00:00Z"
}
没有 data 信封

响应是扁平对象(顶层)。没有 data 信封,也没有 statusCode/title/message 字段。复制粘贴码在 emv 中,密钥在 pixKey 中。

字段描述
emvPIX 复制粘贴码(EMV 字符串)。请渲染为二维码
identifier您提交的标识符(或由 API 生成的)
txididentifier 相同——静态二维码中两者取值一致
type该端点固定为 static
status创建时为 ACTIVE
value固定金额;开放金额二维码时为 0
allowChange付款人可修改金额时为 true

请注意没有 expiresAt:静态二维码不会过期,在您取消之前一直有效。

重复提交不会去重

API 不会按 identifier 对创建请求去重——该端点没有 Idempotency-Key 处理。在重新 创建一个可能已存在的二维码之前,请先用查询接口确认(第四步)。使用已占用的标识符 重新创建,其结果取决于清算行的响应,可能因冲突而失败。

第二步:展示二维码

用任意二维码库(qrcode.jspython-qrcode 等)根据 emv 字符串生成图片,同时提 供复制粘贴框:

<input type="text" value="00020126580014br.gov.bcb.pix..." readonly />
<button onclick="navigator.clipboard.writeText(this.previousElementSibling.value)">
复制
</button>

由于静态二维码不会过期,该图片可以打印、贴在牌子上或发布到网站——在二维码被取消之 前始终有效。

第三步:通过 Webhook 接收付款

该二维码收到的每一笔付款都会触发两个事件,且两者都带有您的 identifier

  • qrcode.paid —— "我创建的二维码被支付了"(收款对账)
  • pix.in.completed —— "我的账户已入账"(账务、余额、对账单)

您可以两个都订阅,也可以只订阅符合自身流程的那个;它们从不同角度描述同一笔钱。

qrcode.paid

{
"id": "qrcode-paid-E303062942026021014300000005ABCD",
"type": "qrcode.paid",
"occurredAt": "2026-02-10T14:30:12.000000000Z",
"schemaVersion": "1.0",
"environment": "production",
"tenantId": "tenant-yourcompany",
"accountId": "{accountId}",
"data": {
"qrcodeId": "store-downtown-register-01",
"identifier": "store-downtown-register-01",
"accountId": "{accountId}",
"tenantId": "tenant-yourcompany",
"type": "static",
"amount": 49.90,
"endToEnd": "E303062942026021014300000005ABCD",
"transactionId": "b7c1e0f2-3a4d-4e5f-8a9b-0c1d2e3f4a5b",
"status": "SUCCESS",
"receivedAt": "2026-02-10T14:30:12.000000000Z",
"payer": {
"name": "John Smith",
"document": "12345678901",
"bankIspb": "30306294",
"branch": "0020",
"account": "004912314"
},
"payee": {
"name": "YOUR COMPANY LTDA",
"document": "12345678000190"
}
}
}

在静态二维码中,qrcodeIdidentifier 取值相同:即您在创建时选定的标识符。区分 不同付款的是 endToEnd

每一笔付款都是独立事件

同一个二维码被支付五次就会产生五个 qrcode.paid,各自带有自己的 endToEnd。不要把 第一个事件当作"收款已结清"就停止监听——该代码仍然有效。请用 endToEnd 作为您自己 入账记录的去重键。

静态二维码没有 qrcode.expiredqrcode.cancelled:它不会过期,而取消是您发起的 同步操作,其确认就是 DELETE 的 HTTP 响应。

第四步:对账

二维码的 identifier 会出现在您查找资金的两个地方:

在对账单中,每条流水都带 identifier 字段:

curl -X GET "https://tenant.api.corpx.com/v1/accounts/{accountId}/statement?from=2026-02-10&to=2026-02-10" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: {tenant_id}"

在付款查询中,可以直接按标识符检索:

curl -X GET "https://tenant.api.corpx.com/v1/accounts/{accountId}/pix/payments/lookup?identifier=store-downtown-register-01" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: {tenant_id}"

查询二维码状态

curl -X GET "https://tenant.api.corpx.com/v1/accounts/{accountId}/pix/qr-code/lookup?identifier=store-downtown-register-01" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: {tenant_id}"

响应与创建时相同,是同一个扁平对象;若已有付款,还会附带付款字段: paidAmountendToEndIdpaidAtpayer

查询显示的是一笔付款,而非历史记录

在可重复使用的二维码上,查询反映的是清算行已知的最近一笔付款,首笔付款之后 status 就变为 PAID。它不会列出此前的付款。若需完整历史,请使用 qrcode.paid webhook 或按时间段筛选的对账单。

可能的状态:ACTIVEAWAITING-PAYMENTPAIDCANCELLEDEXPIREDUNKNOWN —— 一律为大写。

第五步:取消二维码

静态二维码在被取消之前一直有效。当牌子撤下、收银台停用或活动结束时,请予以取消:

curl -X DELETE "https://tenant.api.corpx.com/v1/accounts/{accountId}/pix/qr-code?identifier=store-downtown-register-01" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: {tenant_id}"

响应 (200 OK):

{
"identifier": "store-downtown-register-01",
"status": "CANCELLED"
}

取消之后,已印刷的 BR Code 便无法再用于收款——扫码者会在银行 App 中收到错误。

策略

创建静态二维码会经过 tenant 或账户策略中的 qrCode 板块。违规时返回 422errorCodepolicy_denied,并附带 violations 列表:

规则rule效果
创建静态码qrCode.canCreateStaticfalse 时拒绝创建
最小金额qrCode.minAmount拒绝金额低于下限的二维码
最大金额qrCode.maxAmount拒绝金额高于上限的二维码

金额规则不适用于开放金额二维码:创建时没有 value 就没有可比较的金额,两条规则 都会被跳过。如果您的金额管控必须始终生效,就不要使用开放金额二维码。详见 策略与规则

所需范围

操作范围
创建静态二维码qrcode.manage
查询与取消qrcode.manageread

仅拥有 qrcode.manage 的凭证可以创建并跟踪二维码,而看不到账户的余额和对账单。参见 认证指南

最佳实践

  1. 始终通过 API 生成 —— 在外部拼装 BR Code 会让您失去对账、查询和取消的能力
  2. 给收款点命名 —— 静态二维码的 identifier 标识的是牌子/收银台/活动,而不是某一笔交易
  3. endToEnd 去重 —— 这是在同一个二维码上区分不同付款的依据
  4. 不要只依赖查询接口 —— 它只显示最近一笔付款;完整历史在 webhook 和对账单中
  5. 及时取消已撤下的二维码 —— 静态二维码不会自行过期
  6. 有策略金额限制时优先用固定金额 —— 开放金额二维码会跳过 minAmount/maxAmount 规则

常见错误

错误格式为 { "errorCode": "...", "message": "..." }

errorCodeHTTP原因解决方案
missing_field400缺少 pixKey请提交该账户已注册的密钥
invalid_identifier400identifier 超过 38 个字符、超出字符集 [A-Za-z0-9._-],或以 fee- 开头调整标识符
invalid_field400message 超过 140 个字符缩短消息
invalid_payload400JSON 格式错误修正请求体
missing_param400查询或取消时 query 中缺少 identifier提供 ?identifier=(别名:txid
not_found404查询时未找到二维码检查 identifieraccountId
policy_denied422qrCode 板块的某条规则拒绝了创建查看响应体中的 violations —— 策略与规则
partner_unavailable503清算行不可用请重试

示例:

{
"errorCode": "missing_field",
"message": "pixKey is required"
}

完整列表见错误

后续步骤