Cómo transformé una integración de Paylands para PrestaShop en una arquitectura de pagos resiliente
Introducción
Hace unos meses participé en un proceso de selección para un puesto de soporte técnico relacionado con la pasarela de pagos Eupago España.
Durante las últimas fases del proceso surgieron dudas sobre mi capacidad para desarrollar software y finalmente no fui seleccionado.
No considero que aquella decisión fuera injusta. Sin embargo, me dejó una pregunta rondando la cabeza:
¿Hasta dónde podía llegar realmente si tenía la oportunidad de trabajar en un proyecto complejo y demostrar mis capacidades técnicas?
Poco tiempo después apareció la oportunidad de trabajar sobre una integración de Paylands para una tienda desarrollada en PrestaShop 8.2.1.
Lo que inicialmente parecía una tarea relativamente sencilla terminó convirtiéndose en algo muy distinto.
En lugar de limitarme a instalar y configurar el módulo oficial proporcionado por Paylands, decidí analizarlo en profundidad, cuestionar cada decisión arquitectónica y replantear la forma en que una integración de pagos debía comportarse en producción.
Durante las dos semanas siguientes invertí más de cien horas de desarrollo fuera de cualquier requisito inicial del proyecto.
No porque fuera necesario para que los pagos funcionaran.
Los pagos ya funcionaban.
Lo hice porque quería entender cada detalle del sistema, explorar sus límites y construir una solución capaz de responder a problemas reales que normalmente solo aparecen cuando una plataforma empieza a recibir tráfico, incidencias y situaciones inesperadas.
Lo que comenzó como una simple integración terminó convirtiéndose en un proyecto personal de arquitectura, resiliencia, observabilidad y diseño de sistemas.
Más que integrar una pasarela de pago, terminé profundizando en cómo funcionan realmente los sistemas de cobro cuando abandonan el entorno ideal y empiezan a enfrentarse a los problemas del mundo real.
Mi objetivo dejó de ser simplemente hacer que los pagos funcionaran.
Quería construir una integración sólida, observable, mantenible y preparada para evolucionar con el tiempo.
El punto de partida: una integración funcional
Es importante aclarar algo desde el principio.
El módulo original no era un mal módulo.
De hecho, cumplía correctamente con su función principal: permitir que una tienda PrestaShop aceptara pagos mediante Paylands utilizando tarjetas bancarias.
El problema no era que funcionara mal.
El problema era que estaba diseñado para resolver un escenario ideal.
Su arquitectura estaba centrada en completar una transacción satisfactoria y actualizar el pedido correspondiente.
El flujo podía resumirse de forma muy sencilla:
[Cliente paga] → [Paylands responde] → [Pedido actualizado]
Mientras todo ocurría según lo previsto, el sistema funcionaba correctamente.
Sin embargo, la realidad de producción suele ser bastante más compleja.
El cambio de mentalidad
La transformación comenzó cuando dejé de preguntarme:
¿Funciona el pago?
Y empecé a preguntarme:
¿Qué ocurre cuando algo sale mal?
Las preguntas empezaron a cambiar.
- ¿Qué ocurre si el usuario cierra el navegador?
- ¿Qué sucede si el banco tarda más de lo esperado?
- ¿Qué pasa si el callback llega después de que el cliente abandone la página?
- ¿Cómo sabemos exactamente qué ocurrió durante una transacción?
- ¿Cómo puede el equipo de soporte diagnosticar una incidencia?
- ¿Cómo reconstruimos el recorrido completo de una operación?
Cuanto más analizaba el comportamiento del módulo original, más evidente resultaba que el verdadero desafío no estaba en procesar pagos.
El desafío estaba en comprender todo lo que podía ocurrir alrededor de una transacción cuando las cosas dejaban de salir según lo previsto.
El gran problema: el ciclo de vida del pago
Muchas integraciones están construidas alrededor de un único objetivo:
Conseguir que una operación termine correctamente.
Pero una transacción real rara vez sigue un camino perfecto.
En producción aparecen situaciones como esta:
[Cliente paga] → [Espera banco] → [Usuario cierra navegador] → [Callback asíncrono]
↓
¿El pedido se actualiza?
En ese momento aparecen preguntas difíciles.
¿La operación fue autorizada?
¿Debe actualizarse el pedido?
¿Hay que esperar más eventos?
¿Debe reintentarse algún proceso?
Para abordar estos escenarios fue necesario introducir conceptos que apenas tenían presencia en la integración original:
- Estados intermedios.
- Recuperación de operaciones.
- Reconciliación.
- Idempotencia.
- Observabilidad.
- Trazabilidad.
La integración dejó de centrarse únicamente en el resultado final para empezar a gestionar toda la vida de una transacción.

