Skip to content
Last updated

Payment Webhooks (Mexico)

A webhook is a web callback that Belvo uses to send notifications about a specific link. You will need to set up webhooks in order to use Belvo's APIs.

Webhook Services

You can use services like Webhook.site or Pipedream to create temporary endpoints for testing.

Setting up your webhooks

To set up a webhook:

  1. Log in to your Direct Debit Portal. (Sandbox Login | Production Login)
  2. Go to Developers -> Webhooks. (Sandbox Webhooks | Production Webhooks)
  3. Click New webhook.
  4. Enter your URL.
  5. Select the events you want to receive, or select All events.
  6. Optionally, enter an authentication token. See Authentication.
  7. Click Create webhook.

✅ Your webhook is successfully added.

You can add up to 5 webhooks. To edit a webhook, click its row in the list. Use the Active / Inactive toggle to pause or resume deliveries to a webhook without deleting it, and the delete icon to remove it. Inactive webhooks do not receive any events.

Multiple webhooks

Each event is delivered to every active webhook that is subscribed to its eventType (or to All events). Every webhook receives the same payload.

If two webhooks are subscribed to the same event, both receive it. This is intentional, so you can send the same events to different systems, such as your backend and a monitoring tool.

Authentication

Each webhook can have its own authentication token. When a token is set, every request to that webhook includes it in the Authorization header:

Authorization header
Authorization: Bearer <token>

Verify this header on your server to make sure the request comes from Belvo.

Test your webhook

To check that your webhook is reachable, click Test on the webhook's row and select an event type. The list shows the event types the webhook is subscribed to (all of them if it is subscribed to All events). Belvo sends a sample payload for the selected event type to your URL.

The Event delivery panel shows the request that was sent, along with the response code and body returned by your server. Click Resend to send it again. Test deliveries are not retried.

Webhook Payload

Webhook Payload Example (Success)
{
  "eventType": "payment_request_update",
  "eventCode": "payment_request_successful",
  "datetime": "2022-01-01T12:34:56.789Z",
  "details": {
    "id": "3118128a-6792-4b06-bd61-4acf6f6ad6b5",
    "reference": "your_reference_here",
    "status": "successful",
    "amount": 100.5,
    "failedReason": null,
    "failedMessage": null
  }
}
Penny Validation Results

The result of a penny validation is delivered through the payment method registration webhooks. A successful validation sends payment_method_registration_successful (the payment method becomes active), while a failed validation sends payment_method_registration_failed with a failedReason of account_validation_failed. For more information, see our dedicated Penny Validation guide.

Parameter TypeDescription
eventTypestringThe type of the API resource event. Can be one of: consent_update, customer_update, payment_method_update, payment_request_update, or withdrawal_update.
eventCodestringThe code of the webhook event. For details regarding the possible values, please see the Webhook Event Codes section below.
datetimestringThe ISO-8601 timestamp when the event was sent.
detailsobjectAn object containing specific data about the event.
details.idstringThe Belvo ID of the API resource (Customer, Payment Method, Payment Request, or Withdrawal) that the event is related to.
details.referencestringIf you provided a reference when creating the resource, an optional description of the object.
details.statusstringThe status of the resource.
details.amountnumberThe amount of the payment request. This field is present for all payment_request event codes.

details.failedReason

string

If the status is failed or canceled, this field contains a failure code. This field is null if the status is not failed or canceled.

For details regarding the expected failedReason and failedMessage (including the list of possible values), please see our Direct Debit Bank Errors guide.

details.failedMessage

string

If the status is failed or canceled, this field contains a description of the failure. This field is null if the status is not failed or canceled.

For details regarding the expected failedReason and failedMessage (including the list of possible values), please see our Direct Debit Bank Errors guide.

details.documentNumberstringIf the event is related to a customer, this field contains the RFC or CURP of the customer related to the direct debit payment method. This field is only available for customer-related events.
details.paymentMethodIdstringIf the event is related to a consent, this field contains the ID of the associated payment method. This field is only available for consent-related events.
details.reasonsarrayIf the event is consent_rejected or consent_incomplete_information, this field lists the files that failed validation. Each item has a fileType (id_front, id_back, selfie, or contract) and a code. For the list of possible codes, see Consent rejection reasons. This field is only available for these two consent events, and only when there is at least one reason to report.
details.fromDatetimestringIf the event is related to a withdrawal, this field contains the ISO-8601 timestamp of the start of the settlement period. This field is only available for withdrawal-related events.
details.toDatetimestringIf the event is related to a withdrawal, this field contains the ISO-8601 timestamp of the end of the settlement period. This field is only available for withdrawal-related events.
details.extraobjectIf the event is related to a withdrawal, this field contains additional information about the withdrawal. This field is only available for withdrawal-related events.

For information about specific payloads for a given API resource and webhook code, just click on the webhook Event Code in the table below.

Webhook Event Codes

The Event Type column is what you subscribe to when you set up a webhook.

