Webhooks
In this guide, we will look at how to register and consume webhooks to integrate your app with Hub. With webhooks, your app can know when something happens in Hub, such as someone sending a message or adding a contact.
Registering webhooks
To register a webhook, instead of configuring it in the Hub dashboard, you must send the postbackUrl property in the transaction route. That way, whenever a relevant event occurs, the Hub will send a notification to the specified URL.
Now, whenever a transaction takes place in your application, a webhook will be triggered by the Hub.
Transaction Status Types
- Name
CREATED
- Type
- enum
- Description
A new transaction was created and is awaiting processing.
- Name
PENDING
- Type
- enum
- Description
The transaction is in progress and awaiting confirmation.
- Name
EXPIRED
- Type
- enum
- Description
The transaction was not completed within the required time frame and is now invalid.
- Name
REFUNDED
- Type
- enum
- Description
The transaction was successfully processed but later reversed, returning the funds to the payer.
- Name
REFUSED
- Type
- enum
- Description
The transaction was rejected due to issues such as insufficient funds, fraud detection, or policy restrictions.
- Name
APPROVED
- Type
- enum
- Description
The transaction was successfully processed and authorized.
- Name
CANCELED
- Type
- enum
- Description
The transaction was manually or automatically canceled before being processed or approved.
- Name
CHARGEBACK
- Type
- enum
- Description
The payer disputed the transaction with their bank, leading to a forced refund.
- Name
IN_ANALYSIS
- Type
- enum
- Description
The transaction is under review, possibly for fraud prevention or compliance checks.
- Name
PRECHARGEBACK
- Type
- enum
- Description
The transaction is flagged as at risk of a chargeback due to a customer dispute or complaint.
Example payload
{
"id": "18017579377364992",
"status": "PENDING",
"total": 400,
"method": "PIX",
"qrcode": "00020101021226870014br.gov.bcb.pix2565qrcode.santsbank.com/dynamic/cf1e1064-930c-42ec-9abf-03871cad65c15204000053039865802BR5910SYFRA LTDA6009SAO PAULO62070503***63045B62",
"invoice": null,
"currency": "BRL",
"identifier": "38169107220140032",
"endtoend": "DASD7AS89E12JKLJASk9423",
"external_ref": "external_ref_order",
"customer": {
"id": "18017579247341568",
"name": "John Doe",
"email": "john.doe@example.com",
"phone": "11999999999",
"document": "12468239008",
},
"created_at": "2025-02-19T17:15:25.688Z",
"updated_at": "2025-02-19T17:15:26.703Z",
},
Cashout Status Types
- Name
PAID
- Type
- enum
- Description
The withdrawal was successfully completed and the funds were transferred.
- Name
ERROR
- Type
- enum
- Description
An error occurred during the withdrawal process, and the funds were not transferred.
- Name
REQUESTED
- Type
- enum
- Description
The withdrawal request was created and is awaiting processing.
- Name
PARTIALLY_PAID
- Type
- enum
- Description
The withdrawal was partially completed — some batches were processed successfully, while others either failed or are still pending.
Example payload
{
"id": "38508223304568832",
"status": "PAID",
"requested": 200,
"paid": 200,
"receipt": [
{
"status": "PAID",
"amount": 200,
"endtoend": "E3038525920250417164723123b9c2d",
"identifier": "f49b3c1a-29d7-4c9e-8fa3-3e4c2f21e9a4",
"receiver_name": "John doe",
"receiver_bank": "BANCO INTER S.A.",
"receiver_bank_ispb": "00416968"
}
]
},
Security
To know for sure that a webhook was, in fact, sent by Hub instead of a malicious actor, you can verify the request signature. Each webhook request contains a header named x-protocol-signature
, and you can verify this signature by using your secret webhook key. The signature is an HMAC hash of the request payload hashed using your secret key. Here is an example of how to verify the signature in your app:
Verifying a request
const signature = req.headers['x-protocol-signature']
const hash = crypto.createHmac('sha256', secret).update(payload).digest('hex')
if (hash === signature) {
// Request is verified
} else {
// Request could not be verified
}
If your generated signature matches the x-protocol-signature
header, you can be sure that the request was truly coming from Hub. It's essential to keep your secret webhook key safe — otherwise, you can no longer be sure that a given webhook was sent by Hub. Don't commit your secret webhook key to GitHub!