# Usar el modal de pago

El modal de pago de MONEI es la forma más sencilla de recopilar pagos de forma segura de tus clientes sin que abandonen tu sitio web.

![Vista previa del modal de pago de MONEI](/es/assets/images/payment-modal-cbb30083effbd94b0d01dfdd45e6d94d.png)

Recopilar pagos en tu sitio web consiste en crear un objeto de pago y confirmar el pago.

important

Apple Pay no está disponible al usar la integración del modal de pago de MONEI.

## Antes de empezar[​](#antes-de-empezar "Enlace directo al Antes de empezar")

* Necesitarás una cuenta MONEI y tus claves de API (de prueba o de producción). Encuéntralas en tu [MONEI Dashboard](https://dashboard.monei.com/settings/api).
* Usa tus [claves en modo de prueba](https://docs.monei.com/es/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.
* Puedes monitorizar los pagos de prueba en tu [MONEI Dashboard → Pagos](https://dashboard.monei.com/payments) (asegúrate de que el Modo de prueba esté activo).

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

<!-- -->

1. Tu **backend** crea un pago y recibe un `payment.id`
2. El **payment.id** se pasa a tu página del lado del cliente
3. Llamar a `monei.confirmPayment()` abre una **ventana modal** donde el cliente realiza el pago (incluyendo 3D Secure si es necesario)
4. MONEI envía el estado final del pago a tu **backend** mediante webhook

## Pasos de integración[​](#pasos-de-integración "Enlace directo al Pasos de integración")

### 1. Crear el pago (lado del servidor)[​](#1-crear-el-pago-lado-del-servidor "Enlace directo al 1. Crear el pago (lado del servidor)")

Crea un [Pago](https://docs.monei.com/es/es/apis/rest/schemas/payment/.md) en tu servidor con un importe y una moneda. Determina siempre el importe en el lado del servidor, un entorno de confianza, y no en el cliente. Esto evita que clientes malintencionados puedan elegir sus propios precios.

<!-- -->

* 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",

  "description": "Test Shop - #14379133960355",

  "customer": {

    "email": "email@example.com"

   },

  "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',

  description: 'Test Shop - #14379133960355',

  customer: {

    email: 'email@example.com'

  },

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

});



// You will need the paymentId from the response in the next step

const paymentId = payment.id;
```

server.php

```
<?php

require_once 'vendor/autoload.php';



use Monei\Model\CreatePaymentRequest;

use Monei\Model\PaymentCustomer;

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',

    'description' => 'Test Shop - #14379133960355',

    'customer' => new PaymentCustomer([

      'email' => 'email@example.com'

    ]),

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

  ])

);



// You will need the paymentId from the response in the next step

$paymentId = $payment->getId();

?>
```

server.py

```
import Monei

from Monei import CreatePaymentRequest, PaymentCustomer



# 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",

        description="Test Shop - #14379133960355",

        customer=PaymentCustomer(

          email="email@example.com"

        ),

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

    )

)



# You will need the paymentId from the response in the next step

payment_id = payment.id
```

**Parámetros principales:**

* **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.

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

El objeto Payment devuelto incluye un `id` de pago. Usarás este `paymentId` en el lado del cliente en el siguiente paso.

### 2. Gestionar la interacción de pago (lado del cliente)[​](#2-gestionar-la-interacción-de-pago-lado-del-cliente "Enlace directo al 2. Gestionar la interacción de pago (lado del cliente)")

Usa [`monei.js`](https://docs.monei.com/es/es/monei-js/reference/.md) para confirmar el pago. Esto activará la ventana modal de pago.

Incluye `monei.js` en tu página de checkout:

checkout.html

```
<head>

  <title>Checkout</title>

  <script src="https://js.monei.com/v3/monei.js"></script>

</head>

<body>

  <form id="payment-form">

    <button id="payment-button" type="submit">Pagar</button>

  </form>

  <script>

    // Initialize client-side script here (see below)

  </script>

</body>
```

Usa el `paymentId` obtenido en el Paso 1 para llamar a `monei.confirmPayment`. También puedes proporcionar parámetros adicionales como `customer.email`. Consulta todos los [parámetros](https://docs.monei.com/es/es/monei-js/reference/.md#confirmpayment-function) disponibles.

client.js

```
// Get the paymentId passed from your server

const paymentId = '{{payment_id}}'; // Replace with the actual paymentId



const paymentForm = document.getElementById('payment-form');

const paymentButton = document.getElementById('payment-button');



paymentForm.addEventListener('submit', function (event) {

  event.preventDefault();

  paymentButton.disabled = true;



  monei

    .confirmPayment({paymentId: paymentId}) // Pass the paymentId here

    .then(function (result) {

      paymentButton.disabled = false;

      // This result reflects the immediate outcome of the modal interaction (e.g., user closed, initial success).

      // Always rely on the webhook (Step 3) for the definitive final payment status.

      console.log('Payment confirmation result:', result);

      if (result.status === 'SUCCEEDED' || result.status === 'PENDING') {

        // Optionally, inform the user that payment is processing.

        handleResult(result);

      } else {

        // Handle errors like user cancellation or immediate failures.

        handleError(result);

      }

    })

    .catch(function (error) {

      paymentButton.disabled = false;

      console.error('Error confirming payment:', error);

      // Handle network errors or other issues.

    });

});



function handleResult(result) {

  // Redirect to a success/pending page or update UI.

  // Remember: Final confirmation comes via webhook.

  console.log('Handling result:', result);

  alert('Payment status: ' + result.status + '. Waiting for final confirmation.');

}



function handleError(result) {

  // Show error message to the user.

  console.error('Handling error:', result);

  alert('Payment failed or was cancelled. Status: ' + result.status);

}
```

Tras enviar el formulario, MONEI muestra automáticamente una ventana emergente con una página de pago para recopilar los datos de pago y gestionar cualquier confirmación 3D Secure necesaria.

Alternativa: página prediseñada

Si prefieres redirigir al cliente en lugar de usar un modal en el propio sitio, consulta la [guía de Página de pago prediseñada](https://docs.monei.com/es/es/integrations/use-prebuilt-payment-page/.md).

### 3. Procesar la notificación de webhook (lado del servidor)[​](#3-procesar-la-notificación-de-webhook-lado-del-servidor "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/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 de forma prematura.

**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/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 (incluidas las redirecciones `3xx`) indica a MONEI que la notificación ha fallado.

Si MONEI no recibe un `200 OK`, reintentará el envío del webhook varias veces durante varios días antes de marcarlo como fallido.

Example Webhook Payload (POST to your callbackUrl)

```
{

  "id": "af6029f80f5fc73a8ad2753eea0b1be0",

  "amount": 110,

  "currency": "EUR",

  "orderId": "14379133960355",

  "status": "SUCCEEDED", // Or FAILED, CANCELED, EXPIRED etc.

  "customer": { ... },

  // ... other payment details ...

  "createdAt": 1594215339,

  "updatedAt": 1594215345

}
```

Una vez verificada la firma, inspecciona el campo `status` en el objeto Payment para determinar si debes completar el pedido o gestionar un fallo.
