Last updated

Payments Webhooks (Brazil)

A webhook is a web callback that Belvo uses to send notifications about a specific link.

This article is about webhooks for our Payment Initiation solution. For information regarding our Aggregation and Enrichment webhooks, check out this article

Set up webhooks

To set up a new webhook:

  1. In your Belvo dashboard, go to the payment webhooks section.

  2. In the Payments Webhooks tab, click +New webhook.

  3. Fill in the New webhook form with the required information.

    • URL: the URL to receive the webhook notifications.
    • Authorization: an optional bearer token to use if your URL is protected.
  4. Click Create webhook.

Webhook types

All webhook events come with a core payload (as described in the code example below).

{
  "webhook_id": "3b9a69f7-0f0a-455b-832d-49ad6fd4905c",
  "webhook_type": "PAYMENT_INTENTS",
  "webhook_code": "STATUS_UPDATE",
  "object_id": "d2e40773-19f6-48d1-93c3-3590ec0c74df",
  "external_id": "c3c51aaf-aaa3-400c-926d-87ab62e195fd",
  "data": {
    "status": "FAILED",
    "metadata": {"internal_reference_id": "GGq12345w2"},
    "failure_code": "consent_expired",
    "failure_message": "The payment consent was not accepted in time.",
    "end_to_end_id": "E432158152024081610416f2b595b056",
  }
}
ParameterRequiredTypeDescriptionExample
webhook_idtruestringThe Belvo webhook ID.aadf41a1fc8e4f79a49f7f04027ac999
webhook_typetruestringThe resource that this webhook relates to.CHARGES
webhook_codetruestringThe event that triggered the webhook.STATUS_UPDATE
object_idtruestringThe ID of the object this webhook relates to.d2e40773-19f6-48d1-93c3-3590ec0c74df
external_idtruestringThe unique identifier you provided when creating the object. For charges and transactions, this field will always return null.c3c51aaf-aaa3-400c-926d-87ab62e195fd
datatrueobjectAn object containing specific data about the event. The fields returned in this object depend on the webhook_type and webhook_code.See following rows.
data.statusfalsestringThe status of the charge or payment intent.FAILED
data.failure_codefalsestringIn the case that the charge or payment intent failed, a unique code for the error.consent_expired
data.failure_messagefalsestringIn the case that the charge or payment intent failed, a human-readable description of the error.The payment consent was not accepted in time.
data.end_to_end_idfalsestringThe ID of the payment in Brazil's payment system.E432158152024081610416f2b595b056
data.metadatafalseobjectIf you provided any information in the metadata object when creating your payment, it is included in the webhook body.{ "internal_reference_id": "GGq12345w2" }

For information about the data specific to a given webhook, click on the webhook type in the table below.

TypeEventSent whenever...
CHARGESSTATUS_UPDATEThere is an update to the status of a payment intent
PAYMENT_INTENTSSTATUS_UPDATEThere is an update on the status of a payment intent.
TRANSACTIONSOBJECT_CREATEDThere is a new transaction created.

Webhook outbound IP addresses

You can receive webhook events from the following IP addresses:

  • 3.130.254.46
  • 18.220.61.186
  • 18.223.45.212

We highly recommend you whitelist these IP addresses so that you can receive webhook events.

Client-side webhook response best practice

We highly recommend that once you receive a webhook you reply to Belvo with a 2XX status code within five seconds to confirm that you have received the webhook. Otherwise, our API will retry the request.

Webhook retry policy

If our system does not receive 2XX status code, it automatically tries to send the request again. This retry process will happen up to three times, with each attempt spaced 60 seconds apart. For example, if the first attempt fails, our system waits for 60 seconds before trying again and will continue this pattern until it either receives a successful response or reaches the maximum of three retries.


slug: "ofpi-webhooks"


Charges

STATUS_UPDATE

You'll receive a webhook event whenever the status of a charge is updated to:

