跳到主要内容

动态 QR Code 指南

本指南说明如何使用动态 QR Code 生成 PIX 收款。

概述

动态 QR Code 允许您创建具有指定金额、过期时间和付款人信息的唯一收款。适用于以下场景:

  • 电子商务 - 订单付款
  • 账单 - 发票和账单
  • 服务 - 服务费用支付

如果需要可重复使用、可接受多笔付款且不会过期的代码——柜台上的牌子、捐赠、月费 ——请参见静态二维码指南

集成流程

┌─────────────┐      ┌─────────────┐      ┌─────────────┐
│ Create │ │ Customer │ │ Webhook │
│ Charge │ ───► │ Pays QR │ ───► │ Received │
└─────────────┘ └─────────────┘ └─────────────┘
│ │
▼ ▼
Returns EMV Confirms
and payload Payment

第一步:创建收款(动态 QR Code)

请求

curl -X POST "https://tenant.api.corpx.com/v1/accounts/{accountId}/pix/qr-code/dynamic" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: {tenant_id}" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-12345" \
-d '{
"pixKey": "your-pix-key-here",
"value": 150.75,
"expirationDate": "2026-02-10T15:30:00Z",
"identifier": "order-12345",
"message": "Payment for order #12345"
}'

请求体参数

字段类型必填描述
pixKeystring收款账户的 PIX 密钥(必须已注册)
valuenumber收款金额(BRL),必须大于零。最多 2 位小数(例如 150.75)
expirationDatedatetime推荐过期日期/时间(RFC3339 格式,例如 2026-02-10T15:30:00Z)。未提供时采用清算行默认值(MT:1 天)
identifierstring推荐唯一的收款标识符(最多 38 个字符,字符集 [A-Za-z0-9._-])。若省略,API 会生成一个不含连字符的 UUID
messagestring向付款人显示的消息(最多 140 个字符)
allowedPayerTaxNumberstring授权付款的特定 CPF/CNPJ

重要请求头

请求头描述
Idempotency-Key唯一标识符,用于防止重复创建收款

成功响应 (201 Created)

{
"txid": "88a38a908a92441a98dac228ee1d9507",
"emv": "00020101021226790014br.gov.bcb.pix2557brcode.starkinfra.com/v2/88a38a908a92441a98dac228ee1d95075204000053039865802BR5912iDez Digital6004Lins62070503***63040BFF",
"type": "dynamic",
"status": "ACTIVE",
"value": 150.75,
"message": "Payment for order #12345",
"description": "Payment for order #12345",
"identifier": "order-12345",
"accountId": "{accountId}",
"pixKey": "8026ff12-cb4a-4d19-9638-08bb15d450e2",
"allowChange": false,
"createdAt": "2026-02-10T12:00:00Z",
"expiresAt": "2026-02-10T15:30:00Z"
}
data 信封

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

字段描述
emvPIX 复制粘贴代码(EMV 字符串)。渲染为 QR code。
txid内部交易 ID
identifier唯一的收款 ID(用于查询)
status收款状态(ACTIVE = 有效)
pixKey用于收款的 PIX 密钥
value收款金额(BRL)
expiresAt过期时间(RFC3339)

第二步:显示 QR Code

使用 PIX 复制粘贴

emv 字段展示给客户进行复制:

<input type="text" 
value="00020101021226790014br.gov.bcb.pix..."
readonly />
<button onclick="navigator.clipboard.writeText(this.previousElementSibling.value)">
Copy
</button>
提示

您可以使用任何 QR code 库(例如 qrcode.jspython-qrcode)从 emv 字符串生成 QR code 图片。

第三步:查询收款状态

通过 identifier 轮询收款状态:

仅用于 QR 码的凭证

qrcode.manage 范围同时涵盖创建、取消和查询 QR:专用于收款的凭证无需通用查询 范围(read,同时可访问余额与流水)即可确认 QR 是否已付款。参见 身份验证指南

请求

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

可能的状态

状态描述
ACTIVE已创建 / 等待中
AWAITING-PAYMENT等待付款
PAID付款已确认
CANCELLED已取消 / 被拒绝
EXPIRED已过期,未收到付款
UNKNOWN合作方状态超出已知映射
大写值

status大写(规范化)返回。PIX 退款不会将 QR 状态改为 "refunded" —— QR 保持 PAID,退款通过交易/账单跟踪。

各状态的响应示例

有效(等待付款)

