Setting up webhooks
- Go to Settings > Webhooks in the dashboard.
- Click Add webhook and enter your endpoint URL. The URL must use HTTPS.
- Select the events you want to receive.
- Save the generated secret somewhere safe — it is shown only once and is required to verify incoming requests.
Event types
PAYMENT_EXPIRED is not always final for boleto. A boleto paid on or shortly after its due date can settle late, so you may receive PAYMENT_EXPIRED and then PAYMENT_PAID for the same charge. Always treat the payload’s data.status as the source of truth rather than assuming PAYMENT_EXPIRED is terminal.Webhook payload
Events are delivered as JSONPOST requests. A PAYMENT_PAID event carries a payer block describing the account that paid the PIX charge, plus the network endToEndId for bank reconciliation:
payer is nullable, and the whole block is null for historical records or open-payer charges where no payer data was captured. The payer document (CPF/CNPJ) is returned unredacted when the full value is on file; for some open-payer charges only a masked value (e.g. 75******20) is available. The endToEndId is the PIX-network end-to-end identifier (Banco Central standard), safe to use for reconciliation.
A WITHDRAWAL_SENT event carries a recipient block describing the destination account:
payer, every recipient field is nullable and the block is null when no recipient data was captured. These blocks are provider-agnostic: the shape is identical regardless of which PIX provider settled the transaction. The fields inside data otherwise depend on the event type and mirror the corresponding resource in the API reference.
Request headers
Each webhook delivery includes these headers:Verifying signatures
YuvexPay signs each delivery with the webhook secret you saved when creating the endpoint. The recommendedv1 algorithm signs both a timestamp and the raw request body, which prevents both tampering and replay attacks.
- Read
X-Webhook-TimestampandX-Webhook-Signaturefrom the headers. - Compute the expected signature using your stored secret and the raw, unparsed request body.
- Compare in constant time. Reject if they don’t match.
- Reject any request whose timestamp is more than 300 seconds off the current time. This is the recommended replay window and matches what YuvexPay applies internally.
Delivery semantics
YuvexPay aims to deliver every event at least once. A few characteristics worth designing around:- At-least-once delivery. The same event may arrive more than once. Treat
X-Webhook-Delivery-Idas the deduplication key. If you’ve processed a delivery id before, return200and skip the side effects. - Order is not guaranteed. Deliveries are dispatched in parallel; under retry, a
PAYMENT_REFUNDEDmay arrive before its priorPAYMENT_PAID. Always reconcile against the resource state indata.status, not against the order of arrival. - Synchronous timeout: 10 seconds. Return
2xxwithin 10 seconds. Process work asynchronously if you need longer. - Redirects are not followed. Your endpoint must respond directly.
Retry behavior
If your endpoint returns a non-2xx status code or fails to respond, YuvexPay retries with exponential backoff. The default schedule is:
You can configure up to 10 retries per endpoint. After all retries are exhausted, the delivery is marked
FAILED. Failed deliveries can be inspected and manually replayed from the dashboard. A manual replay reuses the same X-Webhook-Delivery-Id.
Best practices
- Verify before trusting. Always validate the
X-Webhook-Signatureand theX-Webhook-Timestampskew. - Return 200 quickly. Acknowledge receipt synchronously and do business logic in a background job.
- Deduplicate by delivery id. The same event can be delivered more than once —
X-Webhook-Delivery-Idis stable across retries and replays. - Don’t rely on order. Use the payload’s
statusto decide what to do, not the sequence of arrivals. - Use HTTPS. Webhook endpoints must use HTTPS.
- Don’t log the secret. Treat the webhook secret like an API key.

