Saltar al contenido
Payment Emulator LabDocumentaciónEntrar a la consola

Introducción

Payment Emulator Lab

Payment Emulator Lab es un emulador de pasarelas de pago con estado y variosproveedores, para desarrollar integraciones. Una aplicación en pruebas puede usarAPIs HTTP con la forma

7 min de lectura

Índice / Index · English

Traducción de README.md, que es el original. Si discrepan, manda el inglés. La política está en docs/en/translation.md.

Payment Emulator Lab es un emulador de pasarelas de pago con estado y varios proveedores, para desarrollar integraciones. Una aplicación en pruebas puede usar APIs HTTP con la forma de cada proveedor, páginas de checkout alojadas y webhooks firmados, sin credenciales reales, sin tarjetas reales, sin dinero real y sin el sandbox del proveedor.

El proyecto se rige por contratos a propósito. Las rutas, los campos, los estados, los errores y las firmas de cada proveedor viven en el borde; el estado del pago, la idempotencia, la contabilidad, las trazas y la entrega de webhooks se implementan una sola vez en un núcleo neutral. Una forma cómoda que un proveedor real no usa es un defecto aquí, aunque haga el emulador más fácil de escribir.

#Qué trae

  • Mercado Pago Orders: crear, consultar, añadir una transacción, procesar, capturar, cancelar y devolver total o parcialmente.
  • Stripe PaymentIntents y Refunds, con la separación create/confirm, la captura manual, las peticiones con formulario que manda el SDK y errores con la forma de Stripe.
  • PayPal Orders v2 y Payments v2: OAuth local, aprobación, autorización, captura, anulación y devoluciones para una unidad de compra y una captura final.
  • Escenarios deterministas para éxito, rechazo, latencia, fallos HTTP, webhooks duplicados o con firma inválida, y pagos que se mueven en un plazo.
  • Aislamiento por credencial de aplicación, más aplicaciones que caducan para integración continua.
  • Un libro mayor por partida doble para captura, comisiones, reserva, liquidación, retiro, devolución y contracargo. El dinero se guarda como bigint en unidades mínimas y los saldos se derivan de asientos inmutables.
  • Un outbox transaccional de webhooks con transporte de entrega intercambiable —PostgreSQL, MongoDB o Redis/BullMQ tras un mismo puerto— y firmas propias de cada proveedor.
  • Un catálogo de bancos: cada uno es dueño del prefijo con el que empiezan sus números de cuenta, que se comprueba una vez, cuando el número todavía existe.
  • Una consola de operador en Nuxt y un checkout de comprador aparte, también en Nuxt. Cada navegador habla con su propio servidor Nitro; ninguno recibe credenciales del backend.
  • Personas con rol admin, merchant o customer, alcance por fila sobre las aplicaciones, sesiones revocables y acceso opcional del cliente en el checkout.

Los límites exactos de fidelidad están en los informes de fidelidad. En particular, no se emulan los esquemas OpenAPI completos de los proveedores, Stripe Elements ni la superficie entera de producto de Mercado Pago o Stripe.

#La arquitectura de un vistazo

Código del diagrama
mermaid
flowchart LR
    AUT[Aplicación en pruebas] -->|API del proveedor + token de aplicación| API[API NestJS]
    Operador[Navegador del operador] --> Console[Consola Nuxt / Nitro]
    Comprador[Navegador del comprador] --> Checkout[Checkout Nuxt / Nitro]
    Console -->|sesión de persona| API
    Checkout -->|enlace público; sesión de cliente opcional| API

    API --> Gateway[Orquestación de pasarela]
    Gateway --> Plugin[Plugin del proveedor]
    Gateway --> Payments[Pagos canónicos]
    Payments --> Ledger[Libro mayor por partida doble]
    Payments --> Outbox[Outbox de webhooks]
    API --> PG[(PostgreSQL)]
    Worker[Worker de webhooks y relojes] --> PG
    Worker --> Transport[(Transporte: PostgreSQL, MongoDB o Redis)]
    Transport --> Callback[Callback en la lista de permitidos]

Es una arquitectura modular que delega en un runtime, no DDD. Los controladores declaran superficies HTTP, los servicios son dueños del comportamiento, el EntityManager de MikroORM se usa directamente, y lo compartido vive en apps/api/src/core/ o en el módulo que lo posee. Las fronteras y los flujos están en Arquitectura.

#Tecnología