{
"txid": "88a38a908a92441a98dac228ee1d9507",
"emv": "00020101021226790014br.gov.bcb.pix2557brcode.starkinfra.com/v2/88a38a90...",
"type": "dynamic",
"status": "ACTIVE",
"value": 150.75,
"description": "Payment for order #12345",
"identifier": "order-12345",
"accountId": "6ff57bc1-e4a9-403b-be62-42378b8aafd7",
"pixKey": "8026ff12-cb4a-4d19-9638-08bb15d450e2",
"createdAt": "2026-02-09T01:50:36Z",
"expiresAt": "2026-02-09T02:50:34Z"
}

已支付(付款已确认)

{
"txid": "b091da7bba6a45d1a9f709daaba04e30",
"emv": "00020101021226790014br.gov.bcb.pix...",
"type": "dynamic",
"status": "PAID",
"value": 150.75,
"message": "Payment for order #12345",
"description": "Payment for order #12345",
"identifier": "order-12345",
"accountId": "6ff57bc1-e4a9-403b-be62-42378b8aafd7",
"pixKey": "8026ff12-cb4a-4d19-9638-08bb15d450e2",
"allowChange": false,
"createdAt": "2026-02-05T22:08:02Z",
"expiresAt": "2026-02-05T23:08:00Z",
"paidAt": "2026-02-05T22:10:25Z",
"paidAmount": 150.75,
"endToEndId": "E303062942026020522100000005EXVX",
"payer": {
"name": "John Smith",
"document": "12345678901",
"bankIspb": "30306294",
"bankName": "BANCO EXEMPLO",
"branch": "0020",
"account": "004912314"
},
"payee": {
"name": "iDez Digital",
"document": "12345678000190",
"bankIspb": "50871921",
"bankCode": "681"
}
}

退款后