EventSent when
SCHEDULEDThe charge is 'paused' until the scheduled payment date.
SUCCEEDEDThe charge has been confirmed and processed by the open finance network.
FAILEDThe user hasn't provided consent for the payment, or there has been a general error in the open finance network.
CANCELEDThe scheduled charge was canceled.
{
  "webhook_id": "3b9a69f7-0f0a-455b-832d-49ad6fd4905c",
  "webhook_type": "CHARGES",
  "webhook_code": "STATUS_UPDATE",
  "object_id": "d2e40773-19f6-48d1-93c3-3590ec0c74df",
  "external_id": null,
  "data": {
    "status": "SUCCEEDED", // The status of the charge.
    "metadata": {"internal_reference_id": "GGq12345w2"},
    "failure_code": null,
    "failure_message": null,
    "end_to_end_id": "E432158152024081610416f2b595b056",
  },
}
{
  "webhook_id": "3b9a69f7-0f0a-455b-832d-49ad6fd4905c",
  "webhook_type": "CHARGES",
  "webhook_code": "STATUS_UPDATE",
  "object_id": "d2e40773-19f6-48d1-93c3-3590ec0c74df",
  "external_id": null,
  "data": {
    "status": "FAILED",
    "metadata": {"internal_reference_id": "GGq12345w2"},
    "failure_code": "consent_expired",
    "failure_message": "The payment consent was not accepted in time.",
    "end_to_end_id": "E432158152024081610416f2b595b056"
  }
}

Failure codes and messages

Below is a list of failure_codes and failure_messages that you can receive in a Charges webhook when a charge fails:

CodeMessageWhen it can occur
AMOUNT_OVER_LIMITThe payment amount or the number of payments exceeds the limits set by the institution.Status Update
AUTHORIZATION_EXPIREDThe authorization time has expired.Status Update
CONSENT_PENDING_AUTHORIZATIONConsent pending authorization from multiple levels (status 'PARTIALLY_ACCEPTED')."Status Update
HOLDER_INFRASTRUCTURE_FAILUREThere was a failure in the infrastructure of the account holder.Status Update
ICP_INFRASTRUCTURE_FAILUREThere was a failure in the ICP (Infraestrutura de Chaves Públicas) infrastructure.")Status Update
INSUFFICIENT_FUNDSThe account has insufficient funds to make the payment.Status Update
INVALID_CHARGEThe charge is invalid or incorrect.Status Update
INVALID_PAYMENT_DETAILThe payment details provided are invalid.Status Update
NOT_INFORMEDNo error reason was provided by the institution.On Creation
PAYMENT_CONSENT_MISMATCHThe payment details do not match the consent provided.On Creation
PAYMENT_REFUSED_BY_HOLDERThe payment was refused by the account holder.On Creation, Status Update
PAYMENT_REFUSED_BY_SPIThe payment was refused by the SPI (Sistema de Pagamentos Instantâneos).Status Update
PAYMENT_SCHEDULING_FAILUREThere was a failure in scheduling the payment.Status Update
RECEIVING_PSP_INFRASTRUCTURE_FAILUREThere was a failure in the infrastructure of the receiving PSP (Payment Service Provider).Status Update
SAME_ORIGIN_DESTINATION_ACCOUNTSThe origin and destination accounts are the same.Status Update
SPI_INFRASTRUCTURE_FAILUREThere was a failure in the SPI infrastructure.Status Update
SPI_REJECTED_PAYMENTPayment rejected in the Instant Payment System (SPI).Status Update
USER_REJECTEDThe user rejected the authorization of the consent.Status Update

Customers

OBJECT_CREATED

Whenever there is a new customer created by the Belvo application (that is, when the customer is created asynchronously and not as a result of a direct POST call), you will receive the following webhook:

{
  "webhook_id": "3b9a69f7-0f0a-455b-832d-49ad6fd4905c",
  "webhook_type": "CUSTOMERS",
  "webhook_code": "OBJECT_CREATED",
  "object_id": "7d01c4cf-57ed-4ed9-b109-a5bfb2d8c42b",
  "external_id": "c3c51aaf-aaa3-400c-926d-87ab62e195fd",
  "data": null
}

