docs
Webhooks

概述

什么是 Webhooks?

PIX Webhooks 让您在 PIX 交易状态发生变化时实时接收通知。您无需持续轮询 API,系统会在重要事件发生时自动收到通知。

Webhooks 是跟踪交易状态的推荐方式。与轮询相比,它们可以降低延迟和资源消耗。

特性

  • 实时通知,通过 POST 发送 JSON 请求体
  • 7 种事件类型(Cash In、Cash Out、Refund In、Refund Out、MED Created、MED Accepted、MED Rejected)
  • 每个事件最多 3 个 HTTPS URL,通知会发送到所有 URL(fan-out)
  • 每个 URL 最多 5 个自定义 header(例如您自己的 Authorization)
  • 在 X-Avista-Signature header 中提供请求体的 HMAC-SHA256 签名
  • 失败时自动重试,并支持通过 API 手动重发

可用事件

事件eventType(注册)event(payload)movementType描述
PIX Incash_inCashInCREDITPIX 收款
PIX Outcash_outCashOutDEBITPIX 付款
Refund Inrefund_inCashInReversalDEBIT收款的退款
Refund Outrefund_outCashOutReversalCREDIT收到的付款退回
MED Createdmed_createdMedCreated—针对交易开启的 MED
MED Acceptedmed_acceptedMedAccepted—MED 退款已批准
MED Rejectedmed_rejectedMedRejected—MED 退款已拒绝

注册 URL 时使用 snake_case 的 eventType(cash_in、cash_out...)。收到的 payload 中的 event 字段使用 PascalCase(CashIn、CashOut...)。


端点配置

要接收 webhooks,您需要:

使用面板(https://banking.fypay.me)中的 设置 → Webhooks(Configurações → Webhooks)(参见 配置 Webhooks)。每个事件最多可注册 3 个活跃的 HTTPS URL;触发时,通知会发送到所有 URL(fan-out)。

创建一个接受 POST 请求并在 10 秒内返回 2xx 状态码的 HTTPS 端点。

在面板中生成签名密钥并验证 X-Avista-Signature header(参见实现)。您也可以同时验证已注册的自定义 header,并限制来源 IP。

技术要求

要求描述
协议注册时必须使用 HTTPS
方法POST
Content-Typeapplication/json
超时10 秒
响应任意 2xx 状态码。重定向(3xx)不会被跟随,并计为失败

如果您的端点未在 10 秒内返回 2xx,投递将被视为失败,并在 30 秒、1 分钟、3 分钟、5 分钟和 15 分钟后重试。当同一事件注册了多个 URL 时,每个 URL 独立投递:一个 URL 失败不会影响其他 URL,已成功接收的 URL 在重试时不会再次收到。


Webhook 认证

FyPay 提供三种机制,可以组合使用:

机制工作方式
HMAC 签名(推荐)在面板中生成签名密钥后,每个 webhook 都会带上 X-Avista-Signature header,其值为原始请求体的 HMAC-SHA256(十六进制)。参见如何验证。
自定义 header每个 URL 最多可注册 5 个 header(例如 Authorization: Basic ... 或 X-Webhook-Secret: ...)。它们会随该 URL 的每个 webhook 一起发送,由您的端点验证其值。
IP 白名单只接受来自 FyPay 来源 IP 的请求(见下方列表)。

签名 header 的名称确实就是 X-Avista-Signature。这是目前所有已签名 webhook 发送的技术名称;请在验证程序中原样使用。

在面板中生成签名密钥之前,webhook 投递时不带 X-Avista-Signature header。FyPay 不会自行发送 Basic Auth:如果您的端点需要 Authorization,请将该 header 注册为自定义 header。

验证您注册的自定义 header Authorization: Basic ... 的示例:

app.post('/webhooks/pix', (req, res) => {
  const expected = 'Basic ' + Buffer.from(
    `${process.env.WEBHOOK_USER}:${process.env.WEBHOOK_PASS}`
  ).toString('base64');

  if (req.headers.authorization !== expected) {
    return res.status(401).send('Unauthorized');
  }

  res.status(200).json({ acknowledged: true });
});

IP 白名单

FyPay 的 webhooks 从以下 IP 地址发出。如果您的防火墙或 WAF 限制入站流量,请放行所有这些地址:

来源 IP
184.197.16.190
54.85.39.76
184.197.130.162
184.196.180.161
52.0.159.232
54.88.75.254

请放行整个列表:请求可能从其中任意一个 IP 发出。IP 白名单是对签名验证的补充,而不是替代。


Payload 基础结构

交易事件(CashIn、CashOut、CashInReversal、CashOutReversal)共享以下基础结构。MED 事件有自己的 payload,详见 MedCreated。

{
  "event": "CashIn",
  "status": "CONFIRMED",
  "transactionType": "PIX",
  "movementType": "CREDIT",
  "transactionId": "12345",
  "externalId": "PIX-5482123298-EJUYFSMU1UU",
  "endToEndId": "E00416968202512111942rjzxxzSSTD9",
  "pixKey": "1ff6ce09-4244-44d5-aa8f-1fe69f8986a9",
  "feeAmount": 0.01,
  "originalAmount": 0.5,
  "finalAmount": 0.49,
  "mismatchAmount": null,
  "processingDate": "2025-12-11T19:42:04.080Z",
  "errorCode": null,
  "errorMessage": null,
  "providerId": "a1b2c3d4e5",
  "metadata": {}
}

金额以雷亚尔(BRL)表示,最多 5 位小数。

除基础结构外,CashIn 和 CashOut 包含 counterpart 对象,CashInReversal 和 CashOutReversal 包含 parentTransaction 对象。


后续步骤

本页目录