PIX 退款(POST /v1/accounts/{accountId}/pix/out/refund不会将 QR 状态 改为 "refunded" —— QR 保持 PAID。退款是独立交易;请通过账单 (GET .../statement)或付款查询(GET .../pix/payments/lookup)跟踪。QR 查询不会返回退款字段。

已过期(收款已过期)

{
"txid": "c1234567890abcdef1234567890abcde",
"emv": "00020101021226790014br.gov.bcb.pix...",
"type": "dynamic",
"status": "EXPIRED",
"value": 50.00,
"identifier": "order-99999",
"accountId": "6ff57bc1-e4a9-403b-be62-42378b8aafd7",
"pixKey": "8026ff12-cb4a-4d19-9638-08bb15d450e2",
"createdAt": "2026-02-01T10:00:00Z",
"expiresAt": "2026-02-01T10:30:00Z"
}

字段参考

字段何时出现描述
txid始终内部 QR code 交易 ID
emv始终PIX 复制粘贴代码(BR Code)
type始终QR code 类型(dynamicstatic
status始终当前状态(ACTIVEAWAITING-PAYMENTPAIDCANCELLEDEXPIREDUNKNOWN
value始终收款金额(BRL)
identifier始终您的唯一收款标识符
accountId始终收款所属账户
pixKey可用时收款使用的 PIX 密钥
createdAt可用时创建时间戳
expiresAt可用时过期日期(动态 QR)
paidAt已支付时付款时间戳
paidAmount已支付时实际支付金额(BRL)
endToEndId已支付时PIX E2E 标识符
payer已支付时付款人信息(name、document、bankIspb、bankName、branch、account、pixKey)
payee可用时收款人(您的账户)信息

查询端点

通过 identifier 查询(向后兼容别名:txid):

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

查询在合作方端实时解析,返回扁平的 QR 对象(status、value、emv,以及 付款后返回 payer/payee/endToEndId)。此端点接受 qrcodeId/endToEndId,且返回交易/手续费/退款数据。

第四步:接收付款 Webhook

当客户完成付款时,您会收到一个采用规范信封(idtypeoccurredAtschemaVersiondata)的 qrcode.paid webhook:

{
"id": "evt_987654321",
"type": "qrcode.paid",
"occurredAt": "2026-02-05T22:10:25.000Z",
"schemaVersion": "1.0",
"environment": "production",
"tenantId": "tenant-yourcompany",
"accountId": "{accountId}",
"data": {
"endToEnd": "E303062942026020522100000005EXVX",
"type": "dynamic",
"identifier": "order-12345",
"qrcodeId": "b091da7bba6a45d1a9f709daaba04e30",
"amount": 150.75,
"payer": {
"name": "John Smith",
"document": "12345678901",
"bankCode": "033",
"branch": "0001",
"accountNumber": "54321-0"
},
"payee": {
"name": "iDez Digital",
"document": "12345678000190"
},
"receivedAt": "2026-02-05T22:10:25.000Z"
}
}
提示

通过 POST /v1/webhooks 配置 webhooks,事件类型为 qrcode.paid。参见 Webhooks 指南

第五步:取消收款(可选)

在收款被支付之前取消待处理的收款:

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

响应(200 OK):

{
"identifier": "order-12345",
"status": "CANCELLED"
}

第六步:QR Code 指标(可选)

QR code 没有列表端点 —— 查询始终通过 identifier。如需按天聚合的指标 (生成/支付/退款/金额),请使用:

curl -X GET "https://tenant.api.corpx.com/v1/accounts/{accountId}/pix/qr-codes/stats?days=30" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: {tenant_id}"

完整示例:电子商务集成

#!/bin/bash

# Configuration
API_URL="https://tenant.api.corpx.com"
TOKEN="your_token_here"
TENANT_ID="tenant-yourcompany"
ACCOUNT_ID="your-account-id"
PIX_KEY="your-pix-key"

# 1. Create charge for order
ORDER_ID="order-$(date +%s)"
AMOUNT=299.90
EXPIRATION=$(date -u -v+30M +"%Y-%m-%dT%H:%M:%SZ") # 30 minutes

echo "Creating charge: $ORDER_ID for R\$$AMOUNT..."

response=$(curl -s -X POST "$API_URL/v1/accounts/$ACCOUNT_ID/pix/qr-code/dynamic" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Tenant-Id: $TENANT_ID" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $ORDER_ID" \
-d "{
\"pixKey\": \"$PIX_KEY\",
\"value\": $AMOUNT,
\"expirationDate\": \"$EXPIRATION\",
\"identifier\": \"$ORDER_ID\",
\"message\": \"Store Purchase - $ORDER_ID\"
}")

# 2. Extract information
IDENTIFIER=$(echo $response | jq -r '.identifier')
EMV=$(echo $response | jq -r '.emv')

echo "Charge created!"
echo "ID: $IDENTIFIER"
echo "PIX Copy and Paste: $EMV"

# 3. Poll for payment (alternative to webhook)
while true; do
sleep 10

status_response=$(curl -s "$API_URL/v1/accounts/$ACCOUNT_ID/pix/qr-code/lookup?identifier=$IDENTIFIER" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Tenant-Id: $TENANT_ID")

current_status=$(echo $status_response | jq -r '.status')

if [ "$current_status" = "PAID" ]; then
paid_amount=$(echo $status_response | jq -r '.paidAmount')
e2e=$(echo $status_response | jq -r '.endToEndId')
echo "Payment confirmed! Amount: R\$$paid_amount, E2E: $e2e"
break
elif [ "$current_status" = "EXPIRED" ]; then
echo "Charge expired"
break
fi

echo "Awaiting payment... Status: $current_status"
done

最佳实践

  1. 使用 Idempotency Key - 每笔收款始终发送唯一标识符以防止重复
  2. 设置合适的过期时间 - 结账页面设置 30 分钟,发票设置 24 小时
  3. 配置 webhooks - 不要仅依赖轮询,使用 qrcode.paid 事件
  4. 所有金额使用 BRL - 最多 2 位小数(例如 150.75 表示 R$150,75)
  5. 处理过期情况 - 当收款过期时通知客户
  6. 保存 identifier - 用于查询状态和对账

常见错误

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

errorCodeHTTP原因解决方案
missing_field400缺少 pixKey,或 value 小于等于零提供已注册的密钥和正数 BRL 金额
invalid_identifier400identifier 超出字符集 [A-Za-z0-9._-] 或超过 38 个字符调整标识符
invalid_field400message 超过 140 个字符或含不支持的字符缩短消息
invalid_payload400JSON 格式错误、expirationDate 不符合 RFC3339 或已过期修正请求体
missing_param400查询/取消时未在 query 中提供 identifier提供 ?identifier=(别名:txid
not_found404未找到收款检查 identifier 和 accountId
policy_denied422策略规则拒绝了该收款的创建查看响应体中的 violations —— 策略与规则

示例:

{
"errorCode": "missing_field",
"message": "pixKey and positive value are required"
}

后续步骤