docs
Webhooks

Overview

What are Webhooks?

PIX Webhooks allow you to receive real-time notifications when the status of a PIX transaction changes. Instead of constantly polling the API, your system is automatically notified when important events occur.

Webhooks are the recommended way to track transaction statuses. They reduce latency and resource consumption compared to polling.

Features

  • Real-time notifications, sent via POST with a JSON body
  • 7 event types (Cash In, Cash Out, Refund In, Refund Out, MED Created, MED Accepted, MED Rejected)
  • Up to 3 HTTPS URLs per event, with delivery to all of them (fan-out)
  • Up to 5 custom headers per URL (for example, your own Authorization)
  • HMAC-SHA256 signature of the body in the X-Avista-Signature header
  • Automatic retries on failure and manual resend via API

Available Events

EventeventType (registration)event (payload)movementTypeDescription
PIX Incash_inCashInCREDITPIX receipt
PIX Outcash_outCashOutDEBITPIX send
Refund Inrefund_inCashInReversalDEBITReversal of a receipt
Refund Outrefund_outCashOutReversalCREDITRefund received for a sent PIX
MED Createdmed_createdMedCreated—MED opened against a transaction
MED Acceptedmed_acceptedMedAccepted—MED refund approved
MED Rejectedmed_rejectedMedRejected—MED refund rejected

URL registration uses the eventType in snake_case (cash_in, cash_out...). The event field of the received payload uses PascalCase (CashIn, CashOut...).


Endpoint Configuration

To receive webhooks, you need to:

Use the dashboard (https://banking.fypay.me), under Settings → Webhooks (see Configure Webhooks). You can register up to 3 active HTTPS URLs per event; when the event fires, the notification is sent to all of them (fan-out).

Create an HTTPS endpoint that accepts POST requests and responds with a 2xx status within 10 seconds.

Generate the signing key in the dashboard and validate the X-Avista-Signature header (see Implementation). Optionally, also validate the custom headers you registered and restrict the source IPs.

Technical Requirements

RequirementDescription
ProtocolHTTPS required at registration
MethodPOST
Content-Typeapplication/json
Timeout10 seconds
ResponseAny 2xx status. Redirects (3xx) are not followed and count as failures

If your endpoint does not respond with 2xx within 10 seconds, the delivery is considered failed and will be retried after 30 s, 1 min, 3 min, 5 min and 15 min. When multiple URLs are registered for the same event, each URL has its own delivery: a failure on one URL does not affect the others, and a URL that has already received successfully does not receive again on retries.


Webhook Authentication

FyPay offers three mechanisms, which can be combined:

MechanismHow it works
HMAC signature (recommended)After you generate the signing key in the dashboard, every webhook carries the X-Avista-Signature header with the HMAC-SHA256 (hex) of the raw body. See how to validate.
Custom headersYou can register up to 5 headers per URL (for example, Authorization: Basic ... or X-Webhook-Secret: ...). They are sent with every webhook for that URL and your endpoint validates the values.
IP allowlistAccept only requests coming from FyPay's source IPs (list below).

The signature header name really is X-Avista-Signature. This is the technical name sent today on every signed webhook; use it exactly like that in your validator.

Until the signing key is generated in the dashboard, webhooks are delivered without the X-Avista-Signature header. FyPay does not send Basic Auth on its own: if your endpoint requires Authorization, register that header as a custom header.

Example of validating a custom Authorization: Basic ... header that you registered:

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 Allowlist

FyPay webhooks are sent from the following IP addresses. If your firewall or WAF restricts inbound traffic, allow all of them:

Source 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

Allow the whole list: delivery may come from any of these IPs. The allowlist complements signature validation but does not replace it.


Base Payload Structure

Transaction events (CashIn, CashOut, CashInReversal, CashOutReversal) share the base structure below. MED events have their own payload, described in 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": {}
}

Monetary values are sent in reais (BRL), with up to 5 decimal places.

In addition to the base, CashIn and CashOut include the counterpart object, and CashInReversal and CashOutReversal include the parentTransaction object.


Next Steps

On this page