> ## Documentation Index
> Fetch the complete documentation index at: https://dev-docs.pagoramp.com/llms.txt
> Use this file to discover all available pages before exploring further.

# MXN virtual accounts (Mexico)

> Issue MXN bank details for your customers and receive payments by SPEI (CLABE).

> **Enabled on request.** SPEI accounts are switched on per account. Ask Pagoramp to turn them on.

| | |
| - | - |
| Country | Mexico |
| Payment rail | SPEI (CLABE) |
| Account types | dedicated |
| Customers | Individuals and businesses |
| When it is ready | The customer verifies first. The account is ready once they are approved. |

## 1. Check availability

Ask what MXN needs for your account. The answer lists the required fields per customer type and account type.

```bash theme={null}
curl "https://pay-api.pagoramp.com/api/v1/virtual-accounts/availability?currency=MXN" \
  -H "x-api-key: YOUR_API_KEY"
```

## 2. Create the customer

Required for an individual: `firstname`, `lastname`, `email`. See [Virtual account requirements](https://dev-docs.pagoramp.com/virtual-accounts-requirements#mxn) for every combination.

```bash theme={null}
curl -X POST https://pay-api.pagoramp.com/api/v1/customers \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"firstname":"Ada","lastname":"Okafor","email":"ada@example.com"}'
```

The customer is created with `kycStatus` `incomplete` or `pending`. Anything missing for MXN can be added later with `PATCH /customers/{uuid}` before you request the account.

## 3. Request the account

```bash theme={null}
curl -X POST https://pay-api.pagoramp.com/api/v1/virtual-accounts \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"customerId":"224ca5c5-f2a6-419b-bf36-73997434d945","currency":"MXN","type":"dedicated","reference":"va_1001","redirectUrl":"https://app.example.com/verification-complete"}'
```

You must have a webhook secret set up first, or the request returns `400` with `webhook_secret_required`.

The response depends on the currency. For MXN, expect `requires_action` then `active`:

**`requires_action`**: The customer has to verify first. Send them `nextStep.url`.

```json theme={null}
{
  "status": "success",
  "message": "Virtual account created successfully",
  "data": {
    "uuid": "9a1c1c52-7b8e-4a52-9f0e-3e6b0a8d6c11",
    "reference": "va_1001",
    "status": "requires_action",
    "currency": "MXN",
    "type": "dedicated",
    "bankDetails": null,
    "customer": {
      "uuid": "224ca5c5-f2a6-419b-bf36-73997434d945",
      "email": "ada@example.com"
    },
    "expectedAmount": null,
    "expiresAt": null,
    "nextStep": {
      "type": "verification_link",
      "url": "https://verify.example.com/abc"
    },
    "statusReason": null,
    "metadata": {
      "orderId": "12345"
    },
    "createdAt": "2026-10-16T09:31:00.000Z"
  }
}
```

**`active`**: Ready. Show the bank details to your payer.

```json theme={null}
{
  "status": "success",
  "message": "Virtual account created successfully",
  "data": {
    "uuid": "9a1c1c52-7b8e-4a52-9f0e-3e6b0a8d6c11",
    "reference": "va_1001",
    "status": "active",
    "currency": "MXN",
    "type": "dedicated",
    "bankDetails": {
      "rail": "spei",
      "accountName": "ACME PAY / ADA OKAFOR",
      "accountNumber": "646284259102681222",
      "clabe": "646284259102681222",
      "extra": {
        "paymentRails": [
          "spei"
        ]
      }
    },
    "customer": {
      "uuid": "224ca5c5-f2a6-419b-bf36-73997434d945",
      "email": "ada@example.com"
    },
    "expectedAmount": null,
    "expiresAt": null,
    "nextStep": null,
    "statusReason": null,
    "metadata": {
      "orderId": "12345"
    },
    "createdAt": "2026-10-16T09:31:00.000Z"
  }
}
```

If the request is rejected straight away you get `422` with the reason in `errors[0].reason` and no account is created. If it is rejected later you receive `virtual_account.failed` with a `reason`. See [Webhooks](https://dev-docs.pagoramp.com/webhooks#account-status-events).

## 4. Show the details to your payer

Show these fields from `bankDetails`:

| Label | Field |
| - | - |
| Beneficiary | `accountName` |
| CLABE | `clabe` |

How your payer sends the money:

1. Open their Mexican banking app and choose a SPEI transfer.
2. Enter the CLABE as the destination account.
3. SPEI runs around the clock and settles in seconds.

## 5. Receive the payment

When the payment arrives you receive `virtual_account.payment.received`. Amounts are decimal strings in MXN; `destinationAmount` is in USD, after any fees.

```json theme={null}
{
  "event": "virtual_account.payment.received",
  "data": {
    "transaction": {
      "reference": "va-17912345678901234",
      "status": "Success",
      "sourceAmount": "1000.00",
      "sourceCurrency": "MXN",
      "destinationAmount": "54.21",
      "destinationCurrency": "USD",
      "fees": {
        "sourceTotalFee": "0.00"
      }
    },
    "virtualAccount": {
      "uuid": "9a1c1c52-7b8e-4a52-9f0e-3e6b0a8d6c11",
      "reference": "va_1001",
      "currency": "MXN",
      "type": "dedicated"
    },
    "customer": {
      "uuid": "224ca5c5-f2a6-419b-bf36-73997434d945",
      "email": "ada@example.com",
      "externalReference": null
    },
    "sender": {
      "name": "ADA OKAFOR",
      "bank": "BBVA Mexico",
      "accountNumber": "******6789"
    },
    "occurredAt": "2026-10-16T10:02:00.000Z"
  }
}
```

Verify the signature before you trust it, and use `data.transaction.reference` to ignore repeats. See [Webhooks](https://dev-docs.pagoramp.com/webhooks).

## Things to handle

* The CLABE is also returned as `accountNumber`.
* Payments are converted to USD when they arrive, at the rate in force at that moment. `destinationAmount` is what you are settled.
* A payment can be held for review. You receive `virtual_account.payment.manual_review` with a `review.reason`, then `received` or `rejected` after a decision.
* `GET /virtual-accounts/{uuid}` returns the current status at any time, and `POST /virtual-accounts/{uuid}/deactivate` stops the account accepting payments.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.