付款(Withdrawals / Saque)
产品术语为 Saque(
payout);当前端点/v1/withdrawals是目前使用中的线路名称(wire format),尚未重命名为/v1/payouts。
将余额从您的 Liqfy 钱包转出到现实世界中的目的地——PIX 密钥(巴西)或银行账户(TED)。这与 PIX 支付 相反:支付会为您的钱包入账,付款则从钱包扣款。
**按订单号查询:**创建出款时,将订单号作为 Idempotency-Key 发送。之后使用同一账户的 API 密钥调用 GET /v1/withdrawals/by-idempotency-key/{订单号}。未使用该密钥创建的出款无法按订单号查询。
凭证:GET /v1/withdrawals/{id}/receipt?format=json 返回结构化数据。省略 format 时,仍返回 {contentType, base64} 格式的 PDF 响应。
确认 E2E 后,payout.paid 回调可在 data.object.settlement.end_to_end_id 中携带 Pix E2E。拆分出款应查看 settlement.legs[] 中各段的 E2E;缺少 E2E 不代表出款失败。
通道按账户开通。 TED 取决于是否为您启用了相应模块。在基于其中任一通道进行开发之前,请先与您的 Liqfy 联系人确认。
#流程概览
1. POST /v1/withdrawals/validate-pix-key (optional — pre-flight)
2. POST /v1/withdrawals (creates the request and reserves the funds right away)
3. Liqfy dispatches — automatically or after approval
4. Webhook payout.paid (or payout.failed) hits your endpoint付款使用与收款相同的 API 密钥——Authorization: Bearer <key>,从您的服务器调用,切勿从终端客户的浏览器或应用调用。(仍接受 apikey 请求头。)API 密钥请求同样受您账户的 IP 白名单约束。钱包在创建时即被扣款;付款是否还需要审批取决于您的账户设置。
创建时务必发送 Idempotency-Key 请求头——它是主要的幂等通道(参见创建付款)。
#1. 校验 PIX 密钥(推荐)
在创建付款之前,请检查目标密钥格式是否正确。
POST /v1/withdrawals/validate-pix-key
{
"key": "12345678909",
"type": "CPF"
}响应 201 Created
{
"isValid": true,
"type": "CPF",
"normalized": "12345678909"
}支持的 type 值
| 类型 | 格式 |
|---|---|
CPF | 11 位数字(去除点和短横线),mod-11 校验和。所有数字均相同的号码会被拒绝。 |
CNPJ | 14 位数字(去除点、短横线和斜杠),mod-11 校验和。所有数字均相同的号码会被拒绝。 |
EMAIL | local@domain.tld 格式,转为小写,最多 77 个字符。 |
PHONE | +55 后跟 10 或 11 位数字(+5511999999999)。去除空格、短横线和括号。 |
RANDOM | 随机密钥——UUID v4,转为小写。 |
| (省略) | 根据密钥值自动检测。 |
类型不区分大小写。声明的已知类型会被严格校验——为电子邮件声明 CPF 会失败。声明任何其他类型(例如 EVP)会被忽略:系统自动检测密钥,响应中报告检测到的类型。
自动检测顺序: UUID v4 → RANDOM;以 +55 开头 → PHONE;电子邮件格式 → EMAIL;11 位数字 → CPF;14 位数字 → CNPJ。因此,不带 +55 发送的电话号码(11 位数字)会被识别为 CPF——请以 E.164 格式发送电话号码,或声明 PHONE。当没有任何匹配时,返回 isValid: false,以 type: "CPF" 作为占位符,并带有 error: "Unable to detect PIX key type"。
即使密钥无效,该端点也返回 201——失败信息位于响应体中,绝不体现在 HTTP 状态码上。只有缺失或为空的 key 才会返回 400。
失败 201 Created
{
"isValid": false,
"type": "CPF",
"normalized": "12345678900",
"error": "CPF checksum invalid"
}可能的 error 值
error | 类型 |
|---|---|
CPF must be 11 digits / CPF checksum invalid | CPF |
CNPJ must be 14 digits / CNPJ checksum invalid | CNPJ |
Invalid email format / Email exceeds 77 characters | EMAIL |
Phone must start with +55 / Phone must have 10 or 11 digits after +55 | PHONE |
Random key must be a valid UUID v4 | RANDOM |
Unable to detect PIX key type | 自动检测失败 |
PIX key must not be empty | 仅含空白字符的密钥 |
#2. 报价、手续费与可提现余额
三个只读辅助接口,使用与创建端点相同的 API 密钥。所有接口中的 currency 均为可选(默认 BRL)。
#报价——需要发送多少,收款方才能收到确切金额
POST /v1/withdrawals/quote——请求体 { value, currency? },value 为大于零的整数。按 PIX 定价。请求体无效 → 400。
响应 201 Created
{
"value": 50000,
"fee": 100,
"total": 50100
}total 是您需要支付的总额,以便收款方恰好收到 value——手续费会被加计到总额中,目的地永远不会承担手续费。
curl -X POST https://api.liqfy.com.br/v1/withdrawals/quote \
-H "Authorization: Bearer $LIQFY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "value": 50000 }'import { LiqfyClient } from '@liqfy/node';
const client = new LiqfyClient({ apiKey: process.env.LIQFY_API_KEY! });
const quote = await client.payouts.quote({ value: 50000 });Python client.payouts.quote(value=50000),PHP $client->payouts->quote(50000),.NET client.Payouts.QuoteAsync(50000)。
#手续费——创建时将收取的费用
GET /v1/withdrawals/payout-fee
| 查询参数 | 必填 | 说明 |
|---|---|---|
amount | 是 | 整数,1 至 10.000.000.000(最小货币单位)。 |
currency | 否 | 默认 BRL。3 至 8 个字符。 |
type | 否 | PIX(默认)或 TED。 |
任何超出这些范围的值 → 400。
响应 200 OK
{
"amount": 50000,
"currency": "BRL",
"fee": 100,
"total": 50100
}fee 是 POST /v1/withdrawals 对该金额将收取的费用(已包含超出 PIX 上限部分的拆分分段补充费用);total = amount + fee。
curl "https://api.liqfy.com.br/v1/withdrawals/payout-fee?amount=50000¤cy=BRL&type=PIX" \
-H "Authorization: Bearer $LIQFY_API_KEY"const fee = await client.payouts.payoutFee({ amount: 50000 });Python client.payouts.payout_fee(amount=50000),PHP $client->payouts->payoutFee(50000),.NET client.Payouts.PayoutFeeAsync(50000)。
#可提现余额与手续费参数
GET /v1/withdrawals/payout-info——无副作用,专为“全部提现”按钮而设计。
响应 200 OK
{
"currency": "BRL",
"available": 1000000,
"pendingAdjustment": 0,
"fee": { "fixed": 100, "variablePct": 0, "minimum": 100 },
"maxWithdrawable": 999900
}available 是可用余额。maxWithdrawable 是已计入手续费后可申请的最大总额。fee 是当前适用的参数集(fixed、variablePct、minimum)。
curl "https://api.liqfy.com.br/v1/withdrawals/payout-info?currency=BRL" \
-H "Authorization: Bearer $LIQFY_API_KEY"const info = await client.payouts.payoutInfo();Python client.payouts.payout_info(),PHP $client->payouts->payoutInfo(),.NET client.Payouts.PayoutInfoAsync()。
#3. 创建付款
POST /v1/withdrawals
幂等性。 发送 Idempotency-Key 请求头——这是主要通道,会去除首尾空白,最多 255 个字符(更长的请求头 → 400 "Idempotency-Key must be at most 255 characters")。请求体字段 idempotencyKey(1 至 255 个字符)是供非 SDK 调用方使用的备用方式;两者同时存在时以请求头为准。相同的密钥返回相同的付款:再次返回 201,不会第二次扣款。如果预留失败,该记录会被标记为 REJECTED,且该密钥会被释放——充值后您可以使用同一密钥重试。
如果不提供密钥,唯一的保护是近似重复防护:90 秒内相同的 type、amount 和 pixKey 会返回 409,且没有稳定的 error.code。发送幂等密钥,您就永远无需依赖此防护。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
type | enum | 是 | PIX 或 TED。(CRYPTO 存在,但仅限控制台使用——见下文。) |
amount | integer | 是 | 正整数,最小货币单位。在默认的 gross 模式下,这是收款方收到的金额;手续费另行扣除。 |
currency | string | 否 | 默认 BRL。 |
pixKey | string | PIX 时必填 | 目标 PIX 密钥。 |
pixKeyType | enum | 否 | CPF、CNPJ、EMAIL、PHONE、RANDOM。省略或未知值(例如 EVP):忽略,自动检测密钥。 |
bankCode | string | TED 时必填 | 银行代码(FEBRABAN)。 |
bankAgency | string | TED 时必填 | 支行(agência)。 |
bankAccount | string | TED 时必填 | 账号。 |
walletId | string | 否 | 在 currency 中显式指定的可用 OPERATIONAL 钱包。省略 → 自动选择(若该币种的默认钱包有余额则使用它,否则使用任一余额充足的可用钱包)。未知 → WALLET_NOT_FOUND;不可用 → WALLET_NOT_SPENDABLE;没有钱包能覆盖扣款 → INSUFFICIENT_BALANCE。 |
amountType | enum | 否 | gross(默认)或 net。net 为旧版选项,仍被接受:扣款为 amount,收款方收到 amount − fee(fee >= amount → 400)。 |
idempotencyKey | string | 否 | 备用方式——优先使用 Idempotency-Key 请求头。 |
totpCode | string | 否 | 仅限控制台:当账户要求提现进行 2FA 时的 2FA 验证码。API 密钥请求中会被忽略。 |
未知字段(description、cryptoAddress、cryptoNetwork、cryptoCurrency 及其他任何字段)会被静默剔除——API 从不存储或返回它们。cryptoAddress、cryptoNetwork 和 cryptoCurrency 仍可能作为只读的旧版响应字段出现;它们不是创建输入。
加密货币付款仅限控制台。
type: "CRYPTO"(连同cryptoWalletAddressId和cryptoEstimateId)仅接受已登录的控制台用户发起;使用 API 密钥时返回403,并带有令牌CRYPTO_PANEL_ONLY。POST /v1/withdrawals/crypto/estimate同理;GET /v1/withdrawals/crypto/availability对 API 密钥返回{ "enabled": false }。在控制台中,加密货币付款必须使用BRL,金额不低于 R$ 5.000,00(500000),不能为net,且必须提供两个 id(否则返回400INVALID_CRYPTO_WITHDRAWAL),并且始终要求 2FA 验证码。
示例——PIX 付款
curl -X POST https://api.liqfy.com.br/v1/withdrawals \
-H "Authorization: Bearer $LIQFY_API_KEY" \
-H "Idempotency-Key: payout-2026-W17" \
-H "Content-Type: application/json" \
-d '{
"type": "PIX",
"amount": 50000,
"pixKey": "12345678909",
"pixKeyType": "CPF"
}'示例——TED 付款(银行信息为三个扁平字符串)
curl -X POST https://api.liqfy.com.br/v1/withdrawals \
-H "Authorization: Bearer $LIQFY_API_KEY" \
-H "Idempotency-Key: payout-2026-W17-ted" \
-H "Content-Type: application/json" \
-d '{
"type": "TED",
"amount": 50000,
"bankCode": "001",
"bankAgency": "1234",
"bankAccount": "56789012"
}'const payout = await client.payouts.create(
{ type: 'PIX', amount: 50000, pixKey: '12345678909', pixKeyType: 'CPF' },
{ idempotencyKey: 'payout-2026-W17' },
);
// TED: { type: 'TED', amount: 50000, bankCode: '001', bankAgency: '1234', bankAccount: '56789012' }Python client.payouts.create(input, idempotency_key=…),PHP $client->payouts->create($input, $idempotencyKey),.NET client.Payouts.CreateAsync(input, idempotencyKey)。
响应 201 Created
{
"id": "f6a7b8c9-d0e1-4234-9f01-234567890123",
"type": "PIX",
"status": "PENDING",
"amount": 50000,
"fee": 100,
"netAmount": 50000,
"currency": "BRL",
"source": "API",
"walletId": "2c9f8e7d-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
"pixKey": "12345678909",
"pixKeyType": "CPF",
"idempotencyKey": "payout-2026-W17",
"createdAt": "2026-04-25T16:10:00.000Z",
"updatedAt": "2026-04-25T16:10:00.000Z"
}钱包在创建时即被扣款。 在 gross 模式(默认)下,扣款为 amount + fee(此处为 50.100),收款方恰好收到 amount——这就是 netAmount 等于 amount 的原因。资金从此刻起被预留;审批只决定付款何时发出。
201 返回时状态可能已经是 APPROVED 或 PROCESSING:当您的账户策略允许时,自动付款会立即审批并发出。“总是以 PENDING 开始”并无保证。
当付款未能完成时。 完整的拒绝约定—— 即时余额拒绝时的
error.code、失败代码(failure_code),以及 其中哪些会自动退款——请参见 付款失败。
#从控制台创建
- 只有账户所有者或管理员可以在控制台中创建付款(普通成员会收到
403,code=WITHDRAWAL_CANCEL_ROLE_REQUIRED)。 - 当账户要求提现进行 2FA 时(加密货币始终要求),请求需要一个新的
totpCode。未启用 2FA 的用户会收到403("Esta conta exige 2FA para saques…");验证码缺失或无效时返回401("Código 2FA inválido ou ausente.")。 - 在控制台中创建的付款带有
source: "PANEL";通过 API 密钥创建的则为source: "API"。
#被拒绝的请求会留下记录
POST /v1/withdrawals 的每一次 4xx 拒绝(余额、KYC、校验、限额、规则……)都会以 WITHDRAWAL_REJECTED 记录到账户的审计日志中,并显示在提现页面上,包括金额、来源和原因——例如 "Pedido de saque de R$ 500,00 recusado: saldo insuficiente (disponível R$ 120,00), via API"。使用相同幂等密钥且拒绝代码相同的重复请求,每小时只记录一次。IP 白名单造成的拒绝发生在此步骤之前,不会在此记录。
#4. 生命周期
PENDING ─▶ APPROVED ─▶ PROCESSING ─▶ CONFIRMING ─▶ COMPLETED ✓ funds delivered
└▶ PARTIALLY_COMPLETED delivered in parts终态结果还包括 FAILED、REJECTED、CANCELLED 和 REVERSED。共有十种状态;其中六种终态(COMPLETED、PARTIALLY_COMPLETED、FAILED、REJECTED、CANCELLED、REVERSED)不会再发生变化。
| 状态 | 对钱包的影响 |
|---|---|
PENDING | 创建时扣款(预留金额 + 手续费) |
APPROVED | 已预留——已审批,等待发出 |
PROCESSING | 已预留——已发送结算 |
CONFIRMING | 已预留——等待收款机构确认 |
COMPLETED | 已扣款(终态)——已送达 |
PARTIALLY_COMPLETED | 已扣款(终态)——部分分段已送达,其他分段失败(参见 legs);失败的分段会退款 |
FAILED | 自动退款——发出失败(failure_code)。退款可能会被暂扣直至确认(参见付款失败) |
REJECTED | 已退款——在审核中被拒绝,或因预留失败被拒绝(system:reserve-failed) |
CANCELLED | 已退款(金额 + 手续费)——在发出前由您取消,或在管理员停用账户时取消(原因为 "Cancelado pelo admin; valor devolvido ao saldo") |
REVERSED | 已送达,随后被收款方退回(reversalReason、reversalAmount、reversalStatus)。只有品牌启用此功能时,退回的金额才会自动入账——参见被退回的付款 |
REJECTED 并不只表示“管理员拒绝”:预留失败的创建请求也会被标记为 REJECTED,资金会被退回。
不确定的发出会保持 PROCESSING。 当调用服务商超时时,PIX 可能已发出,也可能未发出。付款(或分段)会保持 PROCESSING,同时 Liqfy 向服务商进行确认——只有在有确凿证据表明 PIX 未发出时,才会将其标记为失败并退款。当该检查证实这一点时,失败消息为 "Saque não efetivado pelo provedor. O valor foi devolvido ao saldo."
#创建响应体之外的响应字段
GET /v1/withdrawals/{id}、列表和取消响应会额外包含:
| 字段 | 说明 |
|---|---|
legs[] | { id, legIndex, amount, status, endToEndId, failureCode, refunded, reversalCredited, reversalEndToEndId, reversedAmount, reversedAt, createdAt, updatedAt }。超过单笔上限的 PIX 付款会在审批时被拆分为 N 个分段;legIndex 从 1 开始。被内部重新发出所替代的分段不会列出。 |
legSummary | 基于 legs 的汇总:{ count, paidOut, returned, awaitingReturn, pendingDecision, inFlight, total }。 |
recipientName | 结算时服务商报告的账户持有人姓名(优先取已完成的分段),如有。 |
reversalReason、reversalAmount、reversalStatus | 当付款被退回时出现。 |
分段字段
status——PENDING、PROCESSING、COMPLETED、FAILED或REVERSED。endToEndId——该分段自身的 PIX E2E,用于与银行对账单核对。failureCode——取自一个封闭集合,绝不是服务商原文:INVALID_PIX_KEY、ACCOUNT_CLOSED、ACCOUNT_BLOCKED、KYC_REJECTED、LIMIT_REJECTED、DESTINATION_UNAVAILABLE、DESTINATION_NOT_ALLOWED、INSUFFICIENT_BALANCE、TIMEOUT、PROVIDER_CANCELLED、PROVIDER_REJECTED、UNKNOWN。分段未失败时为null。refunded——仅适用于FAILED分段:退款入账实际记入账本后(分段退款或整笔付款退款)为true。false表示退款仍被暂扣。reversalCredited——仅适用于REVERSED分段:退回金额已记入您的余额后为true。reversalEndToEndId、reversedAmount、reversedAt——REVERSED分段的退回详情。
legSummary
| 字段 | 求和对象 |
|---|---|
paidOut | COMPLETED 分段——已到达目的地的金额。 |
returned | 已退款的 FAILED 分段 + 已入账的 REVERSED 分段。仅含分段金额:当整笔付款退款时,退回的手续费不计入此处。 |
awaitingReturn | 退款尚未到账的 FAILED 分段。 |
pendingDecision | 退回金额尚未记入您账户的 REVERSED 分段。 |
inFlight | PENDING / PROCESSING 分段。 |
total | 所有分段——等于付款的 netAmount。 |
#被退回的付款
当收款方退回一笔已支付的 PIX 时,一旦退回在服务商对账单中得到确认,该分段即变为 REVERSED(仅接受退回整个分段金额)。当所有有效分段都被退回时,付款变为 REVERSED;若部分分段被退回而其他分段未被退回,付款保持原状态,被退回的分段显示 REVERSED。
退回的资金会回到 Liqfy,而不是直接回到您的钱包。只有当您的品牌启用了该功能,且该退回未被标记为欺诈或可疑(代码 BE08、FR01)时,才会扣除手续费后自动记入您的余额;否则由人工决定入账或保留。请关注 legs[].reversalCredited 和 legSummary.pendingDecision。
reversalReason 对 BACEN 退回代码使用以下标签:
| 代码 | 标签 |
|---|---|
BE08 | Devolução por suspeita de fraude |
FR01 | Conta do recebedor sob suspeita de fraude |
MD06 | Devolução solicitada pelo pagador |
AC03 | Chave/conta do recebedor inválida |
AC04 | Conta do recebedor encerrada |
AC06 | Conta do recebedor bloqueada |
AM09 | Valor incorreto |
SL02 | Devolução por solicitação do participante |
DUPL | Pagamento em duplicidade |
| 其他 | Devolução PIX (<code>),无代码时为 Devolução PIX |
#取消待处理的付款
POST /v1/withdrawals/{id}/cancel——可选请求体 { "reason": "..." }(去除首尾空白,最多 500 个字符;默认 "Cancelado pelo lojista.")。鉴权方式与创建端点相同。接受普通 id 或 po_ id。
- 仅当付款处于
PENDING时(尚未发出任何款项)。付款变为CANCELLED,amount + fee在同一事务中退回钱包,结果会触发下方的 webhook。返回200及付款(与查询结构相同)。 - 已审批、已发出或已处于终态 →
409,code=WITHDRAWAL_NOT_CANCELLABLE。只有我们的支持团队才能取消的记录(来源为MANUAL、高于人工审批下限、非 BRL)也会返回409:请通过支持团队取消。 - 在控制台中,只有账户所有者或管理员可以取消(普通成员会收到
403,code=WITHDRAWAL_CANCEL_ROLE_REQUIRED)。通过 API 时,账户密钥即可。账户会收到一封“Withdrawal cancelled”邮件。 - 其他账户的付款 →
404——且404从不确认该 id 是否存在。
curl -X POST https://api.liqfy.com.br/v1/withdrawals/f6a7b8c9-d0e1-4234-9f01-234567890123/cancel \
-H "Authorization: Bearer $LIQFY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "reason": "Duplicate request" }'await client.payouts.cancel('f6a7b8c9-d0e1-4234-9f01-234567890123', { reason: 'Duplicate request' });Python client.payouts.cancel(id, reason=…),PHP $client->payouts->cancel($id, $reason),.NET client.Payouts.CancelAsync(id, reason)。
#凭证
GET /v1/withdrawals/{id}/receipt——不仅适用于 COMPLETED:每种终态都有对应的文档(COMPLETED、PARTIALLY_COMPLETED、FAILED、REJECTED、CANCELLED、REVERSED)。非终态 → 400。可选 format:pdf(默认)或 json;任何其他值 → 400。
响应 200 OK
{
"contentType": "application/pdf",
"base64": "JVBERi0xLjQKJcTl8uXrp/Og0MTGCg=="
}只有 COMPLETED 的标题为 "Comprovante de Transferência PIX";其他文档记录处理结果,并声明其不是付款证明:
| 状态 | 标题 | 金额标签 |
|---|---|---|
COMPLETED | Comprovante de Transferência PIX | Valor transferido |
PARTIALLY_COMPLETED | Transferência Parcialmente Concluída | Valor solicitado |
FAILED | Transferência Não Realizada | Valor solicitado |
REJECTED | Transferência Não Aprovada | Valor solicitado |
CANCELLED | Transferência Cancelada | Valor solicitado |
REVERSED | Transferência Devolvida | Valor da transferência |
只有当该笔入账在账本中存在时,文档才会提及金额已退回您的余额——未退款的已取消付款绝不会声称已退款。BACEN E2E 仅出现在已支付的文档中;服务商的交易 id 从不出现。CPF/CNPJ 会被掩码处理;只有在收款方姓名和证件均缺失时才会显示目标 PIX 密钥。只有被认定为可安全展示给客户的原因(密钥无效、持有人数据不符、限额、目标账户不符合条件、取消、一般性不可用)才会显示原因行;服务商的原始消息绝不会出现在文档中。
curl https://api.liqfy.com.br/v1/withdrawals/f6a7b8c9-d0e1-4234-9f01-234567890123/receipt \
-H "Authorization: Bearer $LIQFY_API_KEY"const receipt = await client.payouts.receipt('f6a7b8c9-d0e1-4234-9f01-234567890123');Python client.payouts.receipt(id),PHP $client->payouts->receipt($id),.NET client.Payouts.ReceiptAsync(id)。
#5. Webhook
订阅 payout.created、payout.approved、payout.paid 和 payout.failed。所有事件均使用带版本的 evt_ 信封和带时间戳的签名。审批表示 processing,发生在结算之前。参见 Webhook。
{
"id": "evt_5f3a9b2c1d4e5f6a7b8c9d0e1f2a3b4c",
"object": "event",
"api_version": "2026-07-23",
"type": "payout.paid",
"created_at": "2026-04-25T16:11:42.000Z",
"data": {
"object": {
"id": "po_f6a7b8c9-d0e1-4234-9f01-234567890123",
"object": "payout",
"status": "paid"
}
}
}data.object.status 使用公开词汇:pending、processing、paid、failed。FAILED、REJECTED 和 CANCELLED 都会以 payout.failed 送达,并带有 status: "failed"。
payout.failed 在可用时携带 data.object.failure_code 和 data.object.failure_message。请使用稳定代码来决定如何处理。destination_not_allowed 表示服务商拒绝了该目的地类型;只能使用其他 Pix 密钥类型或目的地重试。参见付款失败。
#6. 列出您的付款
GET /v1/withdrawals——使用与创建端点相同的 API 密钥。
| 查询参数 | 默认值 | 说明 |
|---|---|---|
page | 1 | 页码(整数;其他任何值 → 400)。 |
limit | 20 | 整数。硬性上限为 100——更大的值会被静默调低,不报错。 |
status | — | 任一词汇的 CSV(见下文)。未知令牌 → 400("Invalid withdrawal status: …")。 |
source | — | API、PANEL、MANUAL 或 INDEFINIDO(无来源的记录)。其他任何值都会被静默忽略,列表不会被过滤。 |
order | desc | 按创建日期排序。asc 表示最早的在前;其他任何值均视为 desc。 |
idempotency_key | — | 精确密钥,去除首尾空白后为 1 至 255 个字符(否则 400)。零个或一个结果。 |
status 中两种词汇均被接受,响应中的线路值是内部大写值。小写的公开词会展开为对应的集合;其他任何令牌则不区分大小写地与内部状态匹配(PROCESSING = 仅 PROCESSING,而 processing = APPROVED、PROCESSING 和 CONFIRMING;reversed = REVERSED)。
| 公开过滤值 | 内部线路值 |
|---|---|
pending | PENDING |
processing | APPROVED、PROCESSING、CONFIRMING |
paid | COMPLETED、PARTIALLY_COMPLETED |
failed | FAILED、REJECTED、CANCELLED |
| (无) | REVERSED |
curl "https://api.liqfy.com.br/v1/withdrawals?page=1&limit=20&status=paid&source=API&order=desc" \
-H "Authorization: Bearer $LIQFY_API_KEY"const page = await client.payouts.list({ limit: 20, status: 'paid', page: 1, source: 'API', order: 'desc' });Python client.payouts.list(limit=…, status=…, page=…, source=…, order=…),PHP $client->payouts->list([...]),.NET client.Payouts.ListAsync(...)。
响应 200 OK
{
"data": [
{
"id": "f6a7b8c9-d0e1-4234-9f01-234567890123",
"type": "PIX",
"status": "COMPLETED",
"amount": 50000,
"fee": 100,
"netAmount": 50000,
"currency": "BRL",
"source": "API",
"completedAt": "2026-04-25T16:11:42.000Z",
"recipientName": "Maria Silva",
"legs": [
{
"id": "c1d2e3f4-0000-0000-0000-000000000001",
"legIndex": 1,
"amount": 50000,
"status": "COMPLETED",
"endToEndId": "E12345678202604251611abcdef123456",
"failureCode": null,
"refunded": false,
"reversalCredited": false
}
],
"legSummary": { "count": 1, "paidOut": 50000, "returned": 0, "awaitingReturn": 0, "pendingDecision": 0, "inFlight": 0, "total": 50000 },
"...": "..."
}
],
"total": 17,
"page": 1,
"limit": 20
}#7. 限额与规则
- PIX 单笔上限——默认为 R$ 15.000,00(平台设置)。超过上限时,付款会在审批时被拆分为 N 个
legs:每个分段填满至上限,余额放在最后一个分段(R$ 110.000,00 → 7 × R$ 15.000,00 + 1 × R$ 5.000,00)。每个分段都是独立的 PIX,拥有各自的 E2E,并且可以独立失败。 - 账户提现上下限——每次请求
minWithdrawalAmount/maxWithdrawalAmount,每日dailyPayoutMaxAmount/dailyPayoutMaxCount(null = 无限制)。超出范围时返回AMOUNT_BELOW_MINIMUM、AMOUNT_ABOVE_MAXIMUM或DAILY_PAYOUT_LIMIT_EXCEEDED。 - 钱包必须覆盖金额 + 手续费——从不进行部分扣款;请求会被直接拒绝。
- 审批——金额达到或超过
manualApprovalThresholdCents(默认 R$ 15.001,00——比 PIX 上限高一分钱,因此任何不超过上限的单段 PIX 都可以自动审批)的付款、所有非 BRL 付款以及被送入人工审核的记录都需要审批。自动付款属于账户策略(autoPayoutEnabled、autoWithdrawPct——余额百分比门槛,默认 50、允许自动付款的类型、自动付款上限,以及是否所有付款都需要人工审批)——请联系支持团队审查您的策略。符合条件的付款会在创建时数秒内发出;每 5 分钟运行一次的扫描会按相同策略重新检查仍处于PENDING的付款。 - 频率制动——账户中异常密集的付款,或多个账户在短时间内向同一 PIX 密钥付款,可能会使付款转入人工审批而非自动付款。它从不拒绝付款。
- 提现规则——平台规则可以拒绝付款(拒绝时带有
ruleId和reasonKey:withdrawal.rule.pixKeyTypeNotAllowed或withdrawal.rule.notAllowed)或要求对其进行审批。 - TED——仅限巴西银行(FEBRABAN
bankCode列表)。结算:若在 BRT 16:30 之前审批,则于同一工作日结算。
#错误代码
请根据 error.code 进行分支处理。message 用于您的日志;代码才是约定。例外:部分令牌(WALLET_NOT_FOUND、WALLET_NOT_SPENDABLE、TENANT_KYC_REQUIRED、CRYPTO_PANEL_ONLY)是纯消息文本——对应行显示备用值 error.code,您需要在 error.message 中匹配该令牌。完整对照:错误。
| HTTP | error.code | 触发场景 |
|---|---|---|
| 400 | INSUFFICIENT_BALANCE | 没有钱包能覆盖扣款(details:available、requested、currency)。此路径返回 400——而非 422。 |
| 400 | invalid_request | 显式指定的 walletId 未知、未激活、币种不同或不可用。error.message 中的令牌:WALLET_NOT_FOUND / WALLET_NOT_SPENDABLE。 |
| 400 | invalid_request | 请求体校验失败、Idempotency-Key 超过 255 个字符、status 过滤值无效,或查询时幂等密钥无效。 |
| 400 | AMOUNT_BELOW_MINIMUM / AMOUNT_ABOVE_MAXIMUM | 超出账户的提现上下限。 |
| 422 | DAILY_PAYOUT_LIMIT_EXCEEDED | 已达到账户的每日金额或次数上限。 |
| 403 | account_suspended | 账户已被暂停或冻结。 |
| 403 | forbidden | 账户 KYC 未激活(启用 KYC 门槛时)。error.message 中的令牌:TENANT_KYC_REQUIRED。 |
| 403 | forbidden | 使用 API 密钥调用了 type: "CRYPTO"(或加密货币估算)。error.message 中的令牌:CRYPTO_PANEL_ONLY。 |
| 403 | WITHDRAWAL_CANCEL_ROLE_REQUIRED | 账户成员身份不是 OWNER/ADMIN:创建或取消提现、钱包转账,或创建、更新、删除已保存的提现目的地。API 密钥法币付款保持现有访问权限。 |
| 404 | not_found | 未知 id,或属于其他账户的付款——404 从不确认该 id 是否存在。 |
| 409 | WITHDRAWAL_NOT_CANCELLABLE | 取消非 PENDING 状态的付款,或只有支持团队才能取消的记录。 |
| 409 | (无稳定代码) | 未提供密钥的创建请求在 90 秒内近似重复。请发送 Idempotency-Key 后重试。 |
#常见问题
问:我创建了一笔付款,但它一直停留在 PENDING。
答:它正在等待审批——即时发出仅涵盖您的账户策略所允许的情况。常见原因:账户未开启自动付款、该类型不支持自动付款(默认仅 PIX)、金额超过自动付款上限或达到/超过 manualApprovalThresholdCents(默认 R$ 15.001,00)、余额门槛(autoWithdrawPct)、频率制动或要求审批的规则。请通过控制台审批,或向支持团队咨询自动付款。
问:我的付款 FAILED——我被收取手续费了吗?
答:没有。FAILED 会触发自动、原子性的钱包退款 amount + fee。退款在钱包变动发生时即到账;当 failure_message 为 "Estamos confirmando com o banco; você será avisado." 时,退款被暂扣(legs[].refunded 为 false)——资金尚未退回,请等待入账和通知。
问:我的付款被 REVERSED——资金已经回到我的余额了吗?
答:不一定。只有当您的品牌启用了该功能且该退回未被标记为欺诈时,退回金额才会扣除手续费后自动入账;否则需等待决定。请检查 legs[].reversalCredited 和 legSummary.pendingDecision。
问:我可以取消付款吗?
答:仅在 PENDING 期间可以,使用 POST /v1/withdrawals/{id}/cancel 或控制台中的 Cancel withdrawal 按钮。一旦审批通过,资金即处于在途状态。
问:我的 CNPJ 密钥被判定为无效,但我的银行接受它。 答:系统强制执行 mod-11 校验和,且没有绕过参数。如果您的密钥未通过校验,请联系支持团队。
问:我的电话密钥被识别为 CPF。
答:如果没有 +55,11 位的电话号码在自动检测中看起来像 CPF。请以 +55… 格式发送电话号码,或声明 type: "PHONE"。
问:我的下拉列表中没有 TED 银行。 答:我们使用 Bacen 的 FEBRABAN 代码列表。如有代码缺失,请提交工单——通常会在 24 小时内修复。
#结算标识符与查询
只有当存在有效的 BACEN Pix E2E 时,charge.paid 或 payout.paid 才可能包含 data.object.settlement.end_to_end_id。服务商交易 ID 不是 E2E。对于多分段付款,单个顶层标识符不能替代各个分段;当存在多个有效分段时,JSON 凭证会在已完成的分段上提供有效的 E2E。缺少 E2E 并不意味着付款失败。
已支付 webhook 的保留功能由每个商户自行选择开启。严格保留可防止在没有 E2E 的情况下投递,但如果服务商始终不提供 E2E,可能会无限期地暂扣 webhook;钱包入账不会等待。若要获得实际保证,请将路由限制为已验证支持 E2E 的路由。定时释放可能在没有 E2E 的情况下投递,因此不属于严格保证。
使用 GET /v1/charges/by-idempotency-key/{key} 或 GET /v1/withdrawals/by-idempotency-key/{key} 查询由您的集成创建的资源;请对密钥进行百分号编码。对于 /、?、# 或空格,请改用带 URL 编码的列表查询 ?idempotency_key=。列表在您的账户内包含零个或一个匹配项。收款必须提供密钥;请为每笔付款都发送密钥,因为没有密钥的付款无法通过这种方式查到。在预留阶段被拒绝的付款会释放其密钥,无法通过该密钥查到。
付款查询、取消和凭证接受来自 webhook 的 po_ ID。GET /v1/withdrawals/{id}/receipt?format=json 为所有终态结果返回结构化数据:已完成、部分完成、失败、被拒绝、已取消和已退回。只有已完成才是付款证明。非终态付款返回 400。默认仍为 PDF 信封 {contentType, base64};Accept 不决定格式。文档会进行掩码处理,只有在收款方姓名和证件均缺失时才会显示 Pix 密钥。
#查询示例
以下示例在 API_URL 中使用您的 API 源地址,在 API_KEY 中使用您的服务端密钥。密钥去除首尾空白后必须包含 1–255 个字符;空密钥或更长的密钥返回 400。当没有资源属于您的账户时(包括其他账户使用了相同密钥的情况),路径查询返回中性的 404。列表过滤返回正常的列表信封,包含零个或一个条目。
# API_URL is the API origin; API_KEY is your server-side key.
curl "$API_URL/v1/charges/by-idempotency-key/order-42" \
-H "Authorization: Bearer $API_KEY"
curl "$API_URL/v1/withdrawals/by-idempotency-key/order-42" \
-H "Authorization: Bearer $API_KEY"
# URL encoding is especially useful for keys containing /, ?, #, or spaces.
curl --get "$API_URL/v1/charges" \
-H "Authorization: Bearer $API_KEY" \
--data-urlencode "idempotency_key=order/42 ?#"
curl --get "$API_URL/v1/withdrawals" \
-H "Authorization: Bearer $API_KEY" \
--data-urlencode "idempotency_key=order/42 ?#"
curl "$API_URL/v1/withdrawals/po_f6a7b8c9-d0e1-4234-9f01-234567890123/receipt?format=json" \
-H "Authorization: Bearer $API_KEY"#JSON 凭证约定
以下响应展示了一笔已完成的 Pix 付款。金额以货币的最小单位表示(150000 表示 R$1,500.00)。凭证文本为葡萄牙语,与 PDF 相同;issuer 和页脚取决于品牌和处理结果。
{
"object": "payout_receipt",
"payout_id": "po_f6a7b8c9-d0e1-4234-9f01-234567890123",
"status": "paid",
"outcome": "completed",
"is_payment_proof": true,
"title": "Comprovante de Transferência PIX",
"amount": 150000,
"amount_label": "Valor transferido",
"currency": "BRL",
"transferred_at": "2026-10-28T14:33:02.000Z",
"end_to_end_id": "E12345678202610281433Zx9Yw8Vu7Ts",
"payer": { "name": "Example Store", "document": "12.345.678/****-**" },
"receiver": { "name": "Maria da Silva", "document": "***.456.789-**", "pix_key": null },
"refunded_to_balance": false,
"what_happened": "A transferência foi concluída com sucesso.",
"what_to_do": null,
"reason": null,
"legs": null,
"issuer": "Example Brand",
"footer": "O identificador E2E acima é registrado no Banco Central do Brasil e pode ser usado para confirmar esta transferência em qualquer instituição financeira participante do PIX.",
"issued_at": "2026-10-28T15:00:00.000Z"
}- 对于
completed和partially_completed结果,status为paid;对于其他所有结果——包括reversed——则为failed。outcome标识终态结果。特别地,partially_completed结果的状态为paid,但is_payment_proof为false。 title和amount_label遵循凭证中的结果表。- 对于
completed以外的结果,transferred_at和顶层end_to_end_id为null。即使是已完成的付款,除非有有效的 Pix E2E,否则end_to_end_id为null。what_to_do和reason可以为null;reason是可安全展示给客户的说明,而不是服务商的原始错误。 footer:有 E2E 时为上述 BACEN 文本;已支付但无 E2E 时为 "Comprovante emitido pela Liqfy com base nos registros da transferência.";其他情况为 "Documento emitido pela Liqfy com base nos registros desta solicitação. NÃO é comprovante de pagamento."refunded_to_balance反映实际的账本入账;它不是从状态推断出来的。payer和receiver的姓名或证件可以为null;CPF/CNPJ 证件会被掩码处理。receiver.pix_key仅在收款方姓名和证件均缺失时才会填充。- 当有效分段为零个或一个时,
legs为null。存在多个有效分段时,它包含各分段的序号、金额、小写状态和 E2E。被替代的分段不包括在内。只有已完成的分段可以包含有效的 E2E(部分完成的付款亦然);其他分段的 E2E 为null。例如,部分完成的付款可能包含:
{
"legs": [
{ "index": 0, "amount": 60000, "status": "completed", "end_to_end_id": "E12345678202610281433Zx9Yw8Vu7Ts" },
{ "index": 1, "amount": 90000, "status": "failed", "end_to_end_id": null }
]
}#SDK 示例
这些示例假定 client 已配置,payoutId / payout_id 为付款 ID,key 为原始幂等密钥。
Node.js
const receipt = await client.payouts.receipt(payoutId, { format: 'json' });
const charge = await client.charges.retrieveByIdempotencyKey(key);
const payout = await client.payouts.retrieveByIdempotencyKey(key);
const charges = await client.charges.list({ idempotency_key: key });
const payouts = await client.payouts.list({ idempotency_key: key });Python
receipt = client.payouts.receipt(payout_id, format="json")
charge = client.charges.retrieve_by_idempotency_key(key)
payout = client.payouts.retrieve_by_idempotency_key(key)
charges = client.charges.list(idempotency_key=key)
payouts = client.payouts.list(idempotency_key=key)PHP
$receipt = $client->payouts->receipt($payoutId, ['format' => 'json']);
$charge = $client->charges->retrieveByIdempotencyKey($key);
$payout = $client->payouts->retrieveByIdempotencyKey($key);
$charges = $client->charges->list(['idempotency_key' => $key]);
$payouts = $client->payouts->list(['idempotency_key' => $key]);.NET
var receipt = await client.Payouts.ReceiptJsonAsync(payoutId);
var charge = await client.Charges.RetrieveByIdempotencyKeyAsync(key);
var payout = await client.Payouts.RetrieveByIdempotencyKeyAsync(key);
var charges = await client.Charges.ListByIdempotencyKeyAsync(key);
var payouts = await client.Payouts.ListByIdempotencyKeyAsync(key);