MONEI Connect
Conviértete en partner de pagos integrado para ofrecer servicios de pago a los usuarios de tu plataforma o marketplace con MONEI Connect. Registra comercios bajo tu marca, gestiona sus cuentas en su nombre a través de las APIs REST y GraphQL, e integra pagos con tarjeta NFC en persona directamente dentro de tu app de comercio con los SDKs de MONEI Pay.
Antes de empezar
Contacta con connect@monei.com para registrarte como partner. Incluye:
- Tu empresa — nombre legal, sitio web, Número de Identificación Fiscal (CIF), descripción de los servicios.
- Primer usuario administrador — nombre, email, número de teléfono. Puedes añadir más usuarios después desde el panel.
- IPs de tus servidores (opcional pero recomendado) para que podamos restringir las llamadas a la API a tu infraestructura.
- Preferencia de facturación de la tarifa diaria — facturada a tu cuenta principal o transferida a tus comercios. Tarifas actuales:
- MONEI X — 0,10 €/día
- MONEI PLUS — 39,99 €/día
Una vez habilitado, obtendrás acceso al Partner Dashboard en admin.monei.com y un enlace de registro único para tu cuenta de partner. Cada comercio que se registre a través de este enlace quedará vinculado a ti.
Cómo funciona
Claves de API
Genera tus claves de API de partner en admin.monei.com/settings/api → Crear clave de API. La página es sensible al modo: cambia al modo en producción para tu clave pk_live_…, y al modo de prueba para tu clave pk_test_…. Las claves se pueden revocar y volver a crear desde la misma página.
Modo de prueba y modo en producción
Cada cuenta de partner es en realidad un par: una cuenta en producción (pk_live_…) y una cuenta de prueba (pk_test_…) vinculadas de forma permanente. Cada comercio que se registre a través de tu enlace de registro recibe el mismo tratamiento doble: una subcuenta de producción y una subcuenta de prueba con IDs diferentes.
Esto significa que puedes construir y probar la integración completa —incorporación, llamadas a la API, webhooks— en modo de prueba antes de que ningún comercio firme el contrato.
- Las subcuentas de prueba se activan inmediatamente tras confirmar el email de registro; el comercio no necesita completar la incorporación.
- Las subcuentas en producción permanecen en
PENDING_CONTRACThasta que el comercio firme el contrato y sea aprobado. - Las claves en producción no pueden llamar a subcuentas de prueba (ni viceversa). La incompatibilidad de modos es la causa número 1 de errores 401 — consulta Errores de autenticación comunes.
- El selector de modo en el panel (barra superior) cambia toda la vista entre las subcuentas en producción y de prueba.
Enlace de registro
El enlace de registro es único para tu cuenta de partner. Cada comercio que se registre a través de él quedará vinculado a ti.
https://dashboard.monei.com/?action=signUp&promo=<PARTNER_CODE>
Opcionalmente, puedes pasar un ID externo para identificar al comercio en tu propio sistema. El ID se devuelve en cada webhook.
https://dashboard.monei.com/?action=signUp&promo=<PARTNER_CODE>&mid=<EXTERNAL_ID>&h=<HASH>
mid— tu ID de comercio externo.h—HMAC-SHA256(<EXTERNAL_ID>, <PARTNER_API_KEY>)en hexadecimal.
Tu cuenta de partner puede configurarse para requerir un ID externo. Cuando está habilitado, el enlace de registro siempre debe incluir mid + h.
Integración
Envía tu clave de API de partner en la cabecera Authorization y el ID de cuenta del comercio en la cabecera MONEI-Account-ID en cada solicitud.
API REST
Referencia completa: API REST.
- cURL
- Node.js
- PHP
- Python
curl --request POST 'https://api.monei.com/v1/payments' \
--header 'Authorization: <PARTNER_API_KEY>' \
--header 'MONEI-Account-ID: <MONEI_ACCOUNT_ID>' \
--header 'Content-Type: application/json' \
--header 'User-Agent: MONEI/<PARTNER_NAME>/0.1.0' \
--data-raw '{
"amount": 110,
"currency": "EUR",
"orderId": "14379133960355",
"description": "Test Shop - #14379133960355",
"customer": {
"email": "email@example.com"
},
"callbackUrl": "https://example.com/checkout/callback"
}'
import {Monei} from '@monei-js/node-sdk';
// Initialize with Partner API Key, Account ID, and User-Agent
const monei = new Monei('<PARTNER_API_KEY>', {
accountId: '<MONEI_ACCOUNT_ID>',
userAgent: 'MONEI/<PARTNER_NAME>/0.1.0'
});
async function createMerchantPayment() {
try {
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'
});
console.log('Payment created:', payment.id);
// Handle the payment response (e.g., redirect URL)
} catch (error) {
console.error('Error creating payment:', error.message);
}
}
createMerchantPayment();
<?php
require_once 'vendor/autoload.php';
use Monei\MoneiClient;
use Monei\Model\CreatePaymentRequest;
use Monei\Model\PaymentCustomer;
// Initialize with Partner API Key
$monei = new MoneiClient('<PARTNER_API_KEY>');
// Set Account ID and User-Agent for the specific merchant
$monei->setAccountId('<MONEI_ACCOUNT_ID>');
$monei->setUserAgent('MONEI/<PARTNER_NAME>/0.1.0');
try {
$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'
])
);
echo 'Payment created: ' . $payment->getId();
// Handle the payment response (e.g., redirect URL)
} catch (\Exception $e) {
echo 'Error creating payment: ' . $e->getMessage();
}
?>
import Monei
from Monei import CreatePaymentRequest, PaymentCustomer
# Initialize with Partner API Key
monei = Monei.MoneiClient(api_key='<PARTNER_API_KEY>')
# Set Account ID and User-Agent for the specific merchant
monei.set_account_id('<MONEI_ACCOUNT_ID>')
monei.set_user_agent('MONEI/<PARTNER_NAME>/0.1.0')
try:
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"
)
)
print(f'Payment created: {payment.id}')
# Handle the payment response (e.g., redirect URL)
except Exception as e:
print(f'Error creating payment: {e}')
API GraphQL
Referencia completa: API GraphQL.
curl --request POST 'https://graphql.monei.com' \
--header 'Authorization: <PARTNER_API_KEY>' \
--header 'MONEI-Account-ID: <MONEI_ACCOUNT_ID>' \
--header 'Content-Type: application/json' \
--header 'User-Agent: MONEI/<PARTNER_NAME>/0.1.0' \
--data-raw '{"query":"{account {name status}}"}'
Pagos NFC en persona
Referencia completa: SDK de MONEI Pay.
Acepta pagos con tarjeta Tap-to-Pay directamente dentro de tu propia app de comercio, en iOS, Android, React Native o Web. Tu backend genera un token de autenticación POS de corta duración para el comercio y lo entrega al SDK en el dispositivo del comercio.
- cURL
- Node.js
- PHP
- Python
curl --request POST 'https://api.monei.com/v1/pos/auth-token' \
--header 'Authorization: <PARTNER_API_KEY>' \
--header 'MONEI-Account-ID: <MONEI_ACCOUNT_ID>' \
--header 'User-Agent: MONEI/<PARTNER_NAME>/0.1.0'
import {Monei} from '@monei-js/node-sdk';
const monei = new Monei('<PARTNER_API_KEY>', {
accountId: '<MONEI_ACCOUNT_ID>',
userAgent: 'MONEI/<PARTNER_NAME>/0.1.0'
});
const {token} = await monei.posAuthToken.create();
// Send `token` to the merchant app
<?php
require_once 'vendor/autoload.php';
use Monei\MoneiClient;
$monei = new MoneiClient('<PARTNER_API_KEY>');
$monei->setAccountId('<MONEI_ACCOUNT_ID>');
$monei->setUserAgent('MONEI/<PARTNER_NAME>/0.1.0');
$result = $monei->posAuthToken->create();
$token = $result->getToken();
// Send $token to the merchant app
?>
import Monei
monei = Monei.MoneiClient(api_key='<PARTNER_API_KEY>')
monei.set_account_id('<MONEI_ACCOUNT_ID>')
monei.set_user_agent('MONEI/<PARTNER_NAME>/0.1.0')
result = monei.pos_auth_token.create()
token = result.token
# Send token to the merchant app
La respuesta contiene un JWT válido durante 24 horas, con alcance al comercio identificado por MONEI-Account-ID. Pásalo al SDK en el dispositivo del comercio. Opcionalmente, puedes incluir pointOfSaleId / storeId en el cuerpo para limitar el token a un terminal o tienda específicos.
Los reembolsos nunca deben automatizarse. Cada reembolso requiere una instrucción escrita y trazable del comercio. Los partners son responsables de cualquier reembolso no autorizado y pueden ver su contrato rescindido.
Probar la integración
Puedes construir la integración de partner completa de extremo a extremo antes de que ningún comercio firme un contrato.
- Registra un comercio de prueba a través de tu enlace de registro:
https://dashboard.monei.com/?action=signUp&promo=<PARTNER_CODE>. No es necesario completar la incorporación — la subcuenta de prueba ya está activa. - Obtén el ID de la subcuenta de prueba: en el panel del comercio, activa el modo de prueba (selector en la barra superior) → Ajustes → copia el ID de cuenta.
- Obtén tu clave de API de partner de prueba: inicia sesión en admin.monei.com → activa el modo de prueba → Ajustes → Acceso API → haz clic en Crear clave de API si aún no tienes una → copia la clave
pk_test_*. - Llama a la API con ambas cabeceras, usando números de tarjeta de prueba y los simuladores de respuesta documentados en Pruebas:
curl --request POST 'https://api.monei.com/v1/payments' \
--header 'Authorization: pk_test_<...>' \
--header 'MONEI-Account-ID: <TEST_SUB_ACCOUNT_ID>' \
--header 'Content-Type: application/json' \
--data-raw '{"amount": 110, "currency": "EUR", "orderId": "test-1"}'
Errores de autenticación comunes
Cuando obtengas un error 401, comprueba lo siguiente en orden:
- Incompatibilidad de modos — usar una clave
pk_live_*con unMONEI-Account-IDde prueba (o viceversa). La clave de partner y la subcuenta deben estar en el mismo modo. - IP no incluida en la lista de permitidas — si registraste una lista de IPs permitidas (opcional pero recomendado), las llamadas deben originarse desde una de esas IPs. Para añadir o eliminar una IP, envía un email a connect@monei.com.
MONEI-Account-IDincorrecto — la subcuenta debe pertenecer a tu cuenta de partner. Las subcuentas de otros partners (o cuentas independientes) son rechazadas.MONEI-Account-IDausente — sin él, la clave se autentica como el propio partner, lo que solo funciona para un pequeño subconjunto de endpoints exclusivos de partners. Para todas las operaciones de comercio, incluye la cabecera.
Webhooks
Configura los webhooks en el Partner Dashboard en Ajustes → Webhooks. Cada webhook es una URL de endpoint junto con el subconjunto de tipos de eventos que deseas recibir.
Los webhooks de tu cuenta de partner reciben una distribución de eventos de todos los comercios vinculados a ella — no es necesaria ninguna configuración por subcuenta. El campo accountId del payload identifica al comercio.
Suscripción a eventos
Suscripciones de partner habituales:
| Grupo | Eventos de interés |
|---|---|
| Ciclo de vida del comercio | account.pending, account.approved, account.rejected, account.activated, account.suspended, account.blocked, account.unblocked |
| Liquidaciones | account.iban_updated, account.payout_iban_updated, account.payouts_resumed, account.payouts_suspended, settlement.completed, settlement.pending |
| Pagos (por comercio) | charge.succeeded, charge.failed, charge.refunded, charge.chargeback, refund.succeeded |
| Suscripciones (por comercio) | subscription.activated, subscription.canceled, subscription.past_due |
| Facturación | account_invoice.paid, account_invoice.past_due |
El catálogo completo está disponible en el selector de tipos de evento del panel al añadir o editar un webhook.
Payload
MONEI envía application/json con este envelope en cada evento:
| Campo | Tipo | Descripción |
|---|---|---|
| id | string | ID del evento. |
| type | string | Tipo de evento (p. ej. charge.succeeded). |
| objectType | string | Uno de charge, subscription, account, account_invoice, settlement, provider. |
| objectId | string | ID del objeto afectado. |
| accountId | string | Subcuenta del comercio a la que pertenece el evento. Úsalo para enrutar los eventos al comercio correcto en tu sistema. |
| livemode | boolean | true para eventos en producción, false para eventos de prueba. Hazlo coincidir con la clave de API que usas para verificar la firma. |
| createdAt | number | Timestamp del evento, en segundos Unix. |
| object | object | El objeto afectado. La estructura depende de objectType — consulta las pestañas a continuación. |
- charge
- subscription
- account
- account_invoice
object es un pago — referencia completa de campos en Esquema de pago.
{
"id": "evt_5fda0f3b7b2f4e0d…",
"type": "charge.succeeded",
"objectType": "charge",
"objectId": "ch_8e2f…",
"accountId": "<MERCHANT_SUB_ACCOUNT_ID>",
"livemode": true,
"createdAt": 1748390400,
"object": {
"id": "ch_8e2f…",
"amount": 1099,
"currency": "EUR",
"status": "SUCCEEDED",
"orderId": "ORDER-4421",
"customer": {"email": "buyer@example.com"},
"paymentMethod": {"method": "card", "card": {"brand": "VISA", "last4": "4242"}}
}
}
object es una suscripción — referencia completa de campos en Esquema de suscripción.
{
"id": "evt_…",
"type": "subscription.activated",
"objectType": "subscription",
"objectId": "sub_…",
"accountId": "<MERCHANT_SUB_ACCOUNT_ID>",
"livemode": true,
"createdAt": 1748390400,
"object": {
"id": "sub_…",
"amount": 999,
"currency": "EUR",
"interval": "month",
"intervalCount": 1,
"status": "ACTIVE",
"nextPaymentAt": 1751068800,
"customer": {"email": "buyer@example.com"}
}
}
object es la cuenta del comercio afectado. Se dispara con cada tipo de evento account.* y master_account.*.
| Campo | Tipo | Descripción |
|---|---|---|
| id | string | ID de la subcuenta. |
| name | string | Nombre comercial. |
| status | string | PENDING_CONTRACT, PENDING_APPROVAL, APPROVED, ACTIVE, REJECTED, SUSPENDED, BLOCKED. |
| statusReason | string | Motivo legible por máquina del estado actual (cuando aplica). |
| statusNote | string | Nota en texto libre de MONEI Ops (cuando aplica). |
| test | boolean | true para la subcuenta gemela de prueba. |
| adminEmail | string | Email del administrador del comercio. |
| iban | string | IBAN de liquidación, ofuscado (solo los primeros 4 + los últimos 4 dígitos). |
| externalId | string | Identificador del comercio proporcionado por el partner (si usas el flujo de ID externo). |
| language | string | Código de idioma del panel. |
| billingPlan | string | P. ej. MONEI_X, MONEI_PLUS. |
| blocked | boolean | true si MONEI ha bloqueado la cuenta. |
| churned | boolean | true si el comercio ha dado de baja el servicio. |
| churnReason / churnReasonOption / churnNote | string | Metadatos de baja (cuando churned: true). |
| contactPerson | object | {name, email, phone} del administrador del comercio. |
| business | object | {legalName, legalForm, email, phone, website, country, address, documentNumber, status, servicesDescription}. |
{
"id": "evt_…",
"type": "account.approved",
"objectType": "account",
"objectId": "<MERCHANT_SUB_ACCOUNT_ID>",
"accountId": "<MERCHANT_SUB_ACCOUNT_ID>",
"livemode": true,
"createdAt": 1748390400,
"object": {
"id": "<MERCHANT_SUB_ACCOUNT_ID>",
"name": "ACME Shop",
"status": "APPROVED",
"test": false,
"adminEmail": "owner@acme.com",
"iban": "ES12********6789",
"externalId": "merchant-7421",
"language": "es",
"billingPlan": "MONEI_X",
"blocked": false,
"business": {
"legalName": "ACME COMERCIO SL",
"documentNumber": "B12345678",
"country": "ES",
"website": "https://acme.com",
"email": "info@acme.com",
"status": "active"
}
}
}
object es la factura de MONEI del comercio por las tarifas de plataforma acumuladas. Se dispara con eventos account_invoice.*.
| Campo | Tipo | Descripción |
|---|---|---|
| id | string | ID de la factura. |
| number | string | Número de factura legible impreso en el PDF. |
| accountId | string | Subcuenta a la que pertenece la factura. |
| status | string | PENDING, PAID, PAST_DUE, UNPAID. |
| period | object | {from, to} en segundos Unix que cubre el período de facturación. |
| currency | string | Código ISO 4217. |
| amount | number | Importe neto en unidades menores. |
| tax | number | Impuesto en unidades menores. |
| totalAmount | number | amount + tax, en unidades menores. |
| lineItems | array | Líneas de detalle por cobro: {name, quantity, unitType (money|percent), unitAmount, amount, currency}. |
| business | object | {legalName, documentNumber, iban (obfuscated), mandateSignatureTimestamp}. |
| createdAt | number | Timestamp de creación de la factura, en segundos Unix. |
{
"id": "evt_…",
"type": "account_invoice.paid",
"objectType": "account_invoice",
"objectId": "inv_…",
"accountId": "<MERCHANT_SUB_ACCOUNT_ID>",
"livemode": true,
"createdAt": 1748390400,
"object": {
"id": "inv_…",
"number": "1/2026-14510",
"accountId": "<MERCHANT_SUB_ACCOUNT_ID>",
"status": "PAID",
"period": {"from": 1773014400, "to": 1773619199},
"currency": "EUR",
"amount": 153,
"tax": 0,
"totalAmount": 153,
"lineItems": [
{
"name": "Flat fee per Credit card transaction",
"quantity": 1,
"unitType": "money",
"unitAmount": 24,
"amount": 24,
"currency": "EUR"
},
{
"name": "MONEI X daily platform usage fee",
"quantity": 7,
"unitType": "money",
"unitAmount": 10,
"amount": 70,
"currency": "EUR"
}
],
"business": {
"legalName": "ACME COMERCIO SL",
"documentNumber": "B12345678",
"iban": "ES93********0012"
}
}
}
Verificación de la firma
Cada solicitud incluye una cabecera MONEI-Signature con el formato t=<unix-seconds>,v1=<hex>. Calcula HMAC-SHA256("<t>.<rawBody>", <PARTNER_API_KEY>) y compáralo con v1. Usa la misma clave de API de partner (producción o prueba) que coincida con el livemode del evento. Guía completa: Verificar firma.
Entrega y reintentos
- Responde con
2xxpara confirmar la recepción. Cualquier otro código (incluido3xx) se trata como un fallo. - MONEI reintenta las entregas fallidas con retroceso exponencial durante varios días y luego abandona.
User-Agent: MONEI/1.0identifica nuestras solicitudes.
El accountCallbackUrl heredado configurado durante la incorporación del partner sigue funcionando — se dispara únicamente con account.pending, account.approved y account.rejected con un payload limitado — pero está siendo eliminado progresivamente. Las nuevas integraciones deben usar la configuración de webhooks del Partner Dashboard.
Gestiona tu cuenta de partner
Toda la gestión de la cuenta de partner es de autoservicio en el Partner Dashboard.
Usuarios autorizados
Invita a miembros adicionales de tu equipo en admin.monei.com/settings/users → Añadir nuevo usuario. Proporciona su email, nombre y número de teléfono — recibirán una invitación para establecer su contraseña. Todos los usuarios de partner tienen MFA obligatorio.
Seguridad
admin.monei.com/settings/security — tres controles independientes:
- IPs permitidas — cada llamada a la API contra tu clave de API de partner debe originarse desde una de estas IPs. Actúa como segunda línea de defensa si una clave se filtra: una clave robada desde fuera de tu infraestructura queda inutilizable.
- Dominios permitidos — restringe qué dominios pueden cargar la página de pago alojada para los comercios vinculados a tu cuenta. Evita que el checkout de tus comercios sea integrado por sitios no relacionados.
- Requerir ID externo — cuando está habilitado, cada comercio que se registre a través de tu enlace de registro debe llevar un HMAC válido
mid+h(consulta Enlace de registro). Úsalo si solo quieres registros que se originen desde tu propio flujo de incorporación, nunca visitas directas al enlace.
Marca
admin.monei.com/settings/branding — sube tu logotipo. En la página de registro del comercio abierta desde tu enlace de registro, tu logotipo aparece junto a el de MONEI (separados por un +), señalando la asociación de co-branding. Úsalo para que los comercios reconozcan tu plataforma como el origen de la oferta de pagos en lugar de llegar a un registro de MONEI sin marca.
Notificaciones por email
admin.monei.com/settings/emails — añade listas de destinatarios adicionales para los emails operativos que MONEI envía sobre tu cuenta de partner:
- Emails de webhook — destinatarios alertados cuando la entrega de webhooks a tu endpoint comienza a fallar. Enrútalo a tu buzón de operaciones o guardia para que puedas reparar un endpoint roto antes de acumular eventos perdidos.
- Emails de baja — destinatarios alertados cuando un comercio vinculado a ti da de baja el servicio. Enrútalo a tu equipo de gestión de cuentas o finanzas para que puedan hacer seguimiento sin tener que consultar la API.