Skip to content
LIQFYdocs
PTENENEN
Go to dashboard

PIX 支付

PIX 是巴西的即时支付网络。资金在数秒内完成结算,全天候 24/7 运行。Liqfy 为您提供单一端点:在创建收款的同一响应中,返回 BR Code(Pix Copia e Cola)以及可直接在结账页面中渲染的二维码。

**按订单号查询:**创建收款时,将订单号作为 Idempotency-Key 请求头发送。之后使用同一账户的 API 密钥调用 GET /v1/charges/by-idempotency-key/{订单号}。仅设置 metadata.order_id 无法启用此查询。

确认 E2E 后,charge.paid 回调可在 data.object.settlement.end_to_end_id 中携带 Pix E2E。如果 E2E 尚不可用,该字段可能缺失;参见 Webhook。

#流程概览

text
1. POST /v1/charges  ────────▶  Liqfy returns a Charge: ch_…, status "pending", pix.br_code + QR
2. Render QR + Pix Copia e Cola in your UI
3. Customer scans / pastes in their bank app
4. Webhook charge.paid arrives at your endpoint
5. Mark order as paid

#1. 创建收款

端点 POST /v1/charges(Pix 优先快捷方式:POST /v1/pix/charges 固定 payment_method: "pix",并覆盖您发送的任何值。除此之外,其行为与 POST /v1/charges 完全相同:相同的请求头、相同的幂等性、相同的测试/正式密钥处理,响应中返回的 Charge 也完全相同)

请求头

text
Authorization: Bearer lq_live_…
Idempotency-Key: <unique per charge you intend to create>
Content-Type: application/json

Authorization: Bearer <key> 是提供 API 密钥的规范方式。Idempotency-Key 在 POST /v1/charges 上是必需的(缺少时返回 400)。它可以是任意非空字符串,按商户隔离((merchant, key))。使用相同的密钥和请求体重放时,将返回原始收款。当响应为重放时,还会携带请求头 Idempotency-Replayed: true,以便您区分重放的收款与新创建的收款。

未通过校验的请求体将被拒绝,并返回 400 及校验详情。

请求体

字段类型必需说明
amountinteger是单位为分。1000 = R$ 10,00。必须为正整数。
currencystring否默认为 "BRL",这是 Pix 收款唯一接受的币种。
payment_methodstring是"pix"(目前唯一接受的值;/v1/pix/charges 快捷方式会自动为您填写)。
descriptionstring否最多 500 个字符。在 metadata.description 中原样返回。
expires_ininteger否距收款到期的秒数(即 Pix 二维码的有效期)。取值范围为 60–604800(最长 7 天)。超出范围的值将被拒绝并返回 400,绝不会被自动截断为上限。省略时使用账户的默认时长(通常为 3600 = 1 小时)。响应中的 pix.expires_at 始终是权威的到期时间。
customer.namestring否在支持时显示在银行对账单上。
customer.documentstring否CPF 或 CNPJ。
customer.emailstring否用于收据。
customer.phonestring否
expected_payer_tax_idstring否⚠️ 将收款锁定到该 CPF/CNPJ:当您的账户启用锁定时,只有该证件可以付款,来自其他证件的付款将被拒绝(或退回,取决于服务商)。如果付款人可能是其他人,请勿发送。如果您的账户未配置锁定,该字段将被忽略,收款正常创建。参见下文 付款人 CPF 锁定。需要 customer.name。必须为有效的 CPF/CNPJ;如果您同时发送了 customer.document,则必须与之一致。
metadataobject否自由格式的键/值,按原样返回(保留键及以下划线开头的键会被移除)。

示例

bash
curl -X POST https://api.liqfy.com.br/v1/charges \
  -H "Authorization: Bearer $LIQFY_API_KEY" \
  -H "Idempotency-Key: ORD-7821" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 24900,
    "currency": "BRL",
    "payment_method": "pix",
    "description": "Pedido #7821",
    "expires_in": 1800,
    "customer": { "name": "Maria Silva", "document": "12345678901" },
    "metadata": { "order_id": "ORD-7821", "sku": "premium-monthly" }
  }'

响应 201 Created

json
{
  "id": "ch_a1b2c3d4-0000-0000-0000-000000000009",
  "object": "charge",
  "amount": 24900,
  "currency": "BRL",
  "status": "pending",
  "payment_method": "pix",
  "customer": { "name": "Maria Silva", "document": "12345678901" },
  "pix": {
    "br_code": "000201BRCODEPIX",
    "qr_code_url": "https://qr.example/img.png",
    "expires_at": "2026-07-23T15:00:00.000Z"
  },
  "checkout_url": "https://checkout.liqfy.com.br/a1b2c3d4-0000-0000-0000-000000000009",
  "settlement": {},
  "metadata": { "order_id": "ORD-7821", "sku": "premium-monthly", "description": "Pedido #7821" },
  "created_at": "2026-07-23T14:30:00.000Z"
}
字段用法
pix.br_codeEMV "Pix Copia e Cola" 载荷。请将其渲染在“复制到剪贴板”按钮中。
pix.qr_code_url / pix.qr_code_base64二维码图像(仅当服务商返回时提供):qr_code_url 为 https:// URL(可直接放入 <img src="...">),否则为 qr_code_base64(需解码的 PNG)。仅返回 br_code 的服务商两者都不会提供,因此请始终将 br_code 作为后备进行渲染。
checkout_url该收款的 Liqfy 托管结账页,即现成的支付页面(二维码、复制粘贴、实时状态)。您可以将付款人重定向到此处,而无需自行构建页面。GET /v1/charges/{id} 也会返回该字段,因此您可以稍后通过已存储的 id 获取。您无法自行构造此 URL,因为结账页需要的是不带 ch_ 前缀的 id。
pix.expires_at该收款的到期时间。请显示倒计时;到期后,status 变为 expired。
pix.txidBACEN TXID。该字段为可选,仅在服务商绑定了 TXID 时出现。切勿将其视为收款 id。
settlement始终存在。settlement.end_to_end_id 在结算前通常为空:仅在收款达到 paid 并完成结算/对账后才会出现。

pix 对象为 { br_code?, qr_code_url?, qr_code_base64?, expires_at?, txid? }。当没有 br_code、二维码图像或到期时间可显示时,该对象不存在。

#状态

状态含义
pending已创建;等待付款人付款。
processing已检测到付款;尚未确认(例如因审核而暂扣)。
paid已付款并入账。
failed付款被拒绝。
expiredexpires_at 已过但未付款。
cancelled在付款前已取消。
refunded已退还给付款人。
disputed拒付或争议。

#TXID 和 end_to_end_id

ch_… 始终是 Liqfy 收款 id,您应使用它来存储、查询收款以及对账 webhook。pix.txid 和 settlement.end_to_end_id 是由 BACEN 定义的上下文 Pix 数据,仅在适用时出现:

json
{
  "id": "ch_a1b2c3d4-0000-0000-0000-000000000009",
  "pix": { "txid": "BACEN-TXID-77" },
  "settlement": {}
}

charge.id !== charge.pix.txid,始终如此,即使两者都存在也是如此。切勿以 TXID 或 end_to_end_id 作为数据库键;请使用 ch_…。

#付款人 CPF 锁定

设置 expected_payer_tax_id 可要求只有某个特定的 CPF/CNPJ 才能支付收款。例如,用于确保买家从自己的账户而非第三方账户付款。

⚠️ 发送此字段将锁定收款。 当您的账户启用锁定时,只有指定的 CPF/CNPJ 可以付款:任何从其他账户付款的人,其付款都会被银行拒绝(或退回,取决于服务商)。仅在您确实需要此限制时发送,例如必须来自客户本人账户的投注或存款。如果付款人可能是其他人(如父母为孩子付款、公司为合作伙伴付款),请勿发送:请仅使用 customer.document,它仅供参考,不会锁定任何内容。

可用性。 锁定功能默认关闭:它取决于为您账户提供服务的服务商,并且仅在支持团队已完成配置的情况下生效。在未配置锁定的账户上,携带 expected_payer_tax_id 的收款会正常创建,不带锁定:任何付款人都可以付款,款项也会入账。您可以从响应中判断:此时收款不包含 expected_payer_tax_id。当锁定生效时,该字段会在收款中回显,并适用以下规则。需要锁定功能?请联系支持团队。

bash
curl -X POST https://api.liqfy.com.br/v1/charges \
  -H "Authorization: Bearer $LIQFY_API_KEY" \
  -H "Idempotency-Key: ORD-7821" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 24900,
    "payment_method": "pix",
    "customer": { "name": "Maria Silva", "document": "12345678901" },
    "expected_payer_tax_id": "12345678901"
  }'

工作原理:

  • 收款的创建和支付方式与其他任何 Pix 收款完全相同。
  • 结算时,Liqfy 从银行读取实际付款人的证件,并与 expected_payer_tax_id 进行比对。
  • 匹配 → 收款变为 paid,您的余额照常入账。
  • 由其他付款人支付 → 取决于为您账户提供服务的服务商如何执行锁定:
    • 检测式(fail-closed):收款不会入账。Liqfy 会自动将款项退还给付款人(标准的 Pix devolução,依据原始 end_to_end_id 发起);收款保持 processing 状态,直到退款结算完成,之后才变为 refunded。您永远不会收到第三方资金。
    • 预防式:银行端规则应在付款到账前拒绝其他付款人。如果第三方仍然成功付款(规则未生效),资金仍会入账,收款保持 paid,并被标记为付款人不匹配;该款项归您所有。
  • 银行未披露付款人证件 → 收款将保持 processing 状态(永不入账)以进行人工审核,而不会为无法验证的付款人入账。

注意事项:

  • 捕获并退还的保证仅适用于检测式(fail-closed)路径:收款保持 processing 状态,直到自动退款(devolução)结算完成,之后才变为 refunded,并且您的商户余额永远不会因不匹配的付款人而入账。在该路径上,检查发生在结算时,而非在银行层面拦截。在预防式路径上,绕过银行端规则的付款仍会入账,收款保持 paid(并被标记为付款人不匹配)。在两种模式下,BACEN 都允许任何付款人扫描二维码,因此付款人的应用仍可能显示该收款。
  • expected_payer_tax_id 需要 customer.name(收款和退款都需要该字段),必须为校验和有效的 CPF(11 位)或 CNPJ(14 位);如果您同时发送了 customer.document,则必须与之一致。否则请求将被拒绝 400。
  • 该值会在收款中回显(expected_payer_tax_id);实际付款人的证件永远不会被公开。

#2. 查询收款

端点 GET /v1/charges/{id}

bash
curl https://api.liqfy.com.br/v1/charges/ch_a1b2c3d4-0000-0000-0000-000000000009 \
  -H "Authorization: Bearer $LIQFY_API_KEY"

接受带 ch_… 前缀的 id 或原始 id。Pix 付款并结算后,settlement.end_to_end_id 会出现,status 变为 paid:

json
{
  "id": "ch_a1b2c3d4-0000-0000-0000-000000000009",
  "object": "charge",
  "status": "paid",
  "amount": 24900,
  "currency": "BRL",
  "payment_method": "pix",
  "customer": { "name": "Maria Silva", "document": "12345678901" },
  "settlement": { "end_to_end_id": "E12345678202610281433Zx9Yw8Vu7Ts" },
  "metadata": { "order_id": "ORD-7821" },
  "created_at": "2026-07-23T14:30:00.000Z"
}

#通过 Idempotency-Key 查询

端点 GET /v1/charges/by-idempotency-key/{key}

返回与 GET /v1/charges/{id} 相同的公共 Charge,在您的账户内依据创建时发送的 Idempotency-Key 进行查找。当创建请求超时且您从未收到 ch_… id 时,此端点非常有用。

bash
curl https://api.liqfy.com.br/v1/charges/by-idempotency-key/ORD-7821 \
  -H "Authorization: Bearer $LIQFY_API_KEY"

密钥会去除首尾空白;空白密钥或长度超过 255 个字符的密钥将被拒绝,并返回 400(Invalid idempotency key)。

#轮询与 webhook

履约和数据库写入请完全依赖 webhook,webhook 是唯一可信来源。GET /v1/charges/{id} 用于按需状态检查(例如支持工具、手动“检查状态”按钮),而不应用于轮询循环。

#3. 列出收款

端点 GET /v1/charges,采用游标分页(绝不使用偏移量:没有 page/offset)。

查询参数类型默认值说明
limitint251–100。
starting_afterstring—游标:您看到的最后一个收款的 ch_… id(或原始 id)。
statusstring—上述状态之一。
created_after / created_beforeISO-8601 datetime—严格 UTC(…Z),带时区偏移的值将被拒绝。
customer_idstring—按付款人证件筛选。

无效的查询将被拒绝,并返回 400 及校验详情。

bash
curl "https://api.liqfy.com.br/v1/charges?limit=25&status=paid" \
  -H "Authorization: Bearer $LIQFY_API_KEY"

响应 200 OK,即游标信封:

json
{
  "object": "list",
  "data": [ { "id": "ch_a1b2c3d4-0000-0000-0000-000000000009", "object": "charge", "status": "paid" } ],
  "has_more": true,
  "next_cursor": "ch_a1b2c3d4-0000-0000-0000-000000000009"
}

将 next_cursor 作为 starting_after 传入以逐页遍历,直到 has_more 为 false。结果按从新到旧排序。

#4. 接收 webhook

当付款人付款时,您注册的 webhook 端点将收到一个已签名的 POST,其中包含规范的事件信封:

json
{
  "id": "evt_5f3a9b2c1d4e5f6a7b8c9d0e1f2a3b4c",
  "object": "event",
  "api_version": "2026-07-23",
  "type": "charge.paid",
  "created_at": "2026-07-23T14:31:00.000Z",
  "data": {
    "object": {
      "id": "ch_a1b2c3d4-0000-0000-0000-000000000009",
      "object": "charge",
      "amount": 24900,
      "currency": "BRL",
      "status": "paid",
      "payment_method": "pix",
      "settlement": { "end_to_end_id": "E12345678202610281433Zx9Yw8Vu7Ts" }
    }
  }
}

有关签名验证、重试语义和注册,请参阅 Webhooks。

#代码示例

使用官方 SDK(所有品牌使用同一个中立的包,请使用本页的 API 基础 URL 进行配置:https://api.liqfy.com.br):

nodepythonphpdotnet
client.charges.create(input, { idempotencyKey })client.charges.create(input, idempotency_key)$client->charges->create($input, $idempotencyKey)client.Charges.CreateAsync(input, idempotencyKey)
client.charges.retrieve(id)client.charges.retrieve(id)$client->charges->retrieve($id)client.Charges.RetrieveAsync(id)
client.charges.list(query)client.charges.list(**query)$client->charges->list($query)client.Charges.ListAsync(query)

charges.list 返回游标信封 { object: "list", data, has_more, next_cursor }。以下是对应的原始 HTTP 示例。

#Node.js (fetch)

js
const res = await fetch('https://api.liqfy.com.br/v1/charges', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.LIQFY_API_KEY}`,
    'Idempotency-Key': order.id,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    amount: 24900,
    currency: 'BRL',
    payment_method: 'pix',
    customer: { name: order.customer.name, document: order.customer.document },
    metadata: { order_id: order.id },
  }),
});

if (!res.ok) throw new Error(`Liqfy ${res.status}: ${await res.text()}`);
const charge = await res.json();
// charge.id (ch_…) → store on the order; charge.pix.br_code / qr_code_url → render immediately

#PHP

php
$ch = curl_init('https://api.liqfy.com.br/v1/charges');
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_POST           => true,
  CURLOPT_HTTPHEADER     => [
    'Authorization: Bearer ' . getenv('LIQFY_API_KEY'),
    'Idempotency-Key: ' . $order->id,
    'Content-Type: application/json',
  ],
  CURLOPT_POSTFIELDS => json_encode([
    'amount'         => 24900,
    'currency'       => 'BRL',
    'payment_method' => 'pix',
    'customer'       => ['name' => $order->customerName],
    'metadata'       => ['order_id' => $order->id],
  ]),
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($status !== 201) throw new Exception("Liqfy $status: $body");
$charge = json_decode($body, true);

#Python (requests)

python
import os, requests

r = requests.post(
    "https://api.liqfy.com.br/v1/charges",
    headers={
        "Authorization": "Bearer " + os.environ['LIQFY_API_KEY'],
        "Idempotency-Key": order.id,
    },
    json={
        "amount": 24900,
        "currency": "BRL",
        "payment_method": "pix",
        "customer": {"name": order.customer.name},
        "metadata": {"order_id": order.id},
    },
    timeout=10,
)
r.raise_for_status()
charge = r.json()

#边界情况与常见问题

问:响应中缺少 pix.br_code / 二维码字段。 答:Pix 优先创建会同步返回这些字段。如果缺失,status 通常已显示 failed。请先检查请求是否存在校验错误(使用 GET /v1/charges/{id} 重新读取已存储的收款)。

问:我的创建请求超时了,收款是否已创建? 答:使用相同的 Idempotency-Key 和请求体重试:如果收款已存在,您将获得原始收款(带有 Idempotency-Replayed: true)。您也可以通过 GET /v1/charges/by-idempotency-key/{key} 查询。

问:二维码的有效期有多长? 答:请查看收款上的 pix.expires_at,它按每笔收款单独设置。到期后,status 变为 expired,必须创建新的收款。

问:我可以对 PIX 收款退款吗? 答:目前退款需通过管理后台申请。API 未提供商户可用的退款端点(它会拒绝使用 API 密钥的调用方)。/v1/charges/{id}/refund 同样如此,该端点并不存在。

问:如果客户从未付款,我会被收取费用吗? 答:不会。费用仅适用于 paid 的收款,并且从不会在公共 charge 响应中逐项列出(参见 API 约定 §3)。

问:我的客户支付的金额不正确。 答:PIX 要求金额完全匹配。少付的收款保持 pending,银行会将款项退还给付款人。多付的情况很少见,但处理方式相同。

#下一步

→ 为生产环境配置 webhook

有关 E2E 保证和保留期限,请参阅结算标识符与查询。