Once you receive the notification, you can get details on the customer by making the following request:

curl --request GET 'https://api.belvo.com/payments/br/customers/{id}/' \
  -u [Secret Key ID]:[Secret Key PASSWORD]

Where:

  • id is the object_id of the customer (which you receive in the webhook event).

Enrollments

STATUS_UPDATE

You'll receive a webhook event whenever the status of a enrollment is updated to:

EventSent when
PENDINGThe enrollment is awaiting biometric details to be sent through.
SUCCEEDEDThe enrollment was accepted by the institution.
FAILEDThe enrollment was rejected by the institution.
{
  "webhook_id": "9f91116b-bfe1-45f2-8ae3-aa604161c4aa",
  "webhook_type": "ENROLLMENTS",
  "webhook_code": "STATUS_UPDATE",
  "object_id": "06a51b80-708d-49c9-8620-7b0fd2fbc548",
  "external_id": "c3c51aaf-aaa3-400c-926d-87ab62e195fd",
  "data": {
    "status": "PENDING",
    "metadata": null,
    "details": { "status": "AWAITING_ENROLLMENT" }
  }
}
{
  "webhook_id": "9f91116b-bfe1-45f2-8ae3-aa604161c4aa",
  "webhook_type": "ENROLLMENTS",
  "webhook_code": "STATUS_UPDATE",
  "object_id": "e64de9d0-0045-49ad-b1ee-779a9c269ab3",
  "external_id": "c3c51aaf-aaa3-400c-926d-87ab62e195fd",
  "data": {
    "status": "SUCCEEDED",
    "metadata": null,
    "details": { "status": "AUTHORIZED" }
  }
}
{
  "webhook_id": "9f91116b-bfe1-45f2-8ae3-aa604161c4aa",
  "webhook_type": "ENROLLMENTS",
  "webhook_code": "STATUS_UPDATE",
  "object_id": "e64de9d0-0045-49ad-b1ee-779a9c269ab3",
  "external_id": "c3c51aaf-aaa3-400c-926d-87ab62e195fd",
  "data": {
    "status": "FAILED",
    "metadata": null,
    "details": { "status": "REJECTED" }
  }
}

Payment intents

STATUS_UPDATE

You'll receive a webhook event whenever the status of a payment intent is updated to:

EventSent when
REQUIRES_PAYMENT_METHODAdditional details are required to complete the payment intent flow.
REQUIRES_ACTIONYou have sent through confirm=true in the payment intent flow and Belvo now initiates the payment flow in the open finance network.
PROCESSINGThe payment is being processed in the open finance network.
SCHEDULEDThe payment is 'paused' until the scheduled payment date.
CANCELEDThe scheduled payment intent was canceled.
SUCCEEDEDThe payment has been confirmed and processed by the open finance network.
FAILEDThe payment has been rejected by the user, the user hasn't provided consent for the payment, or there has been a general error in the open finance network.
`STATUS_UPDATE` webhook when using payment links

You will also receive STATUS_UPDATE webhooks when using payment links. Please see the Widget payment process of our OFPI inflow payments article for in-depth information regarding when each webhook event is sent.

