跳到主要内容

从 v1 迁移 — 完整参考

如需 2 分钟版本,请见从 v1 迁移 — 快速版

本文档面向审计迁移的开发者、运维团队以及边缘场景。列出约 75 个面向集成方的路由及其在 v2 上的行为。


1. 认证

之前(v1)

TOKEN_URL="https://corpx-{env}.auth.sa-east-1.amazoncognito.com/oauth2/token"
curl -X POST "$TOKEN_URL" \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-d "grant_type=client_credentials&scope=api/full"

现在(v2)

TOKEN_URL="https://auth.api.corpx.com/oauth2/token"
curl -X POST "$TOKEN_URL" \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-d "grant_type=client_credentials&scope=api2/read api2/write"

差异:

  • Token URL 变了(经过我们的 CloudFront)。
  • scopeapi/fullapi2/read api2/write
  • JWT TTL:1 小时(与 v1 相同)。
  • Idempotency-Key:v2 上可选(缺失时自动生成;仍建议你自己传以便于重试控制)。
  • X-Tenant-Id:所有 /v1/* 请求必填GET /v1/me 与健康检查除外);路径含 accountId 时必须与账户租户一致。

2. 已废弃端点(在 2026-11-21 之前仍可用)

v1 上存在但未保留在 v2 规范形态中的 4 条路径,已作为已废弃别名重新启用。它们仍正常响应 — 仅在响应中附加 3 个警示响应头:

Deprecation: true
Sunset: Sat, 21 Nov 2026 00:00:00 GMT
Link: </v1/accounts/.../新路径>; rel="successor-version"

这些响应头遵循 RFC 8594(Deprecation)和 RFC 9745(Sunset)。客户端可以自动检测它们以提醒团队。

预定下线日期:2026-11-21。 该日期之后这些路由将开始返回 410 Gone

已废弃路由(仍可用)规范替代
GET /v1/accounts/{id}/pix/payments/{paymentId}GET /v1/accounts/{id}/pix/payments/lookup?identifier=...
GET /v1/accounts/{id}/payments/{paymentId}(无 /pix/ 别名)GET /v1/accounts/{id}/pix/payments/lookup?identifier=...
GET /v1/accounts/{id}/pix/qr-code(无 /lookupGET /v1/accounts/{id}/pix/qr-code/lookup?identifier=...
POST /v1/accounts/{id}/pix/out/qrcode(无连字符)POST /v1/accounts/{id}/pix/out/qr-code

这些路由不再出现在 OpenAPI 和 Postman 集合中 — 仅在此处记录以便你有时间迁移。新集成请直接使用规范替代。


3. 移除的端点(7 条路由 — 返回 404)

v1 路由(已移除)替代方案
POST /v1/webhooks/replay对账单短窗轮询
GET /v1/integrator/webhooks使用 GET /v1/webhooks
GET /v1/integrator/webhooks/{id}/deliveries无替代 — 如有依赖请联系支持
POST /v1/integrator/events/replay无替代
POST /v1/integrator/events/replay/batch无替代
POST /v1/accounts/{id}/pix/med/{medId}/send使用 /decide(但 MED 当前为 503)
POST /v1/accounts/{id}/pix/med/{medId}/response使用 /answer(但 MED 当前为 503)

GET /v1/health 在 v2 上仍然存在。我们额外添加了 GET /health 别名(不含 /v1),方便外部健康检查 — 你无需修改任何内容。


4. 行为变化的端点

路径相同、方法相同,但行为或 JSON 结构不同

4.1 Statement — 缓存 → 实时(payer/payee 字段精简)

GET /v1/accounts/{id}/statement

v1: 读取由 webhook 填充的本地缓存(DynamoDB)。延迟约 50ms;item 中包含 tariff_ref 与翻译后的标签。每行都有完整的 payer.{bankCode,bankIspb,branch,account,pixKey,...}beneficiary.{...},因为它们由 webhook 拼装而成(webhook 携带对手方所有银行字段)。

v2: 请求时直接调用清算银行。延迟约 500ms-1.5s;不再有派生的 tariff_ref(手续费作为对账单中的独立条目);新响应头 X-Source: live。每次查询最大窗口:31 天。

每行 shape 的变化

v2 将对手方对象标准化为 name + document,再加上我方(清算银行 = MT Bank)的银行信息。对手方其余银行字段(branchaccountpixKey 等)不再出现在对账单的行项中,因为清算银行的对账单端点不暴露这些字段。

v1(旧版,来自 webhook 缓存):

{
"amount": -100.00,
"direction": "OUT",
"endToEndId": "E...",
"payer": { "name": "...", "document": "...", "bankCode": "681", "bankIspb": "50871921", "branch": "...", "account": "...", "pixKey": "..." },
"beneficiary":{ "name": "...", "document": "...", "bankCode": "001", "bankIspb": "00000000", "branch": "...", "account": "...", "pixKey": "..." }
}

v2(实时,来自清算银行):

{
"amount": -100.00,
"direction": "OUT",
"endToEndId": "E...",
"payer": { "name": "我的公司有限公司", "document": "12345678000190", "bankCode": "681", "bankIspb": "50871921", "bankName": "MT Instituição de Pagamentos" },
"payee": { "name": "供应商 XYZ", "document": "98765432000110" },
"counterParty": { "name": "供应商 XYZ", "document": "98765432000110" }
}

v2 shape 说明:

  • payer / payee 对由该行的 direction 决定:
    • direction=INpayer = 对手方(付款给我们的人);payee = 我方账户;
    • direction=OUTpayer = 我方账户;payee = 对手方(我们付款给的人)。
  • 我方 端始终带 name(持有人)、document(CPF/CNPJ)以及清算银行标识(bankCodebankIspbbankName)。
  • 对手方 端始终只带 name + document。可选字段(bankCodebankIspbbranchaccountpixKeyaccountTypebankName)在为空时被省略 —— v2 的 partyToDTO 不会输出空字符串的 key。
  • counterParty(包含对手方 name + document 的额外对象)继续保留,方便无需检查 direction 直接查找。
  • 移除了 authorizationCode 字段(清算银行的 API 在对账单中不返回该字段;即便 v1 在 live fallback 下也始终为空)。

如何获取完整的对手方银行 payload

如果你的集成需要对手方的 branch/account/pixKey/bankCode,请使用下列任一替代方案(它们都返回完整 payload,因为来源于专门的 PIX 端点,而不是对账单):

  • outbound webhookpix.in.completedpix.out.completedpix.refund.completedqrcode.paid —— CorpX 信封中的 payer / payee 包含所有银行字段。
  • 单笔支付查询GET /v1/accounts/{id}/pix/payments/lookup?endToEndId=... —— 返回完整交易对象(与 webhook 相同)。
  • 二维码GET /v1/accounts/{id}/pix/qr-code/lookup?identifier=... —— 对于已支付的二维码,包含 payerpayment.endToEnd

如果你的集成依赖积极的对账单轮询,请改用 webhook

  • pix.in.received:收到 PIX
  • pix.out.confirmed:PIX out 完成
  • boleto.paid / boleto.failed
  • qrcode.paid

同样的影响适用于其他原先从相同缓存读取的端点:

  • GET /v1/accounts/{id}/pix/transactions
  • GET /v1/accounts/{id}/pix/payments
  • GET /v1/accounts/{id}/payments(别名)

它们现在都实时查询清算银行,没有本地缓存。

4.2 MED — 迁移期间 503

所有 /v1/accounts/{id}/pix/med/* 端点返回 503 service_temporarily_unavailable。计划在 v2.x 恢复。如切换时存在活跃 MED,我们团队将单独联系。

med.* webhook 同样暂停 — 此期间不发送任何争议事件。无需移除订阅;模块恢复时事件将自动恢复。

4.3 Boleto — 已激活

v1 上所有 boleto 端点(POST .../boleto/previewPOST .../boleto/payGET .../boleto/payments/{id})返回 503。v2 已激活。见 Cash Out 指南

4.4 PIX out — 同步 vs 异步(并非“全部异步”)

v2 保留与 v1 相同的划分:

路由模式HTTP 响应
POST .../pix/out同步等待 workflow 最多约 25 秒。及时完成:200 含最终状态(APPROVEDFAILED422 等)及 endToEndId(如有)。超时:202 + status: PENDING + warning,再查 lookup/webhook。
POST .../pix/out/qr-code同步/pix/out(约 25s)。
POST .../pix/out/bank-account同步同上。
POST .../pix/out/refund同步同上。
POST .../pix/out/async异步立即 202,含 {paymentId, workflowId, idempotencyKey, identifier} — 最终结果靠 webhook 或 GET .../pix/payments/lookup?identifier=...
POST .../pix/out/bank-account/async异步立即 202(同 /async)。
POST .../pix/out/bigpix(及 bank-account/bigpix异步立即 202(批次;服务端分块不变)。

内部变化(不强制改调 async): 编排改为 Temporal,但已使用 POST .../pix/out /async)的集成方仍为同步路径。仅在需要高吞吐或不想占用 HTTP 连接约 25s 时再改用 /async

幂等: 相同 Idempotency-Key 重试会复用进行中的 paymentId/workflow;FAILED 后换新 key 可再试(见 Cash Out)。

4.5 X-CF-Origin-Verify

v2 仅接受来自 CloudFront 的请求。直接访问 execute-api 返回 403。请始终使用 https://tenant.api.corpx.com/v1

4.6 临时暂停的 webhook — fee.*med.*edi.*

迁移期间,3 个事件家族不发送

家族状态如何继续看到数据
fee.*fee.chargedfee.refunded 等)暂停手续费作为对账单中的独立条目出现(GET /v1/accounts/{id}/statement)。查找 type=internal-transferidentifier=fee-{slug}-{operationReferenceId} 指向 CORPX_FEE_ACCOUNT_ID 的条目。
med.*med.openedmed.answered 等)暂停整个 MED 模块离线(见 §4.2)。
edi.*(CNAB/EDI 批文件事件)暂停文件仍在生成,但 webhook 通知暂停。请使用 CNAB 批次 GET 接口跟踪。

对你意味着什么:

  • 这些事件的订阅可以保留 — 恢复时会自动恢复发送。
  • 如你的对账依赖这些事件,请暂时改为对账单轮询(清算银行的查询为实时,无缓存延迟)。

分阶段恢复计划:

  • fee.* — no-cache 重构稳定后的下一个次版本。
  • med.* — 与 v2.x 上 MED 模块的恢复一同。
  • edi.* — 待定;取决于新的批次管道。

4.7 交易 ↔ 手续费的自动对账 — 暂停

v1: 交易对象包含 fee: { amount, ... } 字段,将每笔 PIX/boleto 与其处理费配对。

v2: 该字段临时移除。对账在客户端通过交叉引用 identifier 完成:

  • 主交易:identifier = <你的 identifier>(或自动生成)
  • 匹配手续费:identifier = fee-{slug}-{operationReferenceId},在同一时间窗内从 CORPX_FEE_ACCOUNT_ID 借记

通过对账单对账:

GET /v1/accounts/{accountId}/statement?startDate=2026-05-21&endDate=2026-05-21

过滤 identifierfee- 开头的条目,通过嵌入的 operationReferenceId 与主交易关联。

no-cache 重构稳定后,交易对象上的 fee 字段会回归。该回归不计划修改载荷 — 仅是字段重新出现。

4.8 Internal transfer by-bank-account — 可选额外字段

POST /v1/accounts/{id}/transfers/internal/by-bank-account

v2 接受两个可选额外字段:holderDocumentholderName。当前清算银行需要这些数据;当客户端未发送时,后端会自动查找。非破坏性 — 继续只发送 {branch, accountNumber, value, ...} 的客户端可正常工作。

4.9 PIX QR-code — 响应已扁平化(JSON 破坏性变更

响应解析破坏性变更

在完整表(§6)中,这些端点标记为 body-diff,而非 identical:路径相同,但成功响应 JSON 已变。使用 response.data.payloaddata.location 的代码会失败——包括 POST .../pix/qr-code/dynamic

影响 5 个 QR-code 端点

  • POST /v1/accounts/{id}/pix/qr-code/dynamic
  • POST /v1/accounts/{id}/pix/qr-code/static
  • GET /v1/accounts/{id}/pix/qr-code/lookup(以及已废弃别名 GET /v1/accounts/{id}/pix/qr-code
  • DELETE /v1/accounts/{id}/pix/qr-code

v1: Finaya 风格的信封:

{
"statusCode": 200,
"title": "...",
"type": "...",
"message": "...",
"data": {
"txid": "ABC123",
"payload": "00020126...",
"location": "https://qr.mtbank.com.br/cob/...",
"...": "..."
}
}

v2: 规范扁平结构,无信封:

{
"txid": "ABC123",
"emv": "00020126...",
"type": "dynamic",
"status": "ACTIVE",
"value": 12.34,
"message": "Charge X",
"identifier": "abc123",
"expiresAt": "2026-12-31T23:59:59Z",
"createdAt": "2026-05-21T20:00:00Z"
}

字段映射:

v1(信封)v2(扁平)备注
data.txidtxid不变
data.payloademv同一段 BRcode/EMV 字符串
data.location(已移除)在客户端从 emv 渲染二维码
statusCodetitletypemessage(信封)(已移除)由规范字段 typestatusvalueidentifierexpiresAtcreatedAt 替代

HTTP 状态码: v2 创建时返回 201 Created(POST)。GET 仍为 200

最小迁移示例:

- const emv = response.data.payload;
+ const emv = response.emv;

- const qrUrl = response.data.location;
+ // 没有原生等价字段。请使用 qrcode-svg / qrcode.js 等库在客户端渲染 EMV,
+ // 或将其托管到自己的 CDN 以获取公开 URL。

如果移除 location 对你是阻塞性的变更,请联系支持 — 我们可以评估通过缓存的 EMV 生成 CDN URL 来重新引入该字段。


5. 新增端点

端点用途
GET /v1/me当前认证 client_id 的身份信息(便于调试)
GET /v1/transactions/{id}/timeline单笔交易的详细时间线(路径中不含 accountId
GET /v1/accounts/{id}/pix/out/bigpix/{batchId}BigPix 批次聚合状态
GET /health/v1/health 的别名(不含 /v1 前缀)

6. 完整表

状态说明:

  • identical:路径与成功响应 JSON 一致。解析逻辑无需修改。
  • body-diff:路径相同,但响应或行为不同。QR-code 行(§4.9)为 JSON 破坏性变更(无 data 信封)。
  • deprecated:在 2026-11-21 之前仍可用,响应附带 Deprecation: true 头。请在下线前迁移到规范替代。
  • v1-only:仅 v1 存在的路由;在 v2 上返回 404。
  • v2-only:新增路由;仅 v2 存在。
端点v2 状态备注
GET /v1/healthidentical也接受 GET /health
GET /v1/accreditations/pfidentical
POST /v1/accreditations/pfidenticalCNPJ 的 simplified tier 请求体可能需要 Agreement
PUT /v1/accreditations/pfidentical
GET /v1/accreditations/pjidentical
POST /v1/accreditations/pjidentical同上
PUT /v1/accreditations/pjidentical
GET /v1/accounts/{id}/balanceidentical
GET /v1/accounts/{id}/statementbody-diff实时(无缓存);见 §4.1
GET /v1/accounts/{id}/transactions/timelineidentical
GET /v1/transactions/{id}/timelinev2-only新增
POST /v1/accounts/{id}/locked-balance/lockremoved (2026-05)v2 不再维护本地 hold。/balance.locked 只反映 MT 端 blocked。
POST /v1/accounts/{id}/locked-balance/unlockremoved (2026-05)同上
GET /v1/accounts/{id}/pix/limitsidentical
PATCH /v1/accounts/{id}/pix/limitsidentical
POST /v1/accounts/{id}/pix/outidentical同步(约 25s):完成时 200/422;超时 202+warning。§4.4
POST /v1/accounts/{id}/pix/out/asyncidentical异步: 立即 202。§4.4
POST /v1/accounts/{id}/pix/out/bigpixidentical单笔请求体;服务端分块;立即 202(异步)。§4.4
GET /v1/accounts/{id}/pix/out/bigpix/{batchId}v2-only批次聚合状态
POST /v1/accounts/{id}/pix/out/bank-accountidentical同步(约 25s)。§4.4
POST /v1/accounts/{id}/pix/out/bank-account/asyncidentical异步: 立即 202。§4.4
POST /v1/accounts/{id}/pix/out/bank-account/bigpixidentical异步: 立即 202(批次)。§4.4
POST /v1/accounts/{id}/pix/out/qr-codeidentical同步(约 25s),同 /pix/out。§4.4
POST /v1/accounts/{id}/pix/out/qr-code/decodeidentical
POST /v1/accounts/{id}/pix/out/qrcode(无连字符别名)deprecated2026-11-21 下线。使用 /pix/out/qr-code
POST /v1/accounts/{id}/pix/out/refundidentical同步(约 25s)。§4.4
GET /v1/accounts/{id}/pix/transactionsbody-diff实时
GET /v1/accounts/{id}/pix/paymentsbody-diff实时
GET /v1/accounts/{id}/pix/payments/{paymentId}deprecated2026-11-21 下线。使用 /pix/payments/lookup?identifier=
GET /v1/accounts/{id}/pix/payments/lookupidentical
GET /v1/accounts/{id}/payments(别名)body-diff实时
GET /v1/accounts/{id}/payments/{paymentId}(别名)deprecated2026-11-21 下线。使用 /pix/payments/lookup?identifier=
POST /v1/accounts/{id}/boleto/previewbody-diff503 → 200(v2 已激活 boleto)
POST /v1/accounts/{id}/boleto/paybody-diff503 → 200
GET /v1/accounts/{id}/boleto/payments/{paymentId}body-diff503 → 200
POST /v1/accounts/{id}/pix/qr-code/staticbody-diff破坏性: 无信封;data.payloademv;无 data.location。§4.9
POST /v1/accounts/{id}/pix/qr-code/dynamicbody-diff破坏性: 无信封;data.payloademv;无 data.location。§4.9
GET /v1/accounts/{id}/pix/qr-code(无 /lookupdeprecated2026-11-21 下线。使用 /pix/qr-code/lookup?identifier=。响应亦为 body-diff(§4.9)
GET /v1/accounts/{id}/pix/qr-code/lookupbody-diff破坏性: 与 POST 相同的扁平结构。§4.9
DELETE /v1/accounts/{id}/pix/qr-codebody-diff破坏性: 扁平响应。§4.9
GET /v1/accounts/{id}/pix/qr-codesidentical分页列表 — 不同于 POST dynamic 的响应契约(§4.9)
GET /v1/accounts/{id}/pix/qr-codes/statsidentical
GET /v1/accounts/{id}/pix/keysidentical
POST /v1/accounts/{id}/pix/keysidentical
DELETE /v1/accounts/{id}/pix/keys/{pixKey}identical
GET /v1/accounts/{id}/pix/key/{pixKey}identicalDICT 查询
GET /v1/accounts/{id}/pix/medbody-diff503 占位;见 §4.2
POST /v1/accounts/{id}/pix/med/{medId}/answerbody-diff503 占位
POST /v1/accounts/{id}/pix/med/{medId}/decidebody-diff503 占位
POST /v1/accounts/{id}/pix/med/{medId}/evidence/upload-urlbody-diff503 占位
POST /v1/accounts/{id}/pix/med/{medId}/evidence/addbody-diff503 占位
POST /v1/accounts/{id}/pix/med/{medId}/evidence/downloadbody-diff503 占位
POST /v1/accounts/{id}/pix/med/{medId}/sendv1-only使用 /decide(当前 503)
POST /v1/accounts/{id}/pix/med/{id}/responsev1-only使用 /answer(当前 503)
POST /v1/accounts/{id}/transfers/internalidentical
POST /v1/accounts/{id}/transfers/internal/by-bank-accountidentical接受可选额外字段(holderDocumentholderName);见 §4.8
POST /v1/accounts/{id}/transfers/internal/by-documentidentical
GET /v1/accounts/{id}/transfers/internal/lookup/{document}identical
POST /v1/accounts/{id}/exportsidentical
GET /v1/accounts/{id}/exportsidentical
GET /v1/accounts/{id}/exports/{exportId}/downloadidentical
GET /v1/mev2-onlyclient_id 调试
GET /v1/webhooksidentical
POST /v1/webhooksidentical
PUT /v1/webhooks/{subscriptionId}identical
DELETE /v1/webhooks/{subscriptionId}identical
GET /v1/webhooks/eventsidentical目录
POST /v1/webhooks/replayv1-only已移除
GET /v1/integrator/webhooksv1-only使用 GET /v1/webhooks
GET /v1/integrator/webhooks/{id}/deliveriesv1-only无替代
POST /v1/integrator/events/replayv1-only无替代
POST /v1/integrator/events/replay/batchv1-only无替代
GET /v1/security/ip-allowlistidentical
PUT /v1/security/ip-allowlistidentical
GET /v1/security/ip-allowlist/auditidentical

汇总: 46 个 identical、5 个 body-diff(PIX QR-code — JSON 扁平化,§4.9)、12 个 body-diff/行为类(statement live、MED 占位、boleto 503→200 等)、4 个 deprecated(别名,2026-11-21 下线)、7 个 v1-only(已移除)、3 个 v2-only(新增)。


7. Account ID 保留

你在所有路径与 webhook 中使用的 account_id 在切换前后完全相同。你不需要更新系统中保存的引用。它们仍然是 UUID。

内部变化(对你透明):

  • 清算银行的标识符是新的 — 你从未看到该字段。
  • 与清算银行的认证机制变了 — 内部 handler。

8. 完整 FAQ

我的 webhook URL 需要改吗? 不需要。

HMAC 密钥变吗? 不变。

account_id 变吗? 不变。

如果出问题,可以回到 v1 吗? 切换后前 4 小时可以 — 我们有预演的回滚方案。之后旧基础设施会逐步下线。

旧 backoffice 保留多久? 切换后 30 天。

高频对账单轮询仍能工作吗? 能,但延迟更高(约 1s,相比旧缓存的 50ms),且每次查询最大窗口为 31 天。对于变化请优先用 webhook。

有新的限流吗? 保持与 v1 相同的每租户限制。如触及限制,返回 429 Too Many Requests 并附 Retry-After

fee 字段会回到交易对象上吗? 会,在稳定后的下一个次版本。无载荷变化 — 仅字段重新出现。

fee.* / med.* / edi.* webhook 会回来吗? 会,分阶段:fee.* 在下一个次版本;med.* 与 v2.x 上 MED 模块的恢复一同;edi.* 待定。


支持

联系方式:suporte-api@corpx.com — 工作时间内 1 小时内回复。