Proyecto personal
CactusPlay - Marketplace de juegos y objetos dentro del juego

Tecnologías
Enlaces
Servicios
- →Cofundación e ingeniería fullstack
- →Scrapers en Node.js para PlayStation Store y Xbox Store
- →Tienda en WooCommerce con extensiones personalizadas en PHP
- →Canalización de sincronización diferencial de precios y sistema de alertas
- →Integración de pasarela de pago y entrega digital
- →Integración con Yandex.Market: mapeo de ofertas, sincronía de precios y entrega instantánea de códigos
- →Cinco plugins de WordPress a medida: sincronización, precios, códigos, acceso social, campañas
- →Servicio de estilizado de portadas en Go y mesa de soporte FreeScout autoalojada
Entregables
- ✓Marketplace de videojuegos con miles de SKU activos en PS y Xbox
- ✓Sincronización automática diaria de precios, cero actualizaciones manuales
- ✓Sistema de alertas de cambio de precio para detección de oportunidades promocionales
- ✓Integraciones de pasarela de pago de la CEI con entrega de claves digitales
- ✓Cadena de precio de extremo a extremo: PS Store, sitio y luego Yandex.Market, sin paso manual
- ✓Fichas de Yandex.Market con todos los atributos disponibles
Recorrido por la infraestructura y las capacidades
Un recorrido por el sistema en funcionamiento: el escaparate en WooCommerce, el catálogo que el grabber mantiene lleno, el panel de administración donde se gestionan precios y pedidos, y cómo encajan las piezas. Comentarios en ruso.
Desafío
Los jugadores de la CEI que compraban títulos de PlayStation y Xbox se enfrentaban a un mercado fragmentado: los precios de las tiendas oficiales variaban significativamente según la región, los revendedores de tarjetas de regalo estaban dispersos por foros, y no había un único lugar para comparar y comprar. Cofundé CactusPlay para llenar ese vacío, un marketplace de juegos y objetos dentro del juego con datos de precios reales procedentes de fuentes oficiales.
El reto técnico central: PlayStation Store y Xbox Store no exponen APIs públicas. Mantener miles de SKU con precios exactos casi en tiempo real requería construir desde cero una capa de scraping y sincronización.
Descubrimiento
La investigación inicial mapeó el recorrido completo del comprador: descubrir un juego, comparar el precio entre regiones, comprar la clave legítima más barata, canjearla. El dolor estaba en los pasos de comparar y comprar. Existían vendedores, pero estaban fragmentados; los compradores no tenían señales de confianza. Un marketplace con datos de precios consistentes, vendedores verificados y un checkout limpio podía apropiarse de esa parte central del embudo.
Opciones consideradas
- Entrada manual de precios por administradores: descartado. No escala; los precios cambian a diario, a veces cada hora durante las rebajas.
- API de terceros para agregación de precios, existía ninguna para PlayStation/Xbox en la CEI en ese momento.
- Scrapers personalizados en Node.js + tienda en WordPress/WooCommerce: elegido. Los scrapers dan propiedad real de los datos; WooCommerce aporta una capa de comercio probada en batalla sin construir el checkout desde cero.
Decisión
Scrapers en Node.js que se ejecutan según una programación cron consultan los endpoints de PlayStation Store y Xbox Store, analizan la respuesta y envían actualizaciones de precio y disponibilidad a WooCommerce a través de su API REST. WordPress + WooCommerce se encargan de la tienda, el carrito y las integraciones de pasarelas de pago. Extensiones personalizadas en PHP gestionan los flujos de incorporación de vendedores que WooCommerce no soportaba de fábrica.