{
  "webhook_id": "3b9a69f7-0f0a-455b-832d-49ad6fd4905c",
  "webhook_type": "PAYMENT_INTENTS",
  "webhook_code": "STATUS_UPDATE",
  "object_id": "d2e40773-19f6-48d1-93c3-3590ec0c74df",
  "external_id": "c3c51aaf-aaa3-400c-926d-87ab62e195fd",
  "data": {
    "status": "SUCCEEDED",
    "end_to_end_id": "E432158152024081610416f2b595b056",
    "metadata": {"internal_reference_id": "GGq12345w2"}
  },
}
{
  "webhook_id": "3b9a69f7-0f0a-455b-832d-49ad6fd4905c",
  "webhook_type": "PAYMENT_INTENTS",
  "webhook_code": "STATUS_UPDATE",
  "object_id": "d2e40773-19f6-48d1-93c3-3590ec0c74df",
  "external_id": "c3c51aaf-aaa3-400c-926d-87ab62e195fd",
  "data": {
    "status": "FAILED",
    "metadata": {"internal_reference_id": "GGq12345w2"},
    "failure_code": "consent_expired",
    "failure_message": "The payment consent was not accepted in time.",
    "end_to_end_id": "E432158152024081610416f2b595b056",
  }
}

Once you receive the notification, you can get details on the payment intent by making the following request:

curl --request GET 'https://api.belvo.com/payments/br/payment-intents/{id}' \
  -u [Secret Key ID]:[Secret Key PASSWORD]

Where:

  • id is the object_id of the payment intent (which you receive in the webhook event).

Failure codes and messages

Below is a list of failure_codes and failure_messages that you can receive in a Payment Intents webhook when a charge fails:

CodeMessageWhen it can occur
AMOUNT_OVER_LIMITThe payment amount or the number of payments exceeds the limits set by the institution.Status Update
AUTHORIZATION_EXPIREDThe authorization time has expired.Status Update
CONSENT_PENDING_AUTHORIZATIONConsent pending authorization from multiple levels (status 'PARTIALLY_ACCEPTED')."Status Update
HOLDER_INFRASTRUCTURE_FAILUREThere was a failure in the infrastructure of the account holder.Status Update
ICP_INFRASTRUCTURE_FAILUREThere was a failure in the ICP (Infraestrutura de Chaves Públicas) infrastructure.")Status Update
INSUFFICIENT_FUNDSThe account has insufficient funds to make the payment.Status Update
INVALID_CHARGEThe charge is invalid or incorrect.Status Update
INVALID_PAYMENT_DETAILThe payment details provided are invalid.Status Update
NOT_INFORMEDNo error reason was provided by the institution.On Creation
PAYMENT_CONSENT_MISMATCHThe payment details do not match the consent provided.On Creation
PAYMENT_REFUSED_BY_HOLDERThe payment was refused by the account holder.On Creation, Status Update
PAYMENT_REFUSED_BY_SPIThe payment was refused by the SPI (Sistema de Pagamentos Instantâneos).Status Update
PAYMENT_SCHEDULING_FAILUREThere was a failure in scheduling the payment.Status Update
RECEIVING_PSP_INFRASTRUCTURE_FAILUREThere was a failure in the infrastructure of the receiving PSP (Payment Service Provider).Status Update
SAME_ORIGIN_DESTINATION_ACCOUNTSThe origin and destination accounts are the same.Status Update
SPI_INFRASTRUCTURE_FAILUREThere was a failure in the SPI infrastructure.Status Update
SPI_REJECTED_PAYMENTPayment rejected in the Instant Payment System (SPI).Status Update
USER_REJECTEDThe user rejected the authorization of the consent.Status Update

Transactions

OBJECT_CREATED

Whenever there is a new transaction created, you will receive the following webhook:

{
  "webhook_id": "3b9a69f7-0f0a-455b-832d-49ad6fd4905c",
  "webhook_type": "TRANSACTIONS",
  "webhook_code": "OBJECT_CREATED",
  "object_id": "d2e40773-19f6-48d1-93c3-3590ec0c74df",
  "data": {
    "metadata": {"internal_reference_id": "GGq12345w2"},
    "end_to_end_id": "E432158152024081610416f2b595b056",
  },
}

Once you receive the notification, you can get details on the transaction by making the following request:

curl --request GET 'https://api.belvo.com/payments/br/transactions/{id}/' \
  -u [Secret Key ID]:[Secret Key PASSWORD]

Where:

  • id is the object_id of the transaction (which you receive in the webhook event).