# Primeros pasos

Acepta pagos NFC desde tu propia app de comercio utilizando los SDK de MONEI Pay.

## Cómo funciona[​](#cómo-funciona "Enlace directo al Cómo funciona")

<!-- -->

1. Tu **backend** genera un token de autenticación POS usando tu clave de API de MONEI
2. Tu **app de comercio** recibe el token a través de tu propia API
3. La app llama a `acceptPayment()` con el token y el importe
4. El SDK abre MONEI Pay (o CloudCommerce en Android) para el pago NFC por contacto
5. El resultado del pago se devuelve a tu app

### Descarga MONEI Pay[​](#descarga-monei-pay "Enlace directo al Descarga MONEI Pay")

[![Descarga MONEI Pay en el App Store](/img/app-store-icon.svg)](https://apps.apple.com/app/monei-pay/id6478438783)[![Descarga MONEI Pay en Google Play](/img/google-play-icon.svg)](https://play.google.com/store/apps/details?id=com.monei.pay)

## Paso 1: Obtén tu clave de API[​](#paso-1-obtén-tu-clave-de-api "Enlace directo al Paso 1: Obtén tu clave de API")

1. Regístrate en [dashboard.monei.com](https://dashboard.monei.com/register)
2. Ve a **Ajustes → Claves de API**
3. Usa la clave de **prueba** para desarrollo y la clave de **producción** para entornos en vivo

## Paso 2: Genera un token de autenticación POS[​](#paso-2-genera-un-token-de-autenticación-pos "Enlace directo al Paso 2: Genera un token de autenticación POS")

Tu backend llama a la API de MONEI para crear un token por cada sesión de pago. El token es válido durante **24 horas** — puedes reutilizarlo para múltiples transacciones dentro de ese período. Nunca expongas tu clave de API en la app de comercio. Consulta la referencia completa de la API [Crear token de autenticación POS](https://docs.monei.com/es/es/apis/rest/pos-auth-token-create/.md).

* cURL
* Node.js
* Python
* PHP

```
curl -X POST https://api.monei.com/v1/pos/auth-token \

  -H "Authorization: YOUR_API_KEY"

# Optional: scope to a specific terminal or store

#   -H "Content-Type: application/json" \

#   -d '{"pointOfSaleId": "pos_abc123", "storeId": "store_xyz"}'
```

server.js

```
import {Monei} from '@monei-js/node-sdk';



const monei = new Monei('YOUR_API_KEY');



const {token} = await monei.posAuthToken.create();

// Optional: .create({pointOfSaleId: 'pos_abc123', storeId: 'store_xyz'})

// Send `token` to your merchant app
```

server.py

```
import Monei



monei = Monei.MoneiClient(api_key="YOUR_API_KEY")



result = monei.pos_auth_token.create()

# Optional: monei.pos_auth_token.create(

#     CreatePosAuthTokenRequest(point_of_sale_id="pos_abc123", store_id="store_xyz")

# )

token = result.token

# Send `token` to your merchant app
```

server.php

```
<?php

require_once 'vendor/autoload.php';



use Monei\MoneiClient;



$monei = new MoneiClient('YOUR_API_KEY');



$result = $monei->posAuthToken->create();

// Optional: ->create(new CreatePosAuthTokenRequest(['point_of_sale_id' => 'pos_abc123', 'store_id' => 'store_xyz']))

$token = $result->getToken();

// Send $token to your merchant app

?>
```

### Parámetros de la solicitud[​](#parámetros-de-la-solicitud "Enlace directo al Parámetros de la solicitud")

| Parámetro       | Tipo   | Requerido | Descripción                                                                                             |
| --------------- | ------ | --------- | ------------------------------------------------------------------------------------------------------- |
| `pointOfSaleId` | String | No        | Identificador único del punto de venta. Si se especifica, el pago queda vinculado a ese punto de venta. |
| `storeId`       | String | No        | Identificador único de la tienda. Si se especifica, el pago queda vinculado a esa tienda.               |

### Respuesta[​](#respuesta "Enlace directo al Respuesta")

```
{

  "token": "eyJhbGciOiJSUzI1NiIs..."

}
```

El token es un JWT (firmado con RS256) que contiene el ID de cuenta y los metadatos del comercio. Expira después de **24 horas**. Genera uno por sesión — no necesitas un token nuevo para cada transacción.

## Paso 3: Integra tu app[​](#paso-3-integra-tu-app "Enlace directo al Paso 3: Integra tu app")

Instala el SDK, configura tu proyecto, llama a `acceptPayment()` con el token del Paso 2 y gestiona los resultados. Cada guía cubre la instalación, la configuración de la plataforma, la referencia del SDK, la app de ejemplo y la resolución de problemas.

* **[iOS](https://docs.monei.com/es/es/monei-pay/app-integration/ios/.md)** — SDK en Swift mediante SPM o CocoaPods
* **[Android](https://docs.monei.com/es/es/monei-pay/app-integration/android/.md)** — SDK en Kotlin mediante GitHub Packages o JitPack, modos Direct y Via MONEI Pay
* **[React Native](https://docs.monei.com/es/es/monei-pay/app-integration/react-native/.md)** — Módulo Expo, multiplataforma con una sola API
* **[Web](https://docs.monei.com/es/es/monei-pay/app-integration/web/.md)** — POS basado en navegador. Sin SDK; abre el deep link de MONEI Pay desde Safari o Chrome

## Verifica los pagos desde el servidor[​](#verifica-los-pagos-desde-el-servidor "Enlace directo al Verifica los pagos desde el servidor")

El SDK devuelve un `PaymentResult` a tu app, pero siempre debes **verificar el pago desde tu backend** antes de completar un pedido. Esto evita la manipulación en el lado del cliente.

Usa el endpoint [Obtener pago](https://docs.monei.com/es/es/apis/rest/payments-get/.md) con el `transactionId` devuelto en el resultado:

```
curl https://api.monei.com/v1/payments/{transactionId} \

  -H "Authorization: YOUR_API_KEY"
```

También puedes configurar un `callbackUrl` al crear pagos para recibir notificaciones asíncronas por webhook. Consulta [Verificar firma](https://docs.monei.com/es/es/guides/verify-signature/.md) para más detalles sobre la validación de las cargas útiles del webhook.

## Entrega de resultados[​](#entrega-de-resultados "Enlace directo al Entrega de resultados")

MONEI Pay devuelve los resultados de los pagos a través de **dos canales independientes**. Cumplen funciones distintas — úsalos conjuntamente, nunca de forma intercambiable.

| Canal          | Tipo                   | Confianza        | Usar para                                                |
| -------------- | ---------------------- | ---------------- | -------------------------------------------------------- |
| `callback_url` | Webhook HTTPS firmado  | **De confianza** | Cumplimiento de pedidos, lógica de negocio, conciliación |
| `complete_url` | Redirección en cliente | NO de confianza  | Redirección UX, devolver al usuario a tu flujo           |

### `callback_url` — webhook de confianza[​](#callback_url--webhook-de-confianza "Enlace directo al callback_url--webhook-de-confianza")

Un webhook HTTPS firmado entregado de servidor a servidor con un HMAC `MONEI-Signature` verificable. Este es el **único** canal en el que debes basar las decisiones de negocio (completar pedidos, conceder acceso, enviar recibos).

* Debe ser `https://` — `http`, IPs privadas y localhost son rechazados
* Máximo 2048 caracteres
* Anulación opcional por pago; si se omite, MONEI usa el webhook configurado en tu punto de venta
* Valida la firma en el servidor antes de confiar en la carga útil — consulta [Verificar firma](https://docs.monei.com/es/es/guides/verify-signature/.md)

### `complete_url` — redirección UX[​](#complete_url--redirección-ux "Enlace directo al complete_url--redirección-ux")

Una URL que se abre en el dispositivo del usuario cuando el pago finaliza (con éxito o con error). Es una redirección única con el resultado codificado en parámetros de consulta. **No está firmada, puede suplantarse y nunca debe usarse para lógica de negocio.**

* Acepta `https://`, esquemas de URL personalizados (`mymerchant://...`), Universal Links (iOS) y App Links (Android)
* Esquemas rechazados: `http`, `tel`, `sms`, `mailto`, `javascript`, `file`, `data`, `blob`, `intent`, además de esquemas internos de la plataforma
* Máximo 2048 caracteres
* Úsalo para devolver al usuario a tu app o página — luego confirma el resultado real mediante [Obtener pago](https://docs.monei.com/es/es/apis/rest/payments-get/.md) o el webhook `callback_url`

### Parámetros de consulta del resultado al abrir `complete_url`[​](#parámetros-de-consulta-del-resultado-al-abrir-complete_url "Enlace directo al parámetros-de-consulta-del-resultado-al-abrir-complete_url")

Cuando MONEI Pay abre `complete_url`, añade los siguientes parámetros de consulta:

**Éxito:**

| Parámetro            | Descripción                                       |
| -------------------- | ------------------------------------------------- |
| `success`            | `"true"`                                          |
| `transaction_id`     | ID de transacción de MONEI                        |
| `amount`             | Importe del pago en céntimos                      |
| `card_brand`         | Marca de la tarjeta (p. ej. `visa`, `mastercard`) |
| `masked_card_number` | Número de tarjeta enmascarado (p. ej. `****1234`) |

**Error / cancelación:**

| Parámetro | Descripción                     |
| --------- | ------------------------------- |
| `success` | `"false"`                       |
| `error`   | Código de error (ver más abajo) |

**Códigos de error** que pueden aparecer en `error`:

| Código                   | Significado                                                                      |
| ------------------------ | -------------------------------------------------------------------------------- |
| `CANCELLED`              | El usuario canceló, o tu app abandonó el flujo a mitad                           |
| `TOKEN_EXPIRED`          | El token de autenticación POS ha expirado (>24h)                                 |
| `INVALID_TOKEN`          | El token de autenticación POS está mal formado o firmado con la clave incorrecta |
| `INVALID_AMOUNT`         | El importe falta, no es numérico o no es positivo                                |
| `INVALID_CALLBACK_URL`   | `callback_url` no es https estricto o supera los 2048 caracteres                 |
| `INVALID_COMPLETE_URL`   | `complete_url` usa un esquema bloqueado o supera los 2048 caracteres             |
| `NOT_AUTHENTICATED`      | No hay token POS y el usuario no ha iniciado sesión en MONEI Pay                 |
| `ACCOUNT_NOT_CONFIGURED` | La cuenta de MONEI Pay existe pero le falta la configuración POS requerida       |
| `PAYMENT_FAILED`         | Tarjeta rechazada, error de red u otro fallo posterior                           |

### Patrón recomendado[​](#patrón-recomendado "Enlace directo al Patrón recomendado")

Combina ambos canales. El webhook se dispara de forma fiable desde los servidores de MONEI incluso si el dispositivo se queda sin conexión; la redirección le proporciona al usuario una ruta de regreso limpia.

```
monei-pay://accept-payment

  ?amount=1500

  &auth_token=eyJ...

  &order_id=order_42

  &callback_url=https://merchant.com/webhook/monei

  &complete_url=https://merchant.com/checkout/done
```

Cuando se abra `complete_url`, trata los parámetros de consulta solo como una pista — confirma mediante el webhook o [Obtener pago](https://docs.monei.com/es/es/apis/rest/payments-get/.md) antes de completar el pedido.

### Conciliación con `order_id`[​](#conciliación-con-order_id "Enlace directo al conciliación-con-order_id")

Opcional. Pasa tu propio `order_id` para que aparezca como `orderId` del pago en el webhook firmado `callback_url`. Es útil cuando tu POS ya tiene una referencia de pedido (número de mesa, número de factura, ID de carrito interno) y quieres correlacionar el pago de MONEI sin una consulta adicional a la base de datos. Si se omite, MONEI genera uno.

## Problemas frecuentes[​](#problemas-frecuentes "Enlace directo al Problemas frecuentes")

| Problema                                                                | Causa                                                                   | Solución                                                                                                                                                                       |
| ----------------------------------------------------------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| El SDK devuelve "app not found"                                         | MONEI Pay (o CloudCommerce en modo Direct de Android) no está instalado | Instala la app requerida en el dispositivo                                                                                                                                     |
| Token rechazado / 401                                                   | Token expirado (>24h) o clave de API del entorno incorrecto             | Genera un token nuevo; asegúrate de usar la clave de prueba para el modo de prueba y la de producción para producción                                                          |
| NFC no funciona                                                         | NFC desactivado o dispositivo no compatible                             | Comprueba los ajustes del dispositivo; consulta la [descripción general de MONEI Pay](https://docs.monei.com/es/es/monei-pay/overview/.md) para los requisitos del dispositivo |
| El pago se completa en el dispositivo pero el backend no tiene registro | Falta la verificación en el servidor                                    | Verifica siempre mediante la API o los webhooks (ver más arriba)                                                                                                               |

## Próximos pasos[​](#próximos-pasos "Enlace directo al Próximos pasos")

* [Descripción general de MONEI Pay](https://docs.monei.com/es/es/monei-pay/overview/.md) — funcionalidades del producto y requisitos del dispositivo
* [API REST de MONEI](https://docs.monei.com/es/es/apis/rest/.md) — referencia completa de la API
* [Pruebas](https://docs.monei.com/es/es/testing/.md) — tarjetas de prueba y entorno sandbox
* [Verificar firma](https://docs.monei.com/es/es/guides/verify-signature/.md) — valida las cargas útiles del webhook
