Skip to content

PIX Cash-In -- 生成 QR Code

生成带 QR Code 的 PIX 收款请求,将资金收入与您 API Key 关联的账户。

端点

POST /api/external/pix/cash-in

请求头

类型必填描述
AuthorizationStringApiKey {client_id}:{client_secret}
Content-TypeStringapplication/json
hmacStringbody 的 HMAC-SHA512 签名(了解详情
Idempotency-KeyString避免重复处理的唯一键(最多 256 字符)
X-Key-CaseString设为 camelCase 以使用 camelCase 接收响应字段(默认 snake_case)

请求体

字段类型必填描述示例
amountInteger金额,以**分(centavos)**为单位(R$ 30,00 = 30003000
descriptionString收款描述。如省略,默认为 "Cobranca PIX""Pedido #1234"
external_idString您系统中的标识符,用于追踪。最多 128 字符。仅 a-zA-Z0-9._:-(超出标准的值会被静默丢弃,字段返回 null -- 见下方警告)。在响应和 webhook 中返回。"order-9876"
pix_keyString用于生成 QR Code 的特定 PIX 密钥。如省略,使用账户最新的活跃密钥(按 inserted_at DESC 排序)。"12345678901"
cityString收款人在 QR Code 中的城市。默认:SAO PAULO。自动截断为 15 个字符。"RIO DE JANEIRO"

amount 始终以整数(分)发送

字段 amount 必须是以分为单位的整数绝不发送 float/decimal 值:

  • "amount": 3000 → R$ 30,00
  • "amount": 30.00 → 解释为 30 分 = R$ 0,30(金额小 100 倍
  • "amount": 30 → R$ 0,30(也不正确)

在 JavaScript 中,始终使用 Math.round 转换后再发送:

js
const valorEmReais = 30.0;
const amount = Math.round(valorEmReais * 100); // 3000

Python: amount = round(valor_em_reais * 100)。Go: amount := int(math.Round(valorEmReais * 100))

货币值(输入 × 响应)

输入值以分(centavos)为单位(R$ 1,00 = 100)。响应值以基础单位为单位(R$ 1,00 = 10000)。要将响应转换为雷亚尔,请除以 10.000。切勿在任何方向使用浮点数。

无效的 external_id = 静默丢弃

如果 external_id 包含 a-zA-Z0-9._:- 之外的字符、超过 128 字节或仅为空白,服务器会静默丢弃该值,响应中返回 "external_id": null(不返回错误)。在用于对账之前始终检查响应中的 external_id -- 如果返回 null,您的标识符被验证拒绝了。

示例

bash
BODY='{"amount":3000,"description":"Pedido #1234","external_id":"order-9876"}'
HMAC=$(echo -n "$BODY" | openssl dgst -sha512 -hmac "$CLIENT_SECRET" | awk '{print $2}')

curl -X POST https://api.owem.com.br/api/external/pix/cash-in \
  -H "Authorization: ApiKey $CLIENT_ID:$CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -H "hmac: $HMAC" \
  -d "$BODY"

成功响应 (200)

json
{
  "worked": true,
  "transaction_id": "7popu57v6us7p6pcicgq12345",
  "qr_code": "00020126580014br.gov.bcb.pix...",
  "qr_code_image": "data:image/png;base64,iVBORw0KGgo...",
  "external_id": "order-9876",
  "amount": 300000,
  "status": "active",
  "type": "dynamic",
  "location_url": "https://qrcode.owem.com.br/pix/v2/a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
  "expires_at": "2026-03-07T16:30:00Z"
}
字段类型描述
workedBooleantrue 表示操作成功
transaction_idString | null收款唯一标识(QR Code 的 tx_id,按 BACEN spec 最多 35 个字母数字字符)。仅在罕见的内部持久化故障中为 null
qr_codeString | null用于支付的 EMV 复制粘贴码。仅在罕见的内部持久化故障中为 null(JSON 字面值,不是字符串 "null"
qr_code_imageStringBase64 编码的 QR Code 图像(PNG,前缀 data:image/png;base64,)。在罕见的内部故障中为空字符串(""
external_idString | null您的标识符,按发送时原样返回。未提供时、无效时(见上方警告)或被清理丢弃时为 null
amountInteger收款金额,以基础单位(÷ 10.000 得到雷亚尔)。300000 = R$ 30,00
statusString初始状态始终为 active(QR Code 已激活可收款)。后续演变(paid/expired/cancelled)可通过查询和 webhook 查看(见 QR Code 生命周期
typeString | nullQR Code 类型:dynamic(2026 年 4 月起的默认)或 static。Dynamic 要求付款方银行查询 location_url 并验证 JWS
location_urlString | nullBACEN 动态载荷查询 URL(例:https://qrcode.owem.com.br/pix/v2/{uuid})。不是 JWS 本身 -- 付款方银行对此端点执行 GET 以接收签名的 ISO 20022 载荷(JWS PS256)。仅在动态 QR 中出现;静态 QR 为 null
expires_atString | nullQR Code 过期日期/时间,ISO 8601 UTC 带 Z 后缀(例:2026-03-07T16:30:00Z)。无过期时为 null

动态 QR 是默认

所有生产账户自 2026 年 4 月起默认使用动态 QR。动态 QR 包含 URL(location_url),付款方银行通过 JWS 查询该 URL 获取签名载荷 -- 最大化与 BACEN-strict 银行的兼容性。

错误响应 (400)

json
{
  "worked": false,
  "detail": "O campo amount é obrigatório"
}

错误响应 (401)

json
{
  "error": {
    "status": 401,
    "message": "Missing API key credentials. Use Authorization: ApiKey <client_id>:<client_secret>"
  }
}

错误响应 (422)

json
{
  "worked": false,
  "detail": "Invalid HMAC signature"
}

推荐流程

  1. 使用此端点生成收款请求
  2. 向付款方展示 QR Code(qr_code_image)或复制粘贴码(qr_code
  3. 通过 Webhook 接收支付成功确认
  4. 或查询状态:按 ID按 E2E按 Tag

QR Code 有效期

生成的 QR Code 默认有效期 1 小时。有效期可按账户配置(字段 qrcode_expiration_seconds);始终检查响应中返回的 expires_at 获取确切日期/时间。

过期后,状态自动变为 expired(通过内部 worker,每 5 分钟运行一次)。对于 merchant 手动取消的收款,状态为 cancelled。参见 按 ID 查询 Cash-In 中的完整状态列表。

QR Code 生命周期

QR Code 在创建后经历这些状态:

状态来源描述
active初始QR 生成成功,准备被扫描/支付
paid收到付款BACEN 付款已确认并关联到 QR(通过 ACCC 后的内部 worker)
expiredWorker QrExpirationCheckerTTL 达到 expires_at。Worker 每 5 分钟运行,标记过期的 active QR 并触发 webhook pix.charge.expired
cancelled手动或批量由 merchant 取消(通过门户)或在管理操作中(例:2026 年 4 月静态→动态迁移取消了带值的活跃静态 QR)
used遗留旧 pipeline 的瞬时中间状态。新客户端应将其视为等同于 paid

在查询中,paid 可能显示为 settled

端点 GET /transactions/:id 及等效项从交易(非 QR)视角返回 status 字段。已付款的 QR 在查询中显示为 status: "settled",type: "pix"(或结算后短期窗口内 type: "pix_qrcode",此时 transactions 中的最终行仍在持久化)。参见 按 ID 查询 Cash-In 中的完整表格。

Owem Pay Instituição de Pagamento — ISPB 37839059