---
title: "How to add a \"Send to Mexico by SPEI\" feature to your neobank app"
seoTitle: "How to add SPEI transfers to your neobank app"
description: "Build a Send to Mexico by SPEI feature: CLABE check-digit validation, the quote screen, payout, tracking keys, Pix vs SPEI, and CLABEs for receiving."
date: "2026-10-21"
updated: "2026-10-21"
category: "payments"
author: "BlindPay Team"
howto:
  name: "How to add a Send to Mexico by SPEI feature to a neobank app"
  steps:
    - name: "Verify the sender"
      text: "Make sure the user has accepted the terms of service and passed KYC, so payouts can be created for them."
    - name: "Collect and validate the CLABE"
      text: "Ask for the recipient's 18-digit CLABE and full name, check the length and the check digit on the device, and show the bank the first three digits point to."
    - name: "Save the recipient as a SPEI bank account"
      text: "Store the CLABE and beneficiary name as a SPEI bank account for the customer, so repeat transfers reuse it."
    - name: "Request a live quote"
      text: "Create a payout quote in USD or MXN. The quote locks the exchange rate and fees for 5 minutes."
    - name: "Confirm and execute"
      text: "Show the MXN amount, fee, rate, and countdown. On confirm, create the payout with the quote ID and an idempotency key."
    - name: "Track and share proof"
      text: "Update the transfer from payout webhooks and give the user a receipt with the reference the recipient can use to look up the payment."
faq:
  - q: "How do I add SPEI transfers to my app?"
    a: "Use a payout API that pays out over SPEI. Your app collects the recipient's 18-digit CLABE and name, validates the check digit, and your backend saves it as a SPEI bank account. Then it requests a quote that locks the rate and fees, shows the MXN amount, and executes the payout. BlindPay runs this flow through one REST API with webhooks for every status."
  - q: "How do I validate a CLABE number?"
    a: "Check that it has exactly 18 digits. Then multiply each of the first 17 digits by the weights 3, 7, 1, repeating, keep the last digit of each product, and add them up. Take that sum modulo 10, subtract it from 10, and take the result modulo 10. The answer must equal the 18th digit. If it doesn't, the CLABE has a typo."
  - q: "How fast is a SPEI transfer?"
    a: "Banco de México runs SPEI as a real-time settlement system on a 24/7 schedule, and its user guide says a SPEI payment should not take more than 30 seconds. BlindPay lists SPEI payouts as instant once the payout executes. Show users usually within minutes and notify them when the payout webhook reports it as completed."
  - q: "Can a SPEI payment go to a debit card or phone number?"
    a: "SPEI can address an account by its 18-digit CLABE, a 16-digit debit card number, or a 10-digit phone number linked to the account, according to Banco de México. On BlindPay, the SPEI bank account takes a protocol field, and debit card or phone protocols also need the receiving institution's code. CLABE is the most common choice."
  - q: "What is the difference between Pix and SPEI for a neobank?"
    a: "Both are instant, 24/7 rails run by central banks. Pix in Brazil addresses accounts with keys such as a CPF, phone, or email. SPEI in Mexico mostly uses an 18-digit CLABE with a built-in check digit. Both work as payout destinations for a stablecoin-funded transfer feature, and both have a public reference the recipient can use to confirm arrival."
  - q: "Can my Mexican users receive SPEI deposits too?"
    a: "Yes. BlindPay issues SPEI CLABE virtual accounts: each customer gets a permanent 18-digit CLABE, and anyone with a Mexican bank account can send MXN to it by SPEI. Each deposit creates a payin at the live MXN rate and settles to the linked wallet. Payers see a pooled recipient name, which the API returns so you can tell them."
---

To add a "Send to Mexico by SPEI" feature, your app collects the recipient's 18-digit CLABE, validates its check digit, saves it as a SPEI bank account, requests a live quote, and executes a payout. BlindPay converts the stablecoins and pays MXN over SPEI through one API, and webhooks tell you when the pesos land.

This guide is the product view: screens, validation, and states. For the business payout mechanics, read [how to send USDC to a bank account in Mexico](/resources/more/how-to-send-usdc-to-bank-account-mexico). For the full build, start with [how to build a neobank](/resources/more/how-to-build-a-neobank).

**Key takeaways**

