# Usar pagos con código QR

Crea pagos QR de un solo uso de forma programática con la API de pagos. Cada pago recibe su propio código QR de corta duración — ideal para checkouts dinámicos, kioscos y facturas generadas por tu sistema.

¿Buscas pagos QR sin código?

Para crear y gestionar **códigos QR permanentes** (reutilizables, imprimibles, con importes fijos y notificaciones de callback) desde el dashboard, consulta [tiendas y puntos de venta](https://docs.monei.com/es/manage-account/stores-and-points-of-sale.md). Para cobrar presencialmente desde un teléfono, consulta la [app MONEI Pay](https://docs.monei.com/es/monei-pay/using-the-app.md).

## Códigos QR permanentes frente a los de un solo uso[​](#permanent-vs-one-time "Enlace directo al Códigos QR permanentes frente a los de un solo uso")

|                  | Permanente                                                                                                      | De un solo uso                                                                         |
| ---------------- | --------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| **Creado desde** | [Puntos de venta del dashboard](https://docs.monei.com/es/manage-account/stores-and-points-of-sale.md#qr-codes) | API de pagos / app MONEI Pay                                                           |
| **Formato URL**  | `https://secure.monei.com/codes/{code_id}`                                                                      | `https://secure.monei.com/payments/{payment_id}/qr`                                    |
| **Reutilizable** | Sí, el mismo QR para varias transacciones                                                                       | No, un pago por QR                                                                     |
| **Importe**      | El cliente lo introduce (manual) o fijo                                                                         | Predefinido por pago                                                                   |
| **Expiración**   | Nunca (se puede deshabilitar)                                                                                   | 7 días por defecto (o `expireAt` personalizado mediante API, cualquier momento futuro) |
| **Ideal para**   | Displays estáticos, materiales impresos, mesas                                                                  | Checkout dinámico, facturas, TPV móvil                                                 |

Esta guía cubre el flujo **de un solo uso**. Para códigos permanentes, [configura un punto de venta de tipo QR](https://docs.monei.com/es/manage-account/stores-and-points-of-sale.md#points-of-sale) — sin necesidad de programar.

## Antes de empezar[​](#before-you-begin "Enlace directo al Antes de empezar")

* Necesitarás una cuenta MONEI. Encuentra tus claves de API en [MONEI Dashboard → Configuración → Acceso a API](https://dashboard.monei.com/settings/api).
* Usa las [claves en modo de prueba](https://docs.monei.com/es/testing.md) para las pruebas de integración.
* Asegúrate de que los métodos de pago relevantes estén habilitados en los ajustes de tu cuenta.
* Monitoriza los pagos de prueba en [Panel → Pagos](https://dashboard.monei.com/payments) (activa el interruptor de Modo de prueba).

Tu clave API está en [MONEI Dashboard → Configuración → Acceso a API](https://dashboard.monei.com/settings/api):

![Página Acceso a API en los ajustes del panel de MONEI, con tu ID de cuenta y tu clave API](/img/dashboard/es/settings-api-access.png)

Página Acceso a API en los ajustes del panel de MONEI, con tu ID de cuenta y tu clave API

## 1. Crear el pago (lado del servidor)[​](#1-create-a-payment-server-side "Enlace directo al 1. Crear el pago (lado del servidor)")

Crea un [Pago](https://docs.monei.com/es/apis/rest/schemas/payment.md) en tu servidor con un importe y una moneda.

![QR](/img/qr.svg)![Demo de QR](/img/qr-demo-es.png)

* cURL
* Node.js
* PHP
* Python

POST https\://api.monei.com/v1/payments

```
curl --request POST 'https://api.monei.com/v1/payments' \

--header 'Authorization: YOUR_API_KEY' \

--header 'Content-Type: application/json' \

--data-raw '{

    "amount": 110,

    "currency": "EUR",

    "orderId": "14379133960355",

    "callbackUrl": "https://example.com/checkout/callback"

}'
```

(Reemplaza `YOUR_API_KEY` con tu clave de API de MONEI real)

server.js

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



// Replace YOUR_API_KEY with your actual MONEI API key

const monei = new Monei('YOUR_API_KEY');



const payment = await monei.payments.create({

  amount: 110,

  currency: 'EUR',

  orderId: '14379133960355',

  callbackUrl: 'https://example.com/checkout/callback'

});



// You will need the paymentId from the response to generate the QR code URL

const paymentId = payment.id;



// Construct the QR code URL

const qrCodeUrl = `https://secure.monei.com/payments/${paymentId}/qr`;
```

server.php

```
<?php

require_once 'vendor/autoload.php';



use Monei\Model\CreatePaymentRequest;

use Monei\MoneiClient;



// Replace YOUR_API_KEY with your actual MONEI API key

$monei = new MoneiClient('YOUR_API_KEY');



$payment = $monei->payments->create(

  new CreatePaymentRequest([

    'amount' => 110,

    'currency' => 'EUR',

    'order_id' => '14379133960355',

    'callback_url' => 'https://example.com/checkout/callback'

  ])

);



// You will need the paymentId from the response to generate the QR code URL

$paymentId = $payment->getId();



// Construct the QR code URL

$qrCodeUrl = "https://secure.monei.com/payments/{$paymentId}/qr";

?>
```

server.py

```
import Monei

from Monei import CreatePaymentRequest



# Replace YOUR_API_KEY with your actual MONEI API key

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



payment = monei.payments.create(

    CreatePaymentRequest(

        amount=110,

        currency="EUR",

        order_id="14379133960355",

        callback_url="https://example.com/checkout/callback"

    )

)



# You will need the paymentId from the response to generate the QR code URL

payment_id = payment.id



# Construct the QR code URL

qr_code_url = f"https://secure.monei.com/payments/{payment_id}/qr"
```

**Parámetros obligatorios:**

* **amount** `positive integer`: Importe en la unidad monetaria más pequeña (p. ej., 110 para €1,10).
* **currency** `string`: [Código de moneda ISO](https://en.wikipedia.org/wiki/ISO_4217) de tres letras (p. ej., `EUR`).
* **orderId** `string`: Tu identificador de pedido único.
* **callbackUrl** `string`: La URL de tu endpoint de servidor para las notificaciones de webhook asíncronas.

**Parámetros opcionales:**

* **allowedPaymentMethods** `array`: Restringe los métodos de pago disponibles (p. ej., `["card", "bizum"]`)
* **description** `string`: Descripción del pago mostrada en la página de pago
* **customer** `object`: Rellena previamente los datos del cliente (`email`, `name`, `phone`)
* **metadata** `object`: Pares clave-valor personalizados para el seguimiento y la conciliación
* **storeId** `string`: Asocia el pago con una tienda (para agrupación y control de acceso de usuarios)
* **pointOfSaleId** `string`: Vincula el pago a un TPV (para agrupación y control de acceso de usuarios)
* **expireAt** `integer`: Marca de tiempo Unix para la expiración personalizada (por defecto: 7 días desde la creación; debe ser una fecha futura)

Consulta todos los [parámetros de la solicitud](https://docs.monei.com/es/apis/rest/payments-create.md) disponibles.

La respuesta de la API incluye el `payment.id`, que usarás en el siguiente paso.

## 2. Mostrar el código QR[​](#display-qr "Enlace directo al 2. Mostrar el código QR")

Usa el `payment.id` del Paso 1 para presentar el código QR a tu cliente.

**Opción 1: Insertar la imagen QR directamente**

Construye la URL de la imagen del código QR: `https://secure.monei.com/payments/{payment_id}/qr`

Puedes renderizarla directamente en una página web o un display:

```
<img

  src="https://secure.monei.com/payments/{{payment_id}}/qr?format=svg&size=300"

  alt="Escanear para pagar"

  width="300"

  height="300"

/>
```

* Reemplaza `{{payment_id}}` con el ID real.
* Usa `?format=svg` para SVG (por defecto es `png`).
* Usa `?size=400` para especificar el tamaño (mín: 100, máx: 1000, por defecto: 300).

![Ejemplo de QR](https://secure.monei.com/codes/RYGJ0ZFK/qr?format=svg\&size=300)

**Opción 2: Redirigir a la página de pago alojada con QR**

El [objeto Payment](https://docs.monei.com/es/apis/rest/schemas/payment.md) devuelto en el Paso 1 también contiene `payment.nextAction.redirectUrl`. Añade `?qr=1` a esta URL para obtener un enlace a una página alojada por MONEI que muestra el código QR.

Ejemplo: `https://secure.monei.com/payments/{payment_id}?qr=1`

![Página de pago alojada con QR](/es/assets/images/qr-demo-2-b4a9016b32b61c1d1b67a35812d432c0.png)

**Interacción del cliente:**

El cliente escanea el código QR con su teléfono y completa el pago en la página de pago de MONEI usando su método preferido.

aviso

El enlace de pago del código QR es válido hasta que el pago expira — **7 días** por defecto, o el `expireAt` personalizado que definas (cualquier momento futuro). Tras ese tiempo, debes crear una nueva solicitud de pago.

## 3. Procesar la notificación de webhook (lado del servidor)[​](#webhook "Enlace directo al 3. Procesar la notificación de webhook (lado del servidor)")

MONEI envía el estado final y autoritativo del pago mediante una solicitud HTTP POST asíncrona a la `callbackUrl` que proporcionaste en el Paso 1. El cuerpo de la solicitud contiene el [objeto Payment](https://docs.monei.com/es/apis/rest/schemas/payment.md) completo en formato JSON.

Este webhook garantiza que recibas el estado definitivo incluso si el cliente cierra el navegador o pierde la conexión tras escanear.

**Es imprescindible que:**

1. **Verifiques la cabecera `MONEI-Signature`** incluida en la solicitud. Esto confirma que el webhook proviene realmente de MONEI. Consulta la [guía de verificación de firmas](https://docs.monei.com/es/guides/verify-signature.md) para los detalles de implementación.
2. **Devuelvas un código de estado HTTP `200 OK`** inmediatamente al recibir el webhook para confirmar la recepción. Cualquier otro código de estado indica a MONEI que la notificación ha fallado.

Si MONEI no recibe un `200 OK`, reintentará el envío del webhook.

Una vez verificada la firma, inspecciona el campo `status` en el objeto Payment para confirmar el éxito del pago (`SUCCEEDED`) y completar el pedido, o gestionar los fallos.

## Alternativa: consultar el estado del pago[​](#polling "Enlace directo al Alternativa: consultar el estado del pago")

Para escenarios de kiosco o display en los que necesitas actualizaciones de estado en tiempo real, consulta el estado del pago en lugar de (o además de) los webhooks.

* cURL
* Node.js
* PHP
* Python

GET https\://api.monei.com/v1/payments/{payment\_id}

```
curl --request GET 'https://api.monei.com/v1/payments/{payment_id}' \

--header 'Authorization: YOUR_API_KEY'
```

server.js

```
const payment = await monei.payments.get(paymentId);

console.log(payment.status);
```

server.php

```
<?php

$payment = $monei->payments->get($paymentId);

echo $payment->getStatus();

?>
```

server.py

```
payment = monei.payments.get(payment_id)

print(payment.status)
```

**Valores de estado:** `PENDING`, `PENDING_PROCESSING`, `SUCCEEDED`, `FAILED`, `CANCELED`, `EXPIRED`

Buenas prácticas de consulta

Consulta cada 2-3 segundos. Detente cuando el estado ya no sea `PENDING`/`PENDING_PROCESSING` o cuando el QR expire.

## Personalización[​](#customization "Enlace directo al Personalización")

Puedes personalizar la apariencia del código QR (color, icono) y la página de pago alojada en tu [Panel de MONEI → Configuración → Branding](https://dashboard.monei.com/settings/branding). El **Icono** que subes ahí es también el icono que MONEI pone en el centro de tus códigos QR, y el **Color principal** es el color con el que se dibujan:

![Página Branding en los ajustes del panel de MONEI, donde personalizas tu página de pago](/img/dashboard/es/settings-branding.png)

Página Branding en los ajustes del panel de MONEI, donde personalizas tu página de pago

## Pruebas[​](#testing "Enlace directo al Pruebas")

* Usa tus [claves de API en modo de prueba](https://docs.monei.com/es/testing.md) para el desarrollo
* Activa el **Modo de prueba** en tu [Panel](https://dashboard.monei.com/payments) para ver los pagos de prueba
* Usa [números de tarjeta de prueba](https://docs.monei.com/es/testing.md#test-card-numbers) para simular diferentes escenarios
* Verifica la entrega de webhooks en [MONEI Dashboard → Configuración → Webhooks](https://dashboard.monei.com/settings/webhooks)

## Solución de problemas[​](#troubleshooting "Enlace directo al Solución de problemas")

**Código QR expirado** Los códigos QR son válidos hasta que el pago expira (7 días por defecto). Crea un nuevo pago si el código expira.

**El método de pago no aparece** Comprueba que el método esté habilitado en tu cuenta y que no esté filtrado por `allowedPaymentMethods`.

**Webhook no recibido** Verifica que tu `callbackUrl` sea accesible públicamente, devuelva `200 OK` y consulta los registros de webhooks en el panel.