ResourceEvent Type Event Code Sent whenever...
Customerscustomer_updatecustomer_blockedthe customer related to the direct debit payment method was blocked due to suspicious activity. This webhook is sent globally to all merchants, even if they don't have the blocked customer registered, since the block list is shared across all merchants.
Customerscustomer_updatecustomer_unblockedthe customer related to the direct debit payment method was unblocked after review by relevant parties.
Consentsconsent_updateconsent_submittedall required documents have been uploaded for the consent.
Consentsconsent_updateconsent_confirmedthe consent has been approved and is now active.
Consentsconsent_updateconsent_incomplete_informationdocuments are missing or invalid for the consent.
Consentsconsent_updateconsent_rejectedthe consent has been denied.
Payment Methodspayment_method_updatepayment_method_registration_successfulthe registration of the direct debit payment method was successful.
Payment Methodspayment_method_updatepayment_method_registration_failedthe registration of the direct debit payment method failed.
Payment Methodspayment_method_updatepayment_method_registration_canceledthe direct debit registration was canceled (usually by the owner).
Payment Requestspayment_request_updatepayment_request_successfulthe payout was successful and we received confirmation from the payment infrastructure provider.
Payment Requestspayment_request_updatepayment_request_failedan error is reported by the payment infrastructure provider.
Payment Requestspayment_request_updatepayment_request_chargebacka chargeback has been made by your customer.
Withdrawalswithdrawal_updatewithdrawal_createda withdrawal has been created and funds are being settled to the merchant.
Global Customer Blocking Notifications

When a customer is blocked due to a chargeback, all merchants receive the customer_blocked webhook, regardless of whether they have that customer registered. This is because Belvo maintains a global block list shared across all merchants to protect the entire ecosystem from fraudulent activity. The webhook is delivered to your webhooks subscribed to customer_update or to All events.

The webhook payload includes the blocked customer's documentNumber (RFC or CURP) so you can check if the customer exists in your system and take appropriate action.

The customer_blocked webhook is sent only once to each merchant (in other words, if you already received one and a new chargeback occurs for the same customer but for another merchant, you will not receive another webhook for that customer).

Consent Webhook Status Notes

The system sends webhook notifications whenever a consent status changes to allow real-time tracking of the consent lifecycle. No webhook is sent for the initial awaiting_information status.

When a consent moves to rejected or incomplete_information because of its files, the webhook includes details.reasons. It has one item for each file that failed validation, with the fileType and a code that explains the problem. If one file has several problems, we send the main one.

Code Meaning
wrong_document_typeThe file is not the expected type of document.
unreadable_documentThe file cannot be read, or the face is not clear enough to compare.
invalid_id_frontThe file is not a valid front of a Mexican government ID.
invalid_id_backThe file is not a valid back of a Mexican government ID.
invalid_selfieThe file is not a valid selfie.
invalid_contractThe file is not a valid contract.
faces_do_not_matchThe ID and the selfie are valid, but the faces do not belong to the same person. We send it for both id_front and selfie.
duplicate_fileThe same file was uploaded for more than one file type. The consent moves to incomplete_information.
validation_failedThe file did not pass validation, and we have no more specific reason. Upload a new file.
validation_unavailableThe validation service was temporarily unavailable, or a related file is missing, for example an ID front without a selfie. Try again or upload the missing file.
Webhook Payload Example (Duplicate files)
{
  "eventType": "consent_update",
  "eventCode": "consent_incomplete_information",
  "datetime": "2025-10-30T12:34:56.789Z",
  "details": {
    "id": "4fa8f2b1-3c7d-4e9a-b5c6-111111111101",
    "paymentMethodId": "4fa8f2b1-3c7d-4e9a-b5c6-111111111102",
    "status": "incomplete_information",
    "reasons": [
      { "fileType": "id_front", "code": "duplicate_file" },
      { "fileType": "id_back", "code": "duplicate_file" },
      { "fileType": "selfie", "code": "duplicate_file" },
      { "fileType": "contract", "code": "duplicate_file" }
    ]
  }
}

Best Practices

When you receive a webhook from Belvo, make sure that you respond with a 2XX status code (for example, a 200). See our Retry policy for which failures we retry.

Retry policy

We retry a webhook delivery only when your server is unreachable, times out, or responds with an HTTP 5xx status code. In those cases we retry every 60 minutes for up to 3 attempts (the initial delivery plus 2 retries).

We do not retry HTTP 4xx responses (for example 400, 404, or 418). Those are treated as client errors and the webhook is not sent again.

For example, if the first attempt fails with a 503, our system waits 60 minutes before trying again, and continues until it receives a 2XX response or reaches the maximum of 2 retries.

Retries are per webhook. If one of your webhooks fails, only that webhook is retried. Your other webhooks are not affected.

Test endpoints

Some test services (including webhook.site's default response) return 418. That is a 4xx status, so Belvo will not retry it. Configure the test endpoint to return 2XX if you want to confirm successful delivery.