Skip to main content

Webhooks

Your account can be configured so that when certain events occur on your account, a HTTP POST request containing JSON data pertaining to that event is sent to one or more URLs of your choosing. These URLs can be configured inside your settings making a request to our team. Notifications of all events listed below are sent to all the configured URLs.


Types of webhooks​

TypeDescription
PAYMENTWhen you send a pix payment.
PAYMENT FAILEDWhen you send a pix payment and it fails.
DEVOLUTIONWhen you send a pix devolution.
DEVOLUTION FAILEDWhen you send a pix devolution and it fails.
DEVOLUTION RECEIVEDWhen receive a pix devolution.
DEVOLUTION RECEIVED FAILEDWhen a received pix devolution fails.
DEPOSITWhen receive a pix deposit.
DEPOSIT RECEIVED FAILEDWhen a received pix deposit fails.
WALLET ACCOUNT BALANCE UPDATEDWhen the balance is updated.


Credentials (Not required)​

Each webhook registration can have one credential. You generate the credential value and share it with our team through a secure channel when you register the webhook. We send it in an HTTP header on every request to that webhook, exactly as registered.

TypeHeader we sendValue
Authorization BasicAuthorizationbase64 of username:password
Authorization BearerAuthorizationAPI key or token
Signature Verificationzro-signatureShared secret key
Custom headerHeader name of your choiceAPI key or token

No prefix such as Basic or Bearer is added. If your server expects one, include it in the value you register.



Verifying Webhook Requests​

When a credential is configured, webhook requests are authenticated only by its header:

  • The value is static: it is the same on every request and carries no timestamp or nonce.
  • No signature, such as an HMAC, is computed, and the payload is not signed. With the Signature Verification type, the zro-signature header carries the shared secret key itself.
  • The same mechanism applies to every webhook type. The credential is configured per webhook registration.

To verify a request, compare the header value with the credential you registered and reject the request if they differ:

const crypto = require('node:crypto');

const expected = Buffer.from(process.env.WEBHOOK_CREDENTIAL);

function isAuthenticWebhook(request) {
// Node.js lowercases header names: use `zro-signature`, `authorization`
// or your custom header name in lowercase.
const received = Buffer.from(request.headers['zro-signature'] ?? '');

return (
received.length === expected.length &&
crypto.timingSafeEqual(received, expected)
);
}


Retry Policy​

A delivery succeeds when your endpoint responds with a 2xx status. A delivery fails when:

  • the response has any other status, including 4xx and 5xx;
  • no response arrives within the request timeout;
  • the connection fails (for example, DNS, TLS or connection refused).

Failed deliveries are retried only if a retry policy is configured for your webhook. Otherwise, each event is sent once. The policy defines:

  • Maximum attempts: the total number of deliveries, including the first one.
  • Initial interval and multiplier: each wait is the previous one multiplied by the multiplier, starting from the initial interval, with a random variation.
  • Maximum interval: the longest wait between two attempts. Once it is reached, the remaining attempts use this interval.

There is no setting for the total retry period. It results from the maximum attempts and the intervals.

Ask our team to set or confirm the retry policy and the request timeout when you register or update the webhook.

When the last attempt fails, the event is not sent again. Use the query endpoints to reconcile events you did not receive.

The same event can arrive more than once, for example when your endpoint processes it but responds after the timeout. Process webhooks idempotently.



Payloads (Version 1)​

{
"id": "4b344f93-68fb-4ddc-83b4-6288eb7c63ce",
"type": "PAYMENT",
"end_to_end_id": "E26264220202404171729SrlHOwU3HqB",
"txid": null,
"operation_id": "0f0aca83-8ea1-5ecb-9fe9-d31782ef06fb",
"amount": "270",
"owner_name": "Z.ro Bolsao",
"owner_person_type": "CNPJ",
"owner_document": "00000000000000",
"beneficiary_name": "Name",
"beneficiary_person_type": "CPF",
"beneficiary_document": "***000000**",
"beneficiary_bank_name": "ZERO IP S/A",
"beneficiary_bank_ispb": "26264220",
"created_at": "2024-04-17T17:30:00.020Z"
}

Payloads (Version 2)​

{
"id": "10b66e97-c747-4dcb-92ad-da1420a0a6b9",
"type": "DEVOLUTION_RECEIVED",
"end_to_end_id": "D26264220202404171733p6FuxQmuCKp",
"txid": null,
"operation_id": "fbfe1a0f-011f-5edb-a01d-19e669a6d853",
"original_id": "4b344f93-68fb-4ddc-83b4-6288eb7c63ce",
"original_end_to_end_id": "E26264220202404171729SrlHOwU3HqB",
"amount": "270",
"owner_name": "Name",
"owner_document": "***000000**",
"owner_bank_name": "ZERO IP S/A",
"owner_bank_ispb": "26264220",
"beneficiary_name": "Name",
"beneficiary_account_number": "000000",
"beneficiary_branch_number": "0000",
"beneficiary_document": "***000000**",
"beneficiary_bank_name": "ZERO IP S/A",
"beneficiary_bank_ispb": "26264220",
"created_at": "2024-04-17T17:33:05.712Z"
}

Payloads (Version 3)​

{
"id": "a839f358-0e39-409e-b9a5-5a56b18ba3f2",
"type": "DEPOSIT",
"end_to_end_id": "E26264220202404171333Hq7F9SWyvUE",
"txid": null,
"operation_id": "7da84c17-d40c-5bc1-9b69-867d1460736b",
"amount": "63",
"owner_name": "Z.ro Bolsao",
"owner_document": "00000000000",
"owner_bank_name": "ZERO IP S/A",
"owner_bank_ispb": "26264220",
"owner_branch_number": null,
"owner_account_number": null,
"beneficiary_name": "Name",
"beneficiary_account_number": "000000",
"beneficiary_branch_number": "0000",
"beneficiary_document": "***000000**",
"beneficiary_bank_name": "ZERO IP S/A",
"beneficiary_bank_ispb": "26264220",
"created_at": "2024-04-17T13:33:41.071Z"
}

Payloads (Version 4)​

{
"id": "a839f358-0e39-409e-b9a5-5a56b18ba3f2",
"type": "DEPOSIT",
"end_to_end_id": "E26264220202404171333Hq7F9SWyvUE",
"txid": null,
"operation_id": "7da84c17-d40c-5bc1-9b69-867d1460736b",
"amount": "63",
"owner_name": "Z.ro Bolsao",
"owner_document": "00000000000",
"owner_bank_name": "ZERO IP S/A",
"owner_bank_ispb": "26264220",
"owner_branch_number": "0000",
"owner_account_number": "000000",
"owner_account_type": "CACC",
"beneficiary_name": "Name",
"beneficiary_account_number": "000000",
"beneficiary_branch_number": "0000",
"beneficiary_document": "***000000**",
"beneficiary_bank_name": "ZERO IP S/A",
"beneficiary_bank_ispb": "26264220",
"created_at": "2024-04-17T13:33:41.071Z"
}