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!

Was this page helpful?