cactusplay.ru, scrollable snapshot of the live storefront
Implementación
Se construyeron scrapers de ingeniería inversa para ambas tiendas, gestionando sesiones, cambio de región y medidas anti-bot. Se configuró un sistema de actualización diferencial: solo los precios que cambian disparan actualizaciones en WooCommerce, manteniendo baja la carga de la API. Un sistema de alertas de cambio de precio notifica a los administradores cuando un producto cae por debajo de un umbral, permitiendo decisiones de timing promocional.
Se integraron pasarelas de pago compatibles con métodos de pago de la CEI. Extensiones personalizadas de WooCommerce en PHP se encargaron de la entrega digital (códigos de clave) y la lógica de pagos a vendedores. Desplegado en un VPS con despliegue automatizado mediante Git hooks.
Preparación legal para aceptar pagos
Aceptar tarjetas de bancos rusos fue primero un problema de papeleo y solo después de plugins. Ningún proveedor da de alta una tienda sin forma legal, así que la forma fue lo primero: el conjunto completo de documentos (oferta pública, política de privacidad, consentimiento para el tratamiento de datos personales, condiciones de devolución y entrega), el registro en el registro estatal de operadores de datos personales y el alta como trabajador autónomo para poder facturar.
Solo entonces se montó el circuito de pago: adquirencia mediante el plugin de WooCommerce del banco Tochka y, junto a él, LifePay CloudPrint para emitir los tickets fiscales, que el plugin de adquirencia no generaba por sí mismo. Lo que ve el comprador es lo que cuenta: pagar directamente con una tarjeta de un banco ruso, en el sitio, y recibir el ticket que exige la ley.
El sistema detrás de la tienda
La tienda es solo una cara de un sistema mayor. Un grabber en Node.js recorre la PlayStation Store oficial, y la Xbox Store sobre la misma abstracción, extrayendo más de 20 000 posiciones cada hora. Itera juegos, DLC y servicios por separado, renombra las categorías a la taxonomía propia de la tienda y fusiona las etiquetas de las stores, de modo que el catálogo llega estructurado y no como un volcado plano.
El resto lo sostienen cinco plugins de WordPress a medida:
- slave-api. El motor de sincronización. Contiene la abstracción de plataformas (una única interfaz sobre las API de PlayStation y Xbox), los manejadores que cambian la visibilidad o retiran SKU, comandos CLI para sincronizaciones totales y parciales, y escenarios de actualización versionados: una regla de catálogo se despliega sobre una tienda viva sin una pasada manual.
- product-manager. El lado de precios de la tienda. Consulta a la PlayStation Store los precios vigentes en varias monedas, elige uno mediante una estrategia intercambiable (la incluida toma el precio regional legítimo más bajo), guarda el resultado en transients para que una ficha de producto nunca espere a una llamada externa, e inyecta los campos personalizados que el flujo necesita en el formulario de producto, el carrito, la compra y el pedido.
- product-code-manager. La mitad de la entrega digital. Genera y almacena códigos de producto, los resuelve y activa, y expone una API autenticada por JWT para que un pedido creado en cualquier parte del sistema se complete sin una persona de por medio. Los manejadores reaccionan a la creación del pedido y a los cambios de estado, y por eso el código llega justo después de la compra digital en lugar de tras un envío manual.
- aw-auth. El acceso. Coloca VK, Yandex, Steam y Discord en los formularios de WordPress y WooCommerce bajo un único contrato de proveedor: cada red nueva es un cliente, un servicio y una pantalla de ajustes, no una bifurcación del flujo. Steam se verifica contra firmas OpenID 2.0 y el resto mediante intercambio de código OAuth; a quien vuelve se le asocia su cuenta existente y solo se crea una nueva si no hay coincidencia. Como una devolución de llamada puede llegar dos veces, cada código se reserva en una tabla de bloqueo con contador: la segunda petición espera a la primera y sigue su redirección en lugar de duplicar la cuenta. Steam no entrega correo, así que esos usuarios pasan por un formulario de correo y teléfono antes de comprar. El acceso es solo por correo, la dirección debe estar en un dominio .ru por la normativa rusa de datos personales, y la caché privada se purga al entrar para que nadie vea una página obsoleta.
- mail-manager. El motor de campañas propio, para que el correo a clientes no dependiera de un proveedor externo. Las audiencias son categorías, las campañas se enlazan a categorías y la cola pendiente se deriva con un join: a quien ya tiene un registro de envío para una campaña no se le vuelve a elegir, de modo que una ejecución interrumpida continúa justo donde se cortó. Un cron envía un lote fijo con una pausa entre mensajes, manteniendo la tienda dentro del límite SMTP en vez de disparar una ráfaga que marca el dominio. Tras la activación el envío está desactivado y un interceptor registra los mensajes en vez de entregarlos, así una copia de la base de producción no puede escribir a clientes reales; el panel muestra pendientes, enviados y fallidos por campaña. Las columnas de aperturas y clics y el endpoint de seguimiento están esbozados: lo que llegó a producción es la entrega.
Yandex.Market: una cadena de precio de extremo a extremo
La integración con el marketplace cierra el círculo. Las ofertas se mapean al esquema de Yandex.Market mediante una capa de mappers dedicada, con configuración por tienda, y un servicio de precios las mantiene al día. La cadena funciona sin intervención humana en ningún paso: el precio cambia en la PlayStation Store oficial, el grabber lo recoge, se actualiza el sitio and then se actualiza la oferta en Yandex.Market. Los códigos se entregan lo bastante rápido como para que una compra digital en el marketplace se complete en la misma sesión, y las fichas llevan todos los atributos que Yandex.Market admite, no el mínimo para publicar.
Servicio de estilizado de portadas, hecho, no integrado
Un servicio aparte en Go componía portadas listas para el marketplace: el arte original, un fondo desenfocado para cubrir la proporción exigida, una cabecera con la marca de la tienda y distintivos de edición. Se terminó y produjo el resultado de abajo, pero la integración en la canalización del catálogo nunca se completó, las portadas salieron sin estilizar.