Cuando el problema no es cobrar, sino saber qué está pasando
Durante el desarrollo apareció una limitación muy habitual en muchas pasarelas de pago.
Cuando algo fallaba era complicado responder preguntas aparentemente simples.
- ¿El cliente llegó realmente a Paylands?
- ¿La orden fue creada?
- ¿El banco rechazó la operación?
- ¿Se ejecutó el callback?
- ¿El pedido se actualizó?
- ¿Qué ocurrió exactamente entre el inicio y el final del proceso?
La información existía.
Pero estaba dispersa.
Una de las dificultades iniciales era reconstruir qué había ocurrido durante una transacción concreta cuando un cliente reportaba una incidencia.
Para resolverlo diseñé una capa específica de observabilidad basada en eventos estructurados donde cada transición relevante del ciclo de vida del pago genera un evento persistente.
Cada transacción comenzó a generar eventos como:
payment_createdsdkpayment_startedsdkpayment_direct_payment_requires_3dscallback_hmac_okpayment_successlandingok_redirect_confirmation
Cada evento almacenaba información contextual sobre el carrito, el pedido, el identificador de Paylands, el canal de pago utilizado, códigos HTTP, estados y datos relevantes del proceso.
El objetivo no era generar más logs.
El objetivo era construir una cronología completa capaz de reconstruir la historia de cualquier transacción desde su creación hasta su resolución final.
Cuando un cliente reporta una incidencia, ahora es posible reconstruir cronológicamente toda la operación desde el checkout hasta la confirmación final sin depender de registros dispersos o interpretaciones manuales.
Trazabilidad de extremo a extremo
La observabilidad permitió introducir otro elemento clave: la trazabilidad.
Cada operación pasó a estar relacionada mediante identificadores consistentes capaces de conectar todos los elementos implicados en el proceso.
Hoy es posible relacionar:
- Cliente.
- Carrito.
- Pedido.
- Operación Paylands.
- Método de pago.
- Canal utilizado.
- Eventos internos.
Esto simplifica enormemente el diagnóstico de incidencias.
Lo que antes requería revisar múltiples registros dispersos ahora puede reconstruirse siguiendo una única línea temporal.
Payment Channel: una decisión que cambió la arquitectura
Uno de los cambios arquitectónicos más importantes fue la introducción del concepto de Payment Channel.
Aquí apareció una limitación importante del módulo original.
Inicialmente la integración únicamente soportaba pagos con tarjeta bancaria.
No existía la necesidad de distinguir entre distintos métodos de pago porque simplemente no había más opciones disponibles.
Sin embargo, a medida que la arquitectura evolucionaba y comenzaban a plantearse futuras integraciones con Bizum, MB WAY, Apple Pay o Google Pay, quedó claro que el modelo existente no iba a escalar correctamente.
Uno de los problemas detectados era que el concepto de «método de pago» mezclaba dos dimensiones diferentes:
- Qué utiliza el cliente para pagar.
- Cómo se procesa técnicamente esa operación.
Para resolverlo se introdujo una separación explícita entre método y canal.
[CARD] → [CARD_REDIRECT]
→ [CARD_IFRAME]
→ [CARD_SDK]
[BIZUM]
[MBWAY]
[Futuro]
→ [APPLEPAY]
→ [GOOGLEPAY]
Esta capa de Payment Channels desacopla ambas responsabilidades y permite incorporar nuevos canales sin modificar la lógica principal del sistema.
Además, facilita la obtención de métricas específicas por canal, el análisis de conversiones, la detección de incidencias concretas y la incorporación futura de nuevos métodos sin necesidad de replantear la arquitectura principal.
Una nueva experiencia de pago con tarjeta
Uno de los cambios más visibles fue la evolución completa de la integración de pagos con tarjeta.
El módulo original únicamente soportaba el flujo más básico disponible en Paylands: la redirección del cliente a la página de pago alojada por la plataforma.
Durante el rediseño decidí implementar los tres mecanismos de pago con tarjeta soportados por Paylands:
- Redirect Payment.
- Embedded Payment.
- SDK Payment.
La incorporación del flujo SDK fue especialmente interesante desde el punto de vista técnico.
[Cliente introduce tarjeta]
↓
[SDK Tokeniza]
↓
[Paylands procesa]
↓
¿Requiere 3DS?
↓ ↓
Sí No
↓ ↓
[Autenticación] [Pago OK]
↓
[Pago OK]
Para conseguirlo fue necesario desarrollar:
- Carga dinámica del SDK.
- Tokenización segura.
- Gestión completa de autenticación 3DS.
- Recuperación del flujo tras autenticaciones bancarias.
- Prevención de dobles envíos.
- Gestión avanzada de errores.
Además, los datos de la tarjeta nunca pasan por el backend de la tienda ni son procesados por sus servidores.
El SDK se ejecuta en el navegador del cliente y realiza la tokenización directamente en el frontend.
Este enfoque reduce significativamente el alcance PCI-DSS de la tienda al evitar que los datos sensibles de la tarjeta sean almacenados, transmitidos o procesados por la infraestructura del comercio.
El resultado es una experiencia mucho más cercana a la que ofrecen las grandes plataformas de comercio electrónico actuales.
Seguridad e idempotencia
Los sistemas de pago reciben constantemente eventos duplicados.
- Callbacks repetidos.
- Usuarios pulsando varias veces el botón de pago.
- Problemas de red.
- Reintentos automáticos.
Por ello se implementaron múltiples mecanismos de protección.
- Claves de idempotencia.
- Restricciones de unicidad en base de datos.
- Validación de estados finales.
- Advisory Locks mediante MySQL.
- Protección frente a condiciones de carrera.
Durante las pruebas apareció uno de los escenarios más interesantes del proyecto.
[Navegador regresa a la tienda]
↓
[Pedido]
↑
↓
[Webhook de Paylands]
Dos procesos independientes intentando actualizar el mismo pedido al mismo tiempo.
Para resolverlo se incorporó un mecanismo de locking mediante Advisory Locks de MySQL combinado con controles de idempotencia.
De esta forma se garantiza que cada transacción solo pueda procesarse una vez independientemente del número de callbacks, reintentos o accesos simultáneos que se produzcan.
Además, todos los callbacks recibidos son sometidos a validación criptográfica HMAC SHA-256 antes de procesar cualquier información.
De una integración síncrona a una arquitectura orientada a eventos
Otro de los cambios más interesantes fue la evolución del modelo de procesamiento.
Inicialmente el flujo seguía una estructura clásica:
[Checkout] → [Paylands] → [Respuesta] → [Pedido]
Con el crecimiento del proyecto comenzó a aparecer una arquitectura mucho más cercana a un sistema orientado a eventos.
[Checkout] → [Payment Created] → [Orden Paylands] → [Callback]
↓
[Actualización Pedido]
↓
[Confirmación]
La integración dejó de comportarse como una secuencia rígida de llamadas para convertirse en un conjunto de procesos conectados mediante eventos capaces de describir el estado real de una operación.
Esto aporta:
- Resiliencia.
- Observabilidad.
- Diagnóstico avanzado.
- Escalabilidad futura.
Más importante aún, permitió modelar explícitamente el ciclo de vida de una transacción y desacoplar procesos que anteriormente dependían de respuestas síncronas inmediatas.
Diseñando para el futuro
Uno de los aspectos más interesantes es que algunas decisiones se tomaron pensando en funcionalidades que todavía no existen.
Aunque Apple Pay y Google Pay aún no están activos dentro de la integración, los canales correspondientes ya forman parte del modelo de datos.
- CHANNEL_APPLEPAY
- CHANNEL_GOOGLEPAY
La arquitectura fue diseñada pensando en el futuro y no únicamente en las necesidades actuales.
El objetivo era evitar que cada nueva funcionalidad obligara a replantear la estructura completa del sistema.
Diseñar para el crecimiento suele ser mucho más eficiente que reaccionar cuando el crecimiento ya ha llegado.
Más de cien horas persiguiendo problemas que todavía no existían
Durante algo más de dos semanas invertí más de cien horas analizando, rediseñando e implementando componentes que inicialmente ni siquiera formaban parte del alcance del proyecto.
Nadie me pidió desarrollar un sistema de observabilidad.
Nadie me pidió crear una arquitectura multicanal.
Nadie me pidió implementar mecanismos avanzados de idempotencia o preparar la integración para futuras wallets digitales.
Lo hice porque cuanto más analizaba el sistema, más evidente resultaba que el verdadero desafío no era procesar pagos.
El verdadero desafío era construir una plataforma capaz de explicar qué estaba ocurriendo cuando las cosas dejaban de salir según lo previsto.
Esa búsqueda terminó llevándome a rediseñar componentes completos, introducir nuevos modelos de datos, desarrollar mecanismos de trazabilidad, reforzar la seguridad y replantear la forma en que la integración gestionaba el ciclo de vida completo de una transacción.
No se trataba de añadir tecnologías.
Se trataba de detectar problemas reales, comprender sus consecuencias y diseñar soluciones que siguieran funcionando cuando el entorno dejara de ser ideal.
Lo que comenzó como una integración terminó convirtiéndose en un ejercicio de arquitectura de software.
Lo que aprendí durante el proceso
Si hay una conclusión que me llevo de este proyecto es que integrar pagos es mucho más que conectar una API.
Cobrar dinero es relativamente sencillo.
Lo difícil es construir una integración que sea:
- Comprensible.
- Mantenible.
- Escalable.
- Observable.
- Resiliente.
- Preparada para crecer.
Lo que comenzó como una integración funcional terminó convirtiéndose en un ejercicio de arquitectura, diseño de sistemas y mejora continua.
Y probablemente esa fue la mejor respuesta que podía dar a aquellas dudas que surgieron meses atrás durante aquel proceso de selección para Eupago España.
No porque alguien me la hubiera dado.
Sino porque la encontré construyendo.
Porque, al final, la mejor forma de responder a una duda no es con palabras.
Es construyendo algo que funcione.
¿Tienes una tienda online con problemas de integración, errores fantasmas en los pagos o necesitas optimizar su rendimiento técnico? Hablemos. Analizo la arquitectura de tu sitio para hacerlo rápido, seguro y escalable.