退款指南(PIX 退款)
本指南说明如何为已收到的 PIX 付款申请退款。
概述
PIX 退款允许您全额或部分撤销已收到的付款。原始交易始终通过 E2E
(End-to-End ID) 标识——不支持按收款 identifier 退款。如果您只有
identifier,请先查询二维码或支付以获取 E2E(参见如何找到 E2E)。
使用场景
- 重复付款 - 客户付款两次
- 订单取消 - 付款后取消订单
- 金额错误 - 客户支付的金额与预期不符
- 操作失误 - 错误地收到付款
期限
PIX 退款期限由 BACEN 规定并由清算行执行:自原始付款起 90 天,普通退款 和欺诈退款均适用。
超过该期限后,清算行会拒绝退款——API 将该拒绝以 partner_rejected(422)
转达,具体原因见 partner 区块。没有专门的"期限已过"错误码。此时请使用
其他撤销方式。
通过 E2E (End-to-End ID) 申请退款
E2E 是巴西 PIX 系统中的唯一交易标识符。格式:E{ISPB}{DATE}{SEQUENTIAL}。
请求
curl -X POST "https://tenant.api.corpx.com/v1/accounts/{accountId}/pix/out/refund" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: tenant-suaempresa" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: refund-e2e-12345" \
-d '{
"originalEndToEnd": "E36741675202601281435001234567",
"amount": 150.00,
"reason": "user-requested",
"identifier": "refund-order-12345"
}'
请求体参数
收到原始 PIX 的账户来自路径({accountId}),币种固定为 BRL —— 两者都不会
从请求体读取。
| 字段 | 类型 | 必填 | 描述 |
|---|---|---|---|
originalEndToEnd | string | 是 | 要退款的原始交易的 E2E ID |
amount | number | 是 | 退款金额(BRL)——等于原始 PIX 金额(全额退款)或更小(部分退款),不得超过 |
reason | string | 是 | 退款原因 kebab-case slug(见下表) |
identifier | string | 否 | 退款标识符(最多 38 个字符 [A-Za-z0-9._-])。省略时自动生成 |
description | string | 否 | 自由格式描述(最多 140 个字符) |
reason 值
列表是封闭的:表中以外的任何值都会返回 HTTP 400。Slug 直接传给合作银行(MT Bank),不做转换。
| Slug | 使用场景 |
|---|---|
user-requested | 终端客户申请退款(最常见) |
transaction-error | 通用交易错误(金额错误、数据不一致) |
unauthorized-transaction | 持有人未授权的交易 |
fraud | 已确认/疑似欺诈 |
trade-disagreement | 商业纠纷(商品/服务未交付) |
withdrawal-purchase | 涉及 PIX Saque/Troco 的操作 |
contractual-divergence | 双方间的合同分歧 |
operational-error | 操作/银行处理错误 |
duplicate-payment | 重复支付 |
成功响应
退款走与 PIX out 相同的流程(和结构)。HTTP 状态反映结果:200
(COMPLETED)、422(FAILED)、202(TIMEOUT/PENDING)。
{
"paymentId": "pay_2f4a0f88-2147-49f2-a4e2-4f7b9f6c0f7a",
"transactionId": "txn-refund-abc123",
"endToEndId": "D12345678202301011500009876543",
"status": "COMPLETED",
"completedAt": "2026-01-28T15:00:03Z",
"identifier": "refund-order-12345"
}
| 字段 | 描述 |
|---|---|
paymentId | 内部支付意图 ID(追踪/对账) |
endToEndId | 退款 D-code/E2E(登记后) |
status | COMPLETED、FAILED、TIMEOUT、PENDING、PROCESSING |
errorCode / errorReason | 当 FAILED 时填充 |
响应中没有
refundId/amount/currency字段 —— 请使用paymentId, 并通过账单或 webhook 跟踪最终结果。
部分退款
amount 为必填,决定退还给付款人的金额:填写原始 PIX 全额即为全额退款,
填写更小的金额即为部分退款。若超过原始金额,API 返回
400 refund_amount_exceeded,且不会发起退款。
同一笔 PIX 可以分多次退款,累计不超过原始金额。这里有两条重要规则:
- 每次退款都需要各自的
Idempotency-Key和identifier。 重复使用其中 任意一个,API 会把该请求视为上一次退款的重试并返回上次的结果 —— 第二笔 部分退款将不会发出。 - 可退余额由清算合作方掌握。 CorpX 不累计部分退款:超出可退余额的请求
会被合作方拒绝,并以
refund_amount_exceeded返回。
要查询某笔 PIX 已退多少,请查看账户账单:退款条目会引用原始交易的 E2E。
退款 Webhook
当退款处理完成后,您会收到一个 webhook:
{
"id": "pix-refund-pay_2f4a0f88-2147-49f2-a4e2-4f7b9f6c0f7a",
"type": "pix.refund.completed",
"occurredAt": "2026-01-28T15:00:03.000000000Z",
"schemaVersion": "1.0",
"environment": "production",
"tenantId": "tenant-yourcompany",
"accountId": "{accountId}",
"data": {
"paymentId": "pay_2f4a0f88-2147-49f2-a4e2-4f7b9f6c0f7a",
"tenantId": "tenant-yourcompany",
"accountId": "{accountId}",
"status": "SUCCESS",
"endToEnd": "D36741675202601281500009876543",
"transactionId": "txn-refund-abc123",
"amount": 150.00,
"currency": "BRL",
"identifier": "refund-order-12345",
"description": "",
"originalTransactionId": "E36741675202601281435001234567",
"initiatedAt": "2026-01-28T15:00:01.000000000Z",
"completedAt": "2026-01-28T15:00:03.000000000Z",
"payee": {
"name": "John Smith",
"document": "12345678901"
}
}
}
被拒绝的退款会发出 pix.refund.failed,其 status 为 "FAILED",且 data
中包含 errorCode/errorReason/error。处于 TIMEOUT 的退款不会发出
webhook —— 请查询流水确认。
完整示例:退款脚本
#!/bin/bash
# Configuration
API_URL="https://tenant.api.corpx.com"
TOKEN="your_token_here"
TENANT_ID="tenant-suaempresa"
ACCOUNT_ID="your_account"
# Refund by E2E function
refund_by_e2e() {
local e2e=$1
local amount=$2
local reason=$3
echo "Requesting refund..."
echo "E2E: $e2e"
echo "Amount: R$ $amount"
echo "Reason: $reason"
echo ""
IDEMPOTENCY_KEY="refund-$(date +%s)-$RANDOM"
response=$(curl -s -X POST "$API_URL/v1/accounts/$ACCOUNT_ID/pix/out/refund" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Tenant-Id: $TENANT_ID" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $IDEMPOTENCY_KEY" \
-d "{
\"accountId\": \"$ACCOUNT_ID\",
\"originalEndToEnd\": \"$e2e\",
\"amount\": $amount,
\"currency\": \"BRL\",
\"reason\": \"$reason\"
}")
echo "$response" | jq
}
# Usage
echo "=== PIX REFUND ==="
echo ""
read -p "E2E (End-to-End ID): " e2e
read -p "Amount to refund: " amount
read -p "Reason: " reason
refund_by_e2e "$e2e" "$amount" "$reason"
如何找到 E2E
E2E 可以在以下位置找到:
- 收款 webhook 响应中
- 收款查询 在付款后
- 账户对账单(Statement)
- 付款方的收据
示例:从 Webhook 中提取 E2E
{
"id": "evt_in_123",
"type": "pix.in.completed",
"occurredAt": "2026-01-28T14:35:00.000Z",
"schemaVersion": "1.0",
"tenantId": "tenant-yourcompany",
"accountId": "{accountId}",
"data": {
"identifier": "cob_abc123def456",
"endToEnd": "E36741675202601281435001234567",
"amount": 150.00
}
}
需要保存的字段是 data.endToEnd。
示例:从收款(QR Code)中提取 E2E
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-suaempresa"
{
"identifier": "order-12345",
"status": "PAID",
"endToEndId": "E36741675202601281435001234567"
}
二维码查询的响应是扁平对象(没有 data 信封);需要保存的字段是
endToEndId。
常见错误
| 错误 | HTTP | 原因 | 解决方案 |
|---|---|---|---|
missing_fields | 400 | 缺少 originalEndToEnd 或 amount | 两个字段都要提供 |
invalid_payload | 400 | reason 不在封闭列表中,或 JSON 格式错误 | 使用上表中的 slug |
refund_amount_exceeded | 400 | amount 大于原始 PIX,或大于剩余可退余额 | 在账单中确认已退金额 |
original_transaction_not_found | 404 | 清算行未找到该 E2E | 检查 originalEndToEnd |
conflict | 409 | 交易已全额退款 | 在账单中检查历史记录 |
insufficient_funds | 422 | 退款余额不足 | 向账户充值 |
policy_denied | 422 | tenant/账户的策略规则拒绝了该退款 | 查看响应体中的 violations —— 策略与规则 |
partner_rejected | 422 | 清算行拒绝(包括超过 90 天期限) | 查看 partner 区块中说明的原因 |
partner_error | 502 | 在清算行查询原始交易失败 | 请重试;若持续出现请联系客服 |
完整列表见错误。
最佳实践
- 保存所有已收交易的 E2E
- 使用 Idempotency Key 以避免重复退款 —— 同一笔 PIX 的每次部分退款都要使用不同的 Key(以及
identifier) - 在申请下一次部分退款前,先在账单中确认 该笔 PIX 已退多少
- 记录退款原因 以便审计
- 配置 webhooks 以跟踪状态
- 保留退款历史 用于对账
后续步骤
- 认证指南 - 获取访问令牌
- QR Code 指南 - 创建收款
- Webhooks - 接收通知