# Crea un checkout personalizado

Crea tu propia experiencia de checkout personalizada usando [MONEI Components](https://docs.monei.com/es/es/monei-js/overview/.md) para recopilar de forma segura los datos de pago de varios métodos directamente en tu sitio.

![Demo de pagos MONEI](/es/assets/images/custom-checkout-demo-eee8eb56f146ccd3e664abc174a19e75.png)

[](https://payments-demo.monei.com)

[Demo en vivo](https://payments-demo.monei.com)

[Código fuente](https://github.com/MONEI/monei-payments-demo)

**Características principales de MONEI Components:**

* Recopila datos de pago de forma segura a través de iframes alojados por MONEI.
* Genera un `paymentToken` de un solo uso para el procesamiento seguro en el servidor.
* Disponible para JavaScript puro, React, Vue, Angular y Svelte.
* Compatible con personalización de estilos, idioma y múltiples métodos de pago.
* Ayuda a cumplir los requisitos de conformidad PCI DSS, ya que los datos sensibles no pasan por tu servidor.

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

* Esta guía cubre la integración de Components para varios métodos de pago. Si prefieres una solución más sencilla sin necesidad de código, considera la [Página de pago alojada](https://docs.monei.com/es/es/integrations/use-prebuilt-payment-page/.md).
* 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 a través de la MONEI API y recibe un `payment.id`
2. El **payment.id** se pasa a la página de checkout del lado del cliente
3. El cliente introduce los datos de pago en un MONEI Component (iframe seguro)
4. `monei.confirmPayment()` envía los datos tokenizados a MONEI, que gestiona 3D Secure si es necesario
5. 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.

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

});



// Pass payment.id to your client-side

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'

  ])

);



// Pass payment ID to your client-side

$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"

    )

)



# Pass payment ID to your client-side

payment_id = payment.id
```

**Parámetros principales:**

* **amount** `positive integer`: Importe en la unidad monetaria más pequeña.
* **currency** `string`: Código de moneda ISO de tres letras.
* **orderId** `string`: Tu identificador de pedido único.
* **callbackUrl** `string`: Tu endpoint de servidor para las notificaciones de webhook.

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

La respuesta contiene `payment.id`. Pásalo de forma segura al lado del cliente para el siguiente paso.

### 2. Añadir el Component a tu página de pago (lado del cliente)[​](#2-añadir-el-component-a-tu-página-de-pago-lado-del-cliente "Enlace directo al 2. Añadir el Component a tu página de pago (lado del cliente)")

Incluye `monei.js` en tu página de checkout añadiendo la etiqueta script al `head` de tu archivo HTML.

checkout.html

```
<head>

  <title>Checkout</title>

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

</head>

<body>

  <!-- Create an empty container for the card input -->

  <div id="card-element">

    <!-- A MONEI Card Input Component will be inserted here. -->

  </div>

  <!-- Your client-side script -->

  <script src="client.js"></script>

</body>
```

Crea un nodo DOM vacío (contenedor) con un ID único en tu página de checkout. A continuación, inicializa el Component:

client.js

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

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



// Create an instance of the Card Input Component using the paymentId.

const cardElement = monei.CardInput({

  paymentId: paymentId

  // You can add other options like style, onFocus, onChange here

  // See MONEI Components reference for details

});



// Render the Component into the container

cardElement.render('#card-element');



// Next step: Confirm the payment (see below)
```

Alternativa: inicializar con el ID de cuenta

También puedes inicializar CardInput con `accountId` + `sessionId` en lugar de `paymentId` para generar un token **antes** de crear el pago. Esto es útil para el [express checkout con envío](https://docs.monei.com/es/es/integrations/express-checkout/.md) o la [activación de suscripciones](https://docs.monei.com/es/es/subscriptions/build-custom-checkout/.md).

```
const cardElement = monei.CardInput({

  accountId: 'YOUR_ACCOUNT_ID',

  sessionId: 'unique_session_id'

});
```

Al usar este método, pasa el mismo `sessionId` al crear el pago en el servidor. Consulta la [referencia de MONEI Components](https://docs.monei.com/es/es/monei-js/reference/.md) para más información.

### 3. Confirmar el pago (lado del cliente)[​](#3-confirmar-el-pago-lado-del-cliente "Enlace directo al 3. Confirmar el pago (lado del cliente)")

Para completar el pago, debes confirmarlo usando la función `monei.confirmPayment`.

Debes proporcionar el `paymentId` (obtenido en el Paso 1) y un `paymentToken` generado con el Component.

client.js

```
// Assumes cardElement is the initialized CardInput component from Step 2



// Function to submit the card input and confirm the payment

async function handlePayment() {

  try {

    // Generate a payment token from the card input

    const {token, error} = await cardElement.submit();



    if (error) {

      // Inform the user if there was an error.

      console.error('Submit error:', error);

      return;

    }



    // Confirm the payment with the generated token

    const result = await monei.confirmPayment({

      paymentId: paymentId,

      paymentToken: token

    });



    // At this moment you can show a customer the payment result (e.g., redirect)

    // But you should ALWAYS rely on the result passed to the callback endpoint

    // on your server (Step 4) to update the final order status.

    console.log('Payment status (client-side):', result.status);

    // Example: window.location.href = '/thank-you?paymentId=' + paymentId;

  } catch (error) {

    console.error(error);

  }

}



// You would typically call handlePayment() when the user clicks your pay button.

// Example: document.getElementById('your-pay-button').addEventListener('click', handlePayment);
```

Después de confirmar el pago, MONEI gestiona todos los pasos necesarios, como la autenticación 3D Secure.

Flujo alternativo

Como proceso alternativo, puedes enviar el `paymentToken` generado a tu servidor y luego [confirmar el pago en el servidor](https://docs.monei.com/es/es/apis/rest/payments-confirm/.md).

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

Tras la interacción del lado del cliente y cualquier procesamiento en segundo plano necesario (como 3D Secure o la autorización bancaria), MONEI envía el estado final y definitivo 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 es la **única forma fiable** de confirmar el resultado definitivo del pago.

**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 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 (`SUCCEEDED`, `FAILED`, `CANCELED`, etc.) para determinar si debes completar el pedido o gestionar el fallo.

## Antes de pasar a producción[​](#antes-de-pasar-a-producción "Enlace directo al Antes de pasar a producción")

* Asegúrate de usar el ID de cuenta y la clave de API en [modo de producción](https://docs.monei.com/es/es/testing/.md).
* Asegúrate de tener un [método de pago configurado y habilitado](https://dashboard.monei.com/settings/payment-methods) en modo de producción.
