跳到主要内容

退款指南(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 —— 两者都不会 从请求体读取。

字段类型必填描述
originalEndToEndstring要退款的原始交易的 E2E ID
amountnumber退款金额(BRL)——等于原始 PIX 金额(全额退款)或更小(部分退款),不得超过
reasonstring退款原因 kebab-case slug(见下表)
identifierstring退款标识符(最多 38 个字符 [A-Za-z0-9._-])。省略时自动生成
descriptionstring自由格式描述(最多 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 状态反映结果:200COMPLETED)、422FAILED)、202TIMEOUT/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(登记后)
statusCOMPLETEDFAILEDTIMEOUTPENDINGPROCESSING
errorCode / errorReasonFAILED 时填充

响应中没有 refundId/amount/currency 字段 —— 请使用 paymentId, 并通过账单或 webhook 跟踪最终结果。

部分退款

amount 为必填,决定退还给付款人的金额:填写原始 PIX 全额即为全额退款, 填写更小的金额即为部分退款。若超过原始金额,API 返回 400 refund_amount_exceeded,且不会发起退款。

同一笔 PIX 可以分多次退款,累计不超过原始金额。这里有两条重要规则:

  • 每次退款都需要各自的 Idempotency-Keyidentifier 重复使用其中 任意一个,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 可以在以下位置找到:

  1. 收款 webhook 响应中
  2. 收款查询 在付款后
  3. 账户对账单(Statement)
  4. 付款方的收据

示例:从 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_fields400缺少 originalEndToEndamount两个字段都要提供
invalid_payload400reason 不在封闭列表中,或 JSON 格式错误使用上表中的 slug
refund_amount_exceeded400amount 大于原始 PIX,或大于剩余可退余额在账单中确认已退金额
original_transaction_not_found404清算行未找到该 E2E检查 originalEndToEnd
conflict409交易已全额退款在账单中检查历史记录
insufficient_funds422退款余额不足向账户充值
policy_denied422tenant/账户的策略规则拒绝了该退款查看响应体中的 violations —— 策略与规则
partner_rejected422清算行拒绝(包括超过 90 天期限)查看 partner 区块中说明的原因
partner_error502在清算行查询原始交易失败请重试;若持续出现请联系客服

完整列表见错误

最佳实践

  1. 保存所有已收交易的 E2E
  2. 使用 Idempotency Key 以避免重复退款 —— 同一笔 PIX 的每次部分退款都要使用不同的 Key(以及 identifier
  3. 在申请下一次部分退款前,先在账单中确认 该笔 PIX 已退多少
  4. 记录退款原因 以便审计
  5. 配置 webhooks 以跟踪状态
  6. 保留退款历史 用于对账

后续步骤