Tecnología Papel
Node.js 22+ / TypeScript Runtime y lenguaje
NestJS 11 API HTTP y cableado de la aplicación
MikroORM 7 / PostgreSQL 17 Estado durable, transacciones y migraciones
PostgreSQL, MongoDB 7 o Redis 8 / BullMQ 6 Transporte de entrega de webhooks, elegido con WEBHOOK_QUEUE_DRIVER
Nuxt 4 / Vue 3 Consola de operador y checkout de comprador
PrimeVue 4 Sólo la consola
Vitest 4 / Supertest / fast-check Pruebas unitarias, de integración, de conformidad y de propiedades
Docker Compose Pila local de seis servicios

Las versiones están confirmadas contra los manifiestos y el lockfile actuales.

#Arranque rápido

Requisitos: Docker con Compose. Node.js >=22.17.0 hace falta además para la semilla, las pruebas de humo y el desarrollo sin Docker.

bash
docker compose up --build --wait
npm run seed

La semilla crea las personas de la demo y datos representativos de Mercado Pago y Stripe a través de las superficies HTTP reales. Con los valores por defecto de Compose, entra a la consola con:

text
correo:      operadora@example.test
contraseña:  emulator-demo-password

Son credenciales locales de demostración y nada más. Si la pila es accesible por alguien más, copia .env.example a .env y cambia todos los secretos antes de arrancarla. Si cambias ADMIN_TOKEN, pásale el mismo valor a npm run seed.

URL Superficie
http://localhost:3000 Consola del operador
http://localhost:3001 Checkout del comprador
http://localhost:8080/health Salud de la API

Para comprobar la pila entera en marcha:

bash
npm run smoke:stack

Para instalar sin Docker, las migraciones y los cuatro procesos de desarrollo, sigue Primeros pasos.

#Mapa del repositorio

text
apps/
├── api/                 # API NestJS y worker de webhooks y relojes
├── console/             # Aplicación Nuxt del operador (PrimeVue)
└── checkout/            # Aplicación Nuxt del comprador y los kits visuales
contracts/               # Especificaciones importadas de proveedores y sus sumas
scenarios/               # Fuentes canónicas de los escenarios, en JSON
scripts/                 # Prueba de humo de aceptación sobre la pila entera
docs/                    # Documentación de mantenimiento y de entrada
.agents/                 # Reglas de arquitectura vinculantes; leer antes de tocar código
graphify-out/            # Grafo de descubrimiento generado (instantánea histórica)

La instantánea de Graphify se generó antes de la disposición actual en apps/. Sigue sirviendo para encontrar los centros originales (pasarela, libro mayor, escenarios y webhooks), pero sus rutas y relaciones hay que confirmarlas contra el código. Dónde va el código nuevo está en Estructura del proyecto.

#Órdenes habituales

Todas desde la raíz del repositorio.

bash
npm ci
npm run typecheck
npm run lint
npm test
npm run build
npm run smoke

Las pruebas de integración corren contra PostgreSQL sólo si DATABASE_URL está puesta; sin ella, Vitest las da por saltadas. La humareda de pila entera exige una pila de Compose en marcha.

Órdenes útiles de desarrollo:

bash
npm run dev:api
npm run dev:console
npm run dev:checkout
npm run start:worker --workspace @payment-emulator/api
npm run migrate
npm run admin:create
npm run scenario:compile

#Tu primer cambio

Antes de tocar código, lee .agents/README.md — que está en inglés a propósito: es el contrato, y un contrato traducido son dos contratos. La versión corta:

  1. Encuentra la aplicación y el módulo dueños.
  2. Deja finos los controladores y las páginas; el comportamiento va en los servicios o en el gateway de la aplicación.
  3. Lo específico de un proveedor va sólo en apps/api/src/providers/<id>/, y su identidad visual sólo en apps/checkout/providers/<id>/.
  4. Nunca metas una rama por proveedor en el núcleo, ni escribas filas del libro mayor a mano, ni guardes un saldo mutable, ni dejes que un navegador llame directamente a la API de NestJS.
  5. Añade o ajusta la prueba más estrecha que valga, y luego pasa typecheck, lint, pruebas y build.

Las rutas y los ejemplos están en la Guía de desarrollo.

#Documentación

Empieza por el índice de documentación:

#Seguridad

  • El código en ejecución nunca llama a un proveedor de pagos real.
  • Los webhooks se mandan sólo si la salida está habilitada y el host de destino está en la lista de permitidos.
  • Los tokens de aplicación y de sesión se guardan como digest; el token de acceso de una aplicación se enseña únicamente al emitirlo o al rotarlo.
  • Las trazas tachan los campos de credencial conocidos antes de persistirlos.
  • No se guardan números de cuenta completos, ni PAN, ni CVV.
  • Los escenarios son datos; no se admite JavaScript arbitrario.

Este repositorio es una herramienta para desarrollar integraciones, no un procesador de pagos ni un libro mayor de tesorería para producción.

Payment Emulator Lab · RonuSoftwareMIT