Account Validation Flow

Overview

This guide shows how to integrate Mexican SPEI account validation. You create a validation with type: MX_SPEI, Bitso looks up ownership on SPEI through Nvio Pagos México, and you track progress with webhooks or GET by id.

Core Resource

ResourceRole
Account validationAsynchronous ownership lookup for a Mexican account (MX_SPEI).

Every resource uses a top-level type discriminator and a matching nested object whose key is the lowercase form of type (type: MX_SPEI with an mx_spei block). Inside mx_spei.account, a second type discriminator selects the identifier: CLABE, PHONE, or DEBIT_CARD.

Step-by-Step

1. Create an account validation

  1. Call Create account validation with type: MX_SPEI, the account identifier, and expected_owner.name.
  2. Optionally send an Idempotency-Key header. Repeating the same key returns that original validation. Use a new key when you mean to start a new lookup.
  3. The response is 202 Accepted with status: PROCESSING. Store the returned id.

2. Retrieve the result

There are two ways to learn the terminal state:

  1. Webhooks (primary) — subscribe to account_validation as described in Webhook Notifications.
  2. GET by id (fallback) — poll Get account validation until status is COMPLETED or FAILED.

On COMPLETED, read mx_spei.account.verified_owner and compare it with the person you intend to pay. expected_owner is returned as you sent it. The verified name may be abbreviated, and the name parts may appear in any order. When the proof of payment (CEP) reports the identification as not available, verified_owner still includes the owner name. The identification on verified_owner is the value the CEP contained, as defined in the API Reference. A later validation returns that same identification. On FAILED, read error.code in Failed validations. HTTP errors on the request itself, such as an invalid field or a rate limit, are separate and are described in the API Reference.

3. List previous validations

Call List account validations to page through validations. Filter by status, account_number, created_at_gte, and created_at_lte. Use page_size (1–100, default 10) and page_token from next_page_token for pagination.

Account Validation Diagram

sequenceDiagram
    participant M as Merchant
    participant B as "Bitso (Nvio)"
    participant Bank as Receiving bank
    participant X as Banxico

    M->>B: Create account validation (MX_SPEI)
    B-->>M: 202 Accepted (PROCESSING)
    B->>Bank: Penny validation
    Bank->>X: Publishes the CDA
    Note over X: Publishes the CEP
    B->>X: Queries the CEP
    X-->>B: CEP
    B-->>M: Webhook account_validation (COMPLETED or FAILED)
    Note over M: GET by id as fallback

Nvio Pagos México, the Bitso entity that operates SPEI in Mexico, sends a penny validation to the receiving bank. That penny is withdrawn from the balance of the client that requested the validation. The bank publishes the CDA (comprobante digital de abono) to Banxico, the Central Bank of Mexico. Banxico publishes the CEP, and Nvio queries that CEP from Banxico. API calls and webhooks stay with Bitso.

Status Lifecycle

  • PROCESSING: Accepted and in flight. Returned on create. This regularly takes a few minutes. In a few cases it can take hours, depending on the receiving bank.
  • COMPLETED: The confirmed owner is in mx_spei.account.verified_owner. Terminal.
  • FAILED: The lookup could not be completed. Terminal. error.code says which case it was. See Failed validations.
stateDiagram-v2
    [*] --> PROCESSING
    PROCESSING --> COMPLETED
    PROCESSING --> FAILED
    COMPLETED --> [*]
    FAILED --> [*]

Response time

Nvio Pagos México sends a penny validation to the receiving bank. That penny is withdrawn from the balance of the client that requested the validation, and it shows as a withdrawal on that account. The receiving bank publishes the CDA to Banxico. Banxico publishes the CEP, and Nvio queries it there. That regularly takes a few minutes. In a few cases it can take hours, depending on the receiving bank. Busy days or other external factors at the receiving bank, such as maintenance or payroll, make a long wait more likely. Maintenance or intermittent outages in Banxico's service can delay this path as well.

If you need to answer your user quickly, handle a long PROCESSING in your own flow. Keep a timeout or a pending state on your side, and apply the webhook when it arrives. Do not block that user on the bank.

Failed validations

A FAILED validation includes error.code and error.message. These codes describe the lookup. They are not the HTTP errors returned when the request itself is rejected.

The error.message for each code is defined in the API Reference.

error.codeWhat it meansWhat to do
account_unreachableThe receiving bank did not accept the penny payment, or it refunded it.You can create a new validation, but it is unlikely to succeed.
cep_unavailableThe proof of payment (CEP) was not published after a long wait. Bitso currently waits 24 hours before setting this status. That wait can change without notice.Creating a new validation may succeed, but it does not guarantee that a CEP will be published.
cep_emptyThe CEP was retrieved and reported both the name and the identification as not available.Do not create another validation expecting a name or an identification. The CEP did not include them.
cep_mismatchThe CEP was retrieved, but the receiving bank reported in it a different account than the one the penny validation was sent to.You can create a new validation, but it is likely to return the same result.
spei_withdrawals_disabledThe penny validation could not be sent because SPEI withdrawals are temporarily disabled.Create a new validation later.
account_validation_internal_errorA technical error prevented the validation from completing.Contact Business Customer Support at [email protected].

cep_unavailable means the CEP was not published after that wait. A CEP that was found and has nothing to compare is cep_empty.

Best Practices

  • Idempotency: Send Idempotency-Key on every create so timeouts and retries do not start duplicate lookups. The same key returns the original validation.
  • Your own deadline: If your flow must respond quickly, decide how long you will wait. Banxico regularly publishes the CEP within a few minutes after the receiving bank sends the CDA. In a few cases it can take hours, depending on the receiving bank.
  • Webhooks first: Treat webhooks as the source of truth for terminal states; use GET polling as fallback.
  • Validation: Always verify webhook signatures before updating your records. See Webhook Signatures.
  • Testing: Exercise the full PROCESSING → COMPLETED / FAILED lifecycle in stage before going live. Use Set Up Your Testing Environment, and the test CLABEs in Test Account Validations to get each terminal state and a validation that stays in PROCESSING.

Did this page help you?