Soporte
La atención al cliente funciona sobre un FreeScout autoalojado en support.cactusplay.ru: chat web y Telegram en una sola bandeja, con los últimos pedidos del cliente cargados junto a la conversación para que el agente responda sin cambiar de sistema.

El motor de correo propio de la tienda
mail-manager, el motor de campañas descrito más arriba, en funcionamiento. Está en CactusPlay y en los sitios de consultoría, que es lo que mantiene el correo a clientes fuera de un proveedor externo.
El formulario antes de la versión final
Tanto el formulario de activación como la guía se apoyan en product-code-manager, igual en CactusPlay que en 1gros. Esta es una versión anterior, intermedia, del formulario: se grabó para repasar el enfoque con el socio y confirmar que era el correcto antes de desarrollarlo del todo.
Otra toma de ese formulario temprano, esta vez con la vista previa: antes de confirmar, el comprador ve qué producto le dará el código. Los fallos de JS en pantalla se corrigieron más tarde.
Guía de activación del código
Un vídeo demostrativo colocado en el propio sitio que guía al comprador en la activación de su código. Está en CactusPlay y en 1gros, el sitio de consultoría. Ese onboarding dejó el proceso lo bastante claro como para que la gente dejara de reclamar a Yandex por él.
Acceso con proveedores rusos
El módulo aw-auth, que existe por separado y aquí se reutiliza en CactusPlay y en los sitios de consultoría. Cubre el acceso OAuth con proveedores para los que entonces no había soluciones hechas: Yandex fue, que yo sepa, el primero disponible, además de VK y Discord. Pensado para el mercado ruso, con los requisitos legales de datos que eso implica.
Entrega inmediata para Yandex.Market
Entrar en el marketplace de Yandex.Market traía una restricción dura: tras la compra hay 15 minutos para entregar el producto digital. Nuestros productos se activan sobre una cuenta en lugar de entregarse como una clave suelta, y eso no cabe en 15 minutos.
La salida fue un formulario propio de activación de claves. Al comprar, nuestra API emite al comprador una clave que en realidad es una obligación diferida, con lo que se cumple la ventana de entrega de Yandex; la activación sobre la cuenta se realiza después en nuestra plataforma, cerrando el pedido del lado de Yandex.
Consultoría para otras tiendas
El grabber y lo construido a su alrededor también salieron en forma de consultoría. Los apliqué en 1gros.ru, ps-store.ru, playstaionplus.ru y xbox-store.ru: sincronización de la base del catálogo con mi propio parser, integración de tiendas de terceros, ajuste de su WordPress y mantenimiento continuo. El vídeo muestra uno de esos sitios, 1gros.
El grabber en acción
Recogida de los listados estáticos de productos del sitio de PlayStation, la materia prima con la que se arma el catálogo.
La otra mitad del mismo trabajo: ajustar el coeficiente de precio que convierte el precio de la tienda oficial en el precio al que vende el shop.
Resultado
El grabber sostiene más de 20 000 posiciones por hora, y los cambios de precio llegan tanto a la tienda como a la ficha de Yandex.Market sin que nadie los toque. La plataforma manejó transacciones reales desde el lanzamiento, y la infraestructura de scraping sobrevivió a varios rediseños de front-end de PlayStation y Xbox Store mediante actualizaciones puntuales de selectores.
Soporte: carga de los rastreadores de LLM
Durante el soporte técnico continuo el sitio mostró una carga anormalmente alta que no cuadraba con el tráfico real. Los logs señalaron a los rastreadores de los proveedores de LLM populares, ClaudeBot entre ellos, recorriendo el catálogo. Se ajustó la configuración y sus agentes se añadieron a las reglas de exclusión: no traían visitantes ni pedidos, solo carga.
Disponible para colaboración por contrato
Estoy disponible para colaborar por contrato. Si tiene una idea de proyecto interesante, reserve una llamada por Calendly.
Agenda una llamada de 30 min