🇧🇷 OFPI Webhooks

Charges

OBJECT_CREATED

Whenever there is a new charge created by the Belvo application (that is, when the charge 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": "CHARGES",
  "webhook_code": "OBJECT_CREATED",
  "object_id": "7d01c4cf-57ed-4ed9-b109-a5bfb2d8c42b", // The ID of the Charge
  "external_id": "c3c51aaf-aaa3-400c-926d-87ab62e195fd",
  "data": null
}

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

OBJECT_CREATED

Whenever there is a new enrollment created by the Belvo application you will receive the following webhook:

{
  "webhook_id": "3b9a69f7-0f0a-455b-832d-49ad6fd4905c",
  "webhook_type": "ENROLLMENTS",
  "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 enrollment by making the following request:

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

Where:

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

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",
    "satus_reason_code": "invalid_account_status",
    "status_reason_message":"The Enrollment status is incompatible with the operation.",
    "metadata": null,
    "details": { "status": "REJECTED" }
  }
}

Status codes and messages

Below is a list of status_reason_codes and status_reason_messages that you can receive in an Enrollment webhook when an enrollment fails:

status_reason_codestatus_reason_message
unexpectedEnrollment encountered an unexpected error.
invalid_permissionsThe permissions associated with the Enrollment do not contain "PAYMENTS_INITIATE" or contain unsupported values for this operation.
invalid_accountThe provided account does not exist or is not compatible with the non-redirect flow.
parameter_not_providedA required parameter was not provided.
invalid_parameterA parameter does not comply with the expected formatting rules.
idempotency_errorThe message content (claim data) differs from the content associated with this idempotency key (x-idempotency-key).
invalid_account_statusThe Enrollment status is incompatible with the operation.
missing_required_platform_signalsThe required signals for the user's platform were not sent in their entirety.
invalid_fido_originThe value in the response.clientDataJSON.origin field cannot be verified.
invalid_rpThe value in the response.attestationObject.authData.rpIdHash field cannot be verified.
invalid_challengeThe response.clientDataJSON.challenge field has a different encoded value than the one generated by the server.
invalid_public_keyThe public key sent is incompatible with the FIDO2 server definitions.
invalid_extensionThe extracted extensions are incompatible with the FIDO2 server security guidelines.
invalid_statusThe Enrollment status does not allow cancellation.
rejection_reasonThe rejection of the Enrollment must be associated with a rejection reason.
rejected_other_no_detailsThe use of the reason REJECTED_OTHER must be accompanied by a description (additionalInformation).
revocation_reasonThe revocation of the Enrollment must be associated with a revocation reason.
revoked_other_no_detailsThe use of the reason REVOKED_OTHER must be accompanied by a description (additionalInformation).

Payment intents

OBJECT_CREATED

Whenever there is a new payment intent created by the Belvo application (that is, when the payment intent 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": "PAYMENT_INTENTS",
  "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 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).

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).