- A CLABE has a check digit. Validate it on the device and most typos never reach the payout.
- The first three digits name the bank. Show the bank name, so the user sees where the money goes before sending.
- Lock the price with a quote and show the MXN amount the recipient gets.
- SPEI runs 24/7 and gives every payment a tracking key the recipient can look up.
- From the same API, Mexican users can also get their own CLABE to receive SPEI deposits.

## What is SPEI?

SPEI is Mexico's interbank electronic payment system, run by the central bank. [Banco de México](https://www.banxico.org.mx/servicios/spei_-informacion-banco-mex.html) describes it as a real-time settlement system operating on a 24/7 schedule since 2004.

Its [user guide](https://www.banxico.org.mx/services/interbanking-electronic-payme.html) says a SPEI payment should not take more than 30 seconds. The guide also says a payer can address the account by its 18-digit CLABE, a 16-digit debit card number, or a 10-digit phone number, and that a reference number (up to seven digits) and a payment description (up to 40 characters) reach the recipient.

That last detail matters for your app. Use the description to say who sent the money, in words the recipient recognizes.

## What is a CLABE, and how is it built?

A CLABE (Clave Bancaria Estandarizada) is the standardized 18-digit account number for Mexican bank accounts. It has four parts:

| Digits | Part | What it tells you |
| --- | --- | --- |
| 1 to 3 | Bank code | Which bank holds the account |
| 4 to 6 | Branch (plaza) code | The city or branch area |
| 7 to 17 | Account number | The account itself |
| 18 | Check digit | Catches typos in the first 17 digits |

The bank code lets you show the bank's name on the confirmation screen. Keep a lookup table of bank codes in your app and refresh it when banks join or merge.

## How do you validate a CLABE before sending?

Run four checks on the device, before any API call:

1. **Digits only.** Strip spaces and dashes the user pasted.
2. **Exactly 18 digits.** Not 16 (that is a card), not 10 (that is a phone).
3. **Known bank code.** The first three digits match a bank in your table.
4. **Check digit.** Multiply each of the first 17 digits by the weights 3, 7, 1, repeating. Keep only the last digit of each product. Add them. Take the sum modulo 10, subtract from 10, then take modulo 10 again. The result must equal digit 18.

Worked example with the commonly cited sample CLABE 002010077777777771:

| Digit | 0 | 0 | 2 | 0 | 1 | 0 | 0 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | 7 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| Weight | 3 | 7 | 1 | 3 | 7 | 1 | 3 | 7 | 1 | 3 | 7 | 1 | 3 | 7 | 1 | 3 | 7 |
| Last digit of product | 0 | 0 | 2 | 0 | 7 | 0 | 0 | 9 | 7 | 1 | 9 | 7 | 1 | 9 | 7 | 1 | 9 |

The sum is 69. 69 modulo 10 is 9. 10 minus 9 is 1, and 1 modulo 10 is 1. Digit 18 is 1, so the CLABE passes.

A passing check digit means the number is well formed. It doesn't prove the account belongs to the person the user named. That is why the confirmation screen repeats the recipient's name. The guide to [verification of payee](/resources/more/verification-of-payee-instant-payments) explains what rails can and can't check.

## How do you build the feature step by step?

1. **Verify the sender.** Terms of service and KYC, once per user.
2. **Collect the CLABE and name.** One numeric input with an 18-digit mask, plus the recipient's full name. Run the four checks as the user types.
3. **Save the recipient.** Store it as a SPEI bank account for the customer. The [bank accounts docs](/docs/bank-accounts) list the fields: name, protocol, CLABE, and beneficiary name. Debit card and phone protocols also take the institution code.
4. **Request a live quote.** The user types USD to send or MXN to arrive. The quote locks rate and fees for 5 minutes ([payout quotes](/docs/payout-quotes)).
5. **Confirm and execute.** Show recipient name, bank, MXN amount, fee, rate, and a countdown. On confirm, create the payout with an `Idempotency-Key` header ([idempotency](/docs/learn/idempotency)).
6. **Track and share proof.** Update the transfer from payout webhooks. When it completes, the receipt shows the amount, rate, time, and a reference the recipient can use.

## How do Pix and SPEI compare for a neobank feature?

If you built [the Pix transfer feature](/resources/more/neobank-pix-transfer-feature), most of the flow carries over. The differences are in the recipient details and the proof.

| | Pix (Brazil) | SPEI (Mexico) |
| --- | --- | --- |
| Operator | [Banco Central do Brasil](https://www.bcb.gov.br/en/financialstability/pix_en) | Banco de México |
| Hours | Any time, including non-business days | 24/7 |
| BlindPay arrival | Instant | Instant |
| How users address the recipient | Pix key: CPF, CNPJ, phone, email, or random key | 18-digit CLABE (or debit card, or phone) |
| Built-in typo check | Format per key type | CLABE check digit |
| What to show on confirm | Recipient name, masked key | Recipient name, bank from the CLABE |
| Proof for the recipient | End-to-end ID in the bank app | Tracking key and CEP from Banxico |
| Receiving deposits on BlindPay | Pix payins | SPEI payins and SPEI CLABE virtual accounts |

For the rail-level comparison (returns, references, failure modes), see [Pix vs SPEI](/resources/more/pix-vs-spei).

## How does the recipient prove the money arrived?

With the CEP. Banco de México's [CEP lookup](https://www.banxico.org.mx/cep/) gives an electronic proof of payment for a SPEI transfer. The recipient enters the date, the tracking key or reference, the banks, the receiving account, and the amount.

Put a "Share proof" button on the receipt that copies those fields. It saves a support ticket every time a recipient says "I didn't get it".

## Can Mexican users receive SPEI deposits too?

Yes. From October 2026, BlindPay issues SPEI CLABE virtual accounts. Each customer gets a permanent 18-digit CLABE. Anyone with a Mexican bank account can send MXN to it by SPEI, any time and any amount, without a quote first. Each deposit creates a payin at the live MXN rate and settles to the wallet linked to the account.

The account is active as soon as it is created. It is not a named account: payers see a pooled recipient name, which the API returns so you can tell payers what to expect. Details are in the [virtual accounts docs](/docs/virtual-accounts).

For a neobank, that closes the loop. A user in Mexico can receive pesos into the app and send pesos out, both over SPEI.

## What does one transfer look like?

Illustrative example, with invented numbers. Diego, in Houston, pays a freelance designer in Guadalajara.

1. Diego taps "Send to Mexico" and types the designer's CLABE. The check digit passes and the app shows the bank name.
2. He types US$ 300. The quote shows MX$ 5,460.00 arriving, a US$ 3.00 fee, and a 5-minute countdown.
3. He confirms. The backend creates the payout with an idempotency key and the description "Diego Ruiz invoice 14".
4. Webhooks move the transfer to completed. Diego shares the proof fields with the designer, who pulls the CEP.

## What are the common SPEI mistakes?

- **No check-digit validation.** It is a ten-line function and it catches most typos.
- **Accepting 16 digits in the CLABE field.** That is a card number. Route it to the debit card protocol or reject it.
- **A vague payment description.** The recipient sees it. "Transfer" tells them nothing.
- **Showing only USD.** Show the MXN amount from the quote.
- **Executing an expired quote.** Requote and show the new numbers.
- **No proof on the receipt.** Recipients need the tracking key or reference for the CEP.
- **Assuming deposit accounts carry the user's name.** CLABE virtual accounts show a pooled name. Tell payers.

## How BlindPay fits

BlindPay gives a neobank one API for Mexico in both directions. Out: add the recipient as a SPEI bank account, request a quote that locks rate and fees for 5 minutes, and execute a payout that BlindPay lists as instant. In: issue a SPEI CLABE virtual account per customer, and every deposit becomes a payin that settles to the linked wallet.

Payouts are funded in USDC or USDT from the wallet you choose, so there is no peso balance to pre-fund. On non-USD local rails like SPEI, if BlindPay can't deliver a payout after collecting the stablecoins, it refunds them automatically to the quote's refund wallet, or to the sending wallet when none is set. KYC and sanctions screening run inside the API. BlindPay is the best fit for a neobank sending stablecoin-funded transfers into Mexico that wants SPEI speed and compliance handled in the same integration. To decide which rails come next, see [which payout rails to launch first](/resources/more/neobank-payout-rails-which-to-launch-first).

## What to do next

Ship the CLABE validator first, it pays off even before payouts go live. Then run one SPEI payout end to end on a development instance with the [payout quickstart](/docs/quickstart-payout).
