Skip to content
LIQFYdocs
PTENENEN
Go to dashboard

银行卡支付

通过由 Liqfy 托管的支付页面接受 Visa、Mastercard、American Express、Elo、Hipercard 及其他主要卡组织的付款——卡数据绝不会经过您的服务器,3D Secure 自动处理。

#流程概览

text
1. POST /v1/payments  ──────▶  Liqfy returns the payment: id, status WAITING_PAYMENT, cardRedirectUrl + checkoutUrl
2. Redirect (or open in iframe) the customer to cardRedirectUrl
3. Customer enters card details + completes 3DS challenge on Liqfy's secure page
4. Customer is bounced back to your returnUrl (success or failure)
5. Webhook charge.paid (or charge.failed) confirms the outcome — trust the webhook, not the redirect

为什么要重定向? 这样持卡人数据完全不会进入您的基础设施。您的应用(无论后端还是前端)永远不会看到 PAN、CVV 或有效期。Liqfy 的处理方在我们这一侧负责 3DS、令牌化和欺诈筛查。

#1. 创建支付

端点 POST /v1/payments

bash
curl -X POST https://api.liqfy.com.br/v1/payments \
  -H "Authorization: Bearer $LIQFY_API_KEY" \
  -H "Idempotency-Key: ORD-9821" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 8990,
    "currency": "EUR",
    "paymentMethods": ["CREDIT_CARD"],
    "customerName": "João Costa",
    "customerEmail": "joao@example.com",
    "customerPhone": "+351912345678",
    "returnUrl": "https://shop.example.com/orders/9821/return",
    "cancelUrl": "https://shop.example.com/cart",
    "metadata": { "orderId": "ORD-9821" }
  }'

幂等性。 POST /v1/payments 接受 Idempotency-Key 请求头(推荐);在缺少该请求头时,也可使用请求体字段 idempotencyKey 作为备选;至少须发送其一。如果两者都发送,它们必须一致——值不一致返回 400,两者都未发送则在此路由上返回 400。可以是任意非空字符串(首尾空白会被去除),作用域为每个商户((merchant, key)):使用相同的键和请求体重放会返回已存储的响应,相同的键配不同的请求体则返回 409。此路由不会返回 Idempotency-Replayed 请求头——请勿基于它构建重试逻辑。

字段说明
amount大于 0 的整数,以最小货币单位(分)计。8990 = € 89,90。
currency3–8 个字符,默认 "BRL"(BRL、EUR、USD;其他币种可按需开通)。
paymentMethods此处为 ["CREDIT_CARD"]。API 接受 PIX、CRYPTO、CREDIT_CARD、BOLETO、MBWAY、MULTIBANCO、IDEAL、BANCONTACT、SEPA、BIZUM、SWAP_NOW。至少一项。除非发送了 checkout,否则为必填(否则返回 400 —— paymentMethods is required unless a checkout template is provided)。
checkout可选的结账模板 slug(1–80)。使用模板时可省略 paymentMethods:由模板加上收费币种决定支付方式,并筛选为实际可路由的方式,它们将成为该笔收费的 paymentMethods。未知 slug → 404;模板服务不可达 → 503。
customerId可选字符串。
customerName / customerDocument / customerEmail / customerPhone扁平化的客户字段。customerEmail 必须是电子邮件地址;customerPhone 为自由格式(建议使用 E.164)。强烈建议提供 customerEmail——用于收据、欺诈信号及拒付争议证明。
customer另一种嵌套形式 { name?, document?, email?, phone? }(email 必须是电子邮件地址);会被展开到上述字段中(以扁平字段为准)。
expectedPayerDocument仅含数字的预期付款人 CPF/CNPJ;在服务商支持的情况下作为付款人锁定。锁定的收费还需要付款人姓名(customerName),否则返回 PAYER_NAME_REQUIRED。
returnUrl客户完成支付后(成功或失败)的跳转地址。http(s) URL,不得包含片段(fragment)。规范字段。
cancelUrl客户中止支付时的跳转地址。URL 规则相同;需要同时提供 returnUrl(否则返回 400 —— cancelUrl requires returnUrl)。
metadata自由格式的键/值。metadata.returnUrl / metadata.cancelUrl 如存在,必须是 http(s) URL。metadata.returnUrl 仍会驱动托管结账页的重定向,但规范字段是顶层的 returnUrl。
items可选 { name, quantity, unitPrice, totalPrice }[];name 不能为空,数值为大于 0 的整数。
webhookUrl可选的单笔交易 webhook URL 覆盖;必须是有效的 URL。
idempotencyKeyIdempotency-Key 请求头的请求体备选(见上文)。
country可选,2–3 个字符;服务商账户路由输入。
riskTier可选 LOW、MEDIUM 或 HIGH;服务商账户路由输入。
environment可选 SANDBOX、STAGING、PRODUCTION —— 让您可以明确指定沙盒账户。省略时根据服务器环境推导。
expiresIn可选的 Pix 二维码有效期(秒),60–604800;作为请求的过期时间转发给服务商(以服务商返回的过期时间为准)。

响应 201 Created —— 创建响应已包含支付方式产物(此处为 cardRedirectUrl)和 checkoutUrl;无需再调用 GET 即可查看。

json
{
  "id": "b2c3d4e5-f6a7-4890-9bcd-ef0123456789",
  "status": "WAITING_PAYMENT",
  "amount": 8990,
  "currency": "EUR",
  "paymentMethods": ["CREDIT_CARD"],
  "customerName": "João Costa",
  "customerEmail": "joao@example.com",
  "customerPhone": "+351912345678",
  "cardRedirectUrl": "https://checkout.liqfy.com.br/c/b2c3d4e5-f6a7-4890-9bcd-ef0123456789",
  "checkoutUrl": "https://checkout.liqfy.com.br/b2c3d4e5-f6a7-4890-9bcd-ef0123456789",
  "createdAt": "2026-04-25T15:50:11.000Z"
}

checkoutUrl 仅在创建和查询时返回——列表行和取消响应中不包含该字段。

#创建时的错误

HTTPcode触发条件
400—(扁平化的校验错误)请求体无效;缺少幂等键或请求头/请求体不一致;发送了 cancelUrl 但未提供 returnUrl;缺少 paymentMethods 且未提供 checkout。
401—请求未能识别您的账户(请求必须经过 API 网关认证后到达)。
403fraud.tenant_velocity_exceeded您的账户在短时间内支付尝试过多(默认:每 60 秒 200 次)。
403fraud.customer_velocity_exceeded同一 customerDocument 或 customerEmail 在短时间内支付尝试过多(默认:每 300 秒 10 次)。已过期和已取消的收费不计入;被拒绝的收费计入。两个字段都没有的收费不受此规则限制。
404—未知的 checkout slug。
4xxNO_PROVIDER_CONFIGURED此支付方式和币种未配置支付服务商。
4xxUNKNOWN_METHOD不支持该支付方式。
4xxMOCK_PROVIDER_IN_PRODUCTION该支付方式不可用于正式收费。
4xxPAYER_IDENTITY_REQUIRED该收费需要付款人的完整身份信息(姓名、电子邮件、电话和税号)。
4xxPAYER_NAME_REQUIRED发送了 expectedPayerDocument 但未提供付款人姓名。
4xxPAYMENT_REJECTED服务商拒绝了该收费(也是其他任何服务商侧拒绝的兜底代码)。
503PROVIDER_UNAVAILABLE支付服务商暂时不可用——请稍后重试(使用相同的 Idempotency-Key)。
5xxPROVIDER_ERROR服务商返回了意外的响应。

服务商侧的 4xx 错误保留路由层返回的 HTTP 状态码。错误消息按设计保持中立——绝不会提及服务商名称或其内部代码;如需详情,请向支持团队提供请求 ID。

使用官方 SDK(所有品牌通用的同一个中立包——通过 https://api.liqfy.com.br 进行配置):

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

payments.list(GET /v1/payments)返回分页封装 { data, total, page, limit }。查询参数:page(默认 1)、limit(默认 20,最大 100)、status、currency、startDate / endDate(ISO-8601 日期时间)、source(API、PANEL、MANUAL、INDEFINIDO)、sortBy、sortOrder(asc / desc)。

#2. 重定向客户

cardRedirectUrl 包含在创建响应中(以及每次 GET /v1/payments/{id} 的响应中),因此您可以立即重定向:

bash
curl https://api.liqfy.com.br/v1/payments/b2c3d4e5-f6a7-4890-9bcd-ef0123456789 \
  -H "Authorization: Bearer $LIQFY_API_KEY"
json
{
  "id": "b2c3d4e5-f6a7-4890-9bcd-ef0123456789",
  "status": "WAITING_PAYMENT",
  "amount": 8990,
  "currency": "EUR",
  "cardRedirectUrl": "https://checkout.liqfy.com.br/c/b2c3d4e5-f6a7-4890-9bcd-ef0123456789",
  "createdAt": "2026-04-25T15:50:11.000Z"
}

将客户引导至 cardRedirectUrl:

html
<a href="{{ cardRedirectUrl }}">Pay with card</a>

或在服务器端执行 303 See Other:

js
res.redirect(303, transaction.cardRedirectUrl);

客户完成流程(或中止)后,会被跳转回您提供的 returnUrl(托管结账页从 metadata.returnUrl 读取相同的重定向地址),并附加 ?transactionId=...&status=...。不要信任这些查询参数。 它们仅供参考——请在收到 webhook 后再履约。

#3. 通过 webhook 确认

json
{
  "id": "evt_00000000000000000000000000000001",
  "object": "event",
  "api_version": "2026-07-23",
  "type": "charge.paid",
  "created_at": "2026-04-25T15:52:34.000Z",
  "data": {
    "object": {
      "id": "ch_b2c3d4e5-f6a7-4890-9bcd-ef0123456789",
      "object": "charge",
      "status": "paid",
      "amount": 8990,
      "currency": "EUR",
      "payment_method": "card",
      "settlement": {}
    }
  }
}

银行卡支付成功时,公开收费状态为 paid。公开状态词汇包括 pending、processing、paid、failed、expired、cancelled、refunded、disputed。

拒绝以 charge.failed 的形式送达;过期优先使用 charge.expired。请读取 data.object.status 获取公开结果。该事件不会暴露发卡行的拒绝原因。

#生命周期

text
WAITING_PAYMENT  ──▶  PROCESSING  ──▶  APPROVED    ✓ fulfill order
                                  ──▶  REFUSED     issuer declined
                                  ──▶  CANCELLED   customer abandoned
                                  ──▶  EXPIRED     redirect link aged out (24h)

结算后(根据卡组织和您的合同,D+1 至 D+30),您还可能看到:

text
APPROVED  ──▶  CHARGEBACK   issuer raised a chargeback
APPROVED  ──▶  DISPUTE      cardholder opened a dispute
APPROVED  ──▶  REFUNDED     you (or Liqfy) issued a refund

每种状态都会触发 webhook,以便您同步订单状态。

#支付的其他操作

端点作用
POST /v1/payments/{id}/cancel取消支付;以与 GET /v1/payments/{id} 相同的结构返回(不含 checkoutUrl)。
POST /v1/payments/{id}/resend-webhook请求 Liqfy 重新发送该支付的 webhook。
POST /v1/payments/{id}/reconcile向服务商重新核查支付状态;返回 { reconciled, status }。
GET /v1/payments/{id}/refunds该支付的退款历史。failureReason 始终为 null,且 reason 仅在您自己发起的退款中填写。
POST /v1/payments/{id}/confirm-sandbox仅限沙盒——确认模拟收费以触发完成 webhook。任何非沙盒收费都会被拒绝;绝不会入账到钱包。
POST /v1/payments/{id}/refundAPI 密钥调用方不可用:返回 403 REFUND_ADMIN_ONLY(见常见问题)。

#测试卡

在沙盒中,重定向页面接受以下确定性卡号(任意未来有效期、任意 CVV):

卡号结果
4111 1111 1111 1111始终 APPROVED
4000 0000 0000 0002始终 REFUSED —— 通用拒绝
4000 0000 0000 0069始终 REFUSED —— 卡已过期
4000 0000 0000 9995始终 REFUSED —— 余额不足
4000 0000 0000 3220触发 3DS 验证后 APPROVED

沙盒收费在模拟器上运行:绝不会入账到您的钱包,也不计入交易量、收入和指标数据(但仍会出现在列表和收费详情中)。使用 POST /v1/payments/{id}/confirm-sandbox 可通过测试密钥端到端触发完成 webhook。

完整列表请参阅沙盒。

#常见问题

问:能让客户留在我的域名上吗? 答:第二阶段我们将推出可嵌入组件(iframe + 令牌化器),既保留您的品牌风格,又让持卡人数据不进入您的基础设施。目前:托管重定向。

问:支持保存卡吗? 答:支持,但需要您一方持有自己的卡数据安全合规证明。请发送邮件至 suporte@liqfy.com.br 以启用 Vault API。

问:使用哪个 3DS 版本? 答:3DS 2.x,在发卡行允许时采用无摩擦流程。EUR 必须进行强客户认证(SCA)——由服务器端强制执行。

问:退款? 答:目前退款需在管理后台发起,支持全额或部分退款——API 未提供商户可用的退款端点:使用 API 密钥调用 POST /v1/payments/{id}/refund 会返回 403 REFUND_ADMIN_ONLY。您仍可通过 GET /v1/payments/{id}/refunds 读取退款历史。

问:客户已被扣款,但我从未收到 webhook。 答:请检查 GET /v1/webhooks/deliveries——很可能我们已尝试发送,但您的端点返回了非 2xx 状态。我们最多重试 15 次。之后请使用 POST /v1/payments/{id}/resend-webhook 或联系支持团队重放。

#下一步

→ MB WAY · Multibanco · API 参考