Módulo Web · Guía de integración
Construí tu propio sitio, cableado a MOBU
La plantilla Custom HTML del Módulo Web te deja pegar tu propio HTML/CSS/JS y reemplazar toda la portada de tu tienda — mientras el catálogo, el carrito, el checkout y el pago siguen siendo nativos de MOBU. Tu sitio lee productos, promos y contenidos en vivo, y opera el negocio a través del SDK window.MOBU y la API pública REST.
Para cualquier desarrollador — interno o externo — que quiera diseñar la vidriera de un negocio MOBU sin tocar el código de la plataforma. No necesitás credenciales de infraestructura: todo lo que ves acá funciona desde el navegador, contra la API pública de la tienda publicada.
Cómo funciona
Cuando tu tienda usa la plantilla custom, MOBU sirve tu HTML en todas las rutas del sitio publicado (tu dominio propio o tuslug.mobu.market). Antes de mostrarlo, inyecta el runtime window.MOBU y deja disponible la API pública en el mismo origen. Vos te enfocás en el diseño; MOBU pone la lógica de comercio.
Tenés dos formas de cablear, y podés combinarlas:
El SDK window.MOBU
Objeto global ya presente en la página. Trae el catálogo, agrega al carrito y abre el checkout nativo. Ideal para tiendas de productos.
Atributos data-mobu-*
Cableás botones sin escribir JavaScript: data-mobu-add agrega un producto, data-mobu-cart abre el carrito.
API pública REST
Para todo lo demás: verticales como Eventos, catálogos a medida, o integraciones externas. fetch directo, sin token.
Requisitos y dónde se edita
El HTML custom se edita en la app, no en el repositorio:
| Paso | Dónde |
|---|---|
| 1. Abrí tu tienda | app.mobu.market → Tienda → Diseño y Personalización |
| 2. Elegí la plantilla | Seleccioná Custom HTML entre las plantillas |
| 3. Pegá tu código | En el editor de HTML (hasta 500.000 caracteres) |
| 4. Publicá | Con la tienda publicada, tu HTML sale en vivo |
Nivel del módulo (webMode)
El Módulo Web tiene tres niveles. El SDK del carrito solo opera de punta a punta en el nivel más alto:
| webMode | Incluye | Carrito / checkout |
|---|---|---|
| landing | Sitio de contenido (páginas, marca, contacto) | — |
| products | Landing + catálogo público de productos | Catálogo sí · carrito no |
| shop | Tienda completa: catálogo + carrito + checkout | Completo |
MOBU.addToCart() y MOBU.checkout() requieren el nivel Tienda completa (shop). En landing/products podés leer el catálogo y armar tu sitio, pero el checkout nativo no estará activo.
Quickstart
El “hola mundo” del HTML custom: espera a que cargue el catálogo, dibuja los productos y agrega al carrito. Pegalo tal cual en el editor de Custom HTML.
Eso es todo lo que hace falta para una tienda funcional: MOBU.ready() te entrega el catálogo, cada botón lleva data-mobu-add="handle", y el data-mobu-cart abre el checkout de MOBU. El resto es diseño.
SDK window.MOBU
Objeto global disponible en toda página de una tienda con plantilla custom. Es la forma recomendada de cablear una tienda de productos: el carrito y el checkout son de MOBU, vos solo pintás la vidriera.
Métodos y propiedades
| Miembro | Devuelve | Qué hace |
|---|---|---|
| MOBU.ready(cb) | void | Ejecuta cb(M) cuando el catálogo terminó de cargar. M es la misma API ya lista para usar. Es tu punto de entrada. |
| MOBU.products | Product[] | Productos publicados de la tienda (canal MOBU, activos). Ver forma del producto. |
| MOBU.config | StoreConfig | Config pública de la tienda: storeName, moneda, branding, redes. Ver modelo. |
| MOBU.cartCount() | number | Cantidad de ítems actualmente en el carrito. |
| MOBU.addToCart(handle) | void | Agrega al carrito el producto con ese handle. Requiere nivel shop. |
| MOBU.checkout() | void | Abre el checkout nativo de MOBU (datos del comprador, envío y pago). Requiere nivel shop. |
| MOBU.on(evt, cb) | void | Suscribe a un evento del sitio. Ver eventos. |
La forma del producto en el SDK
Cada elemento de MOBU.products trae los campos listos para render que usa el ejemplo oficial:
| Campo | Tipo | Uso |
|---|---|---|
| handle | string | Identificador estable del producto. Es lo que pasás a addToCart() y a data-mobu-add. |
| title | string | Nombre para mostrar. |
| priceFormatted | string | Precio ya formateado en la moneda de la tienda (ej. $ 12.990). |
| image | string | URL de la imagen principal (puede venir vacío). |
¿Necesitás variantes, atributos, stock, categorías o SEO? Todo el modelo enriquecido está en la API pública (GET /products). El SDK te da lo justo para pintar rápido; la API te da el detalle.
Atributos data-mobu-*
Si no querés escribir JavaScript, cableás cualquier elemento con atributos. MOBU los detecta y los hace funcionar solos.
| Atributo | En | Al hacer click |
|---|---|---|
| data-mobu-add="handle" | Un botón / cualquier elemento | Agrega ese producto al carrito. |
| data-mobu-cart | Un botón / cualquier elemento | Abre el carrito / checkout de MOBU. |
Eventos del SDK
Suscribite con MOBU.on(evento, callback) para mantener tu UI en sync con el estado del carrito.
| Evento | Se dispara | Uso típico |
|---|---|---|
| 'cart' | Cada vez que cambia el carrito (alta, baja, cantidad) | Actualizar el contador del carrito, un mini-cart, un badge. |
Modelo de datos · Producto
Respuesta de GET /products y GET /products/{handle}. Nunca incluye costo ni flags internos. Este modelo es el que te permite armar verticales ricos (autos, inmuebles, servicios) además de productos clásicos.
| Campo | Tipo | Descripción |
|---|---|---|
| id | string | Identificador único. |
| handle | string | Slug estable para carrito y URLs. |
| name | string | Nombre del producto. |
| description | string | Descripción larga. |
| category · brand | string | Rubro y marca (texto). |
| service | boolean | true = servicio (no lleva stock físico). |
| images | {url,primary}[] | Galería. primary marca la portada. |
| prices | {currency,amount,compareAt}[] | Precio por moneda. compareAt = precio anterior tachado (o null). |
| options | {name,values[]}[] | Ejes de variación (Talle, Color…). |
| variants | {id,options,sku,price,available}[] | Combinaciones concretas con su stock y precio. |
| attributes | {name,value}[] | Ficha técnica libre (Año, Km, Ambientes, m²…). Clave para autos e inmuebles. |
| trackInventory | boolean | Si controla stock. |
| available | number | Stock disponible. |
| categoryId | string | Nodo del árbol de categorías (arma nav/subcategorías). |
| requiresShipping | boolean | false = retiro / coordinación (un auto, un inmueble, un servicio). |
| seoTitle · seoDescription | string | SEO (siempre poblados). |
Modelo de datos · Tienda
Respuesta de GET /config (y lo que trae MOBU.config). Todo lo que necesitás para reflejar la marca y las capacidades activas de la tienda.
| Grupo | Campos |
|---|---|
| Identidad | slug, storeName, template, customHtml |
| Marca | accentColor, secondaryColor, logoUrl, logoDarkUrl, logoScale, faviconUrl, heroTitle, heroSubtitle, fontFamily |
| Comercio | currencyCode, webMode, paymentMethods[], shippingMethods[], shippingOptions[] {id,name,price,eta,note} |
| Contenido | pagesJson, footerJson, secondaryJson, socialJson (JSON crudo, saneado server-side — parsealo y renderizá escapado) |
| Marketing | gtmContainerId, gaMeasurementId, metaPixelId, analyticsEnabled, bannerEnabled, bannerImageUrl, bannerAnimation, bannerFeaturedHandle |
| CRM | webchatEnabled, webchatToken (la burbuja del Web chat solo si hay canal WEBCHAT activo) |
Promos y categorías
Promociones automáticas
GET /promotions devuelve las promos automáticas vigentes (sin código) para que muestres precios rebajados y una barra de ofertas. Por diseño, nunca se expone un código de cupón.
| Campo | Tipo | Descripción |
|---|---|---|
| type | string | Tipo de descuento (porcentaje / monto). |
| value | number | Magnitud del descuento. |
| scope · scopeIds | string · string[] | A qué aplica (tienda, categoría, productos). |
| includeSubcategories | boolean | Si baja a subcategorías. |
| minSubtotal | number | Subtotal mínimo para activarse. |
| name | string | Etiqueta para el badge de oferta. |
Árbol de categorías
GET /categories devuelve las categorías activas para armar el nav. parentId = null es raíz; con valor, es subcategoría.
| Campo | Tipo | Descripción |
|---|---|---|
| id · name · slug | string | Identidad de la categoría. |
| parentId | string | null = raíz · con valor = subcategoría. |
| sortOrder | number | Orden de aparición. |
| imageUrl | string | Portada (si es null, usá un gradiente). |
API pública REST · Tienda & catálogo
Base: /api/public/storefronts. Desde tu HTML custom usá rutas relativas (corre en el mismo origen que la tienda publicada, sin token). Para integraciones externas, prefijá el host de la API (p. ej. https://api.mobu.market). El CORS es abierto sin credenciales en estos endpoints.
mitienda.com) → { slug }. Útil para integraciones externas.{ [id]: { count, average } } → estrellas en el catálogo.
Cotización y checkout
Si construís tu propio flujo de compra (en vez de usar MOBU.checkout()), tenés dos endpoints. El precio y el descuento se recalculan siempre server-side: tu sitio solo los muestra.
paymentUrl. La venta/stock/cobranza se confirman al pagar.Request — quote y checkout
| Campo | Tipo | En |
|---|---|---|
| items | {handle,options,quantity}[] | quote · checkout |
| couponCode | string? | quote · checkout |
| string? | quote | |
| buyer | {name,email,phone,doc} | checkout |
| shippingMethod · shippingAddress | string? | checkout |
| paymentMethod | string? | checkout |
| externalOrderId | string? | checkout · idempotencia |
Response
| quote → | checkout → |
|---|---|
currency, subtotal, discount, total, couponCode, discountLabel, freeShipping, discountError | orderId, status, currency, total, message, paymentUrl |
El checkout público viene apagado por defecto y con rate-limit. Si está deshabilitado, la API responde 503; ante demasiados intentos, 429. Activá el checkout desde la configuración de la tienda antes de probar en vivo.
Tipos de negocio · Eventos (ticketing)
El vertical de Eventos no usa el SDK del carrito: tiene su propia API pública de ticketing con funciones, butacas, lista de espera y pago con Stripe. Tu HTML custom vende entradas llamando directo a estos endpoints. Solo necesitás el editionId de tu edición (lo ves en la URL del panel de Eventos).
Base: /api/public/events
name, startsAt, venue, city, country, currency, brandColor, logoUrl, coverImageUrl, policies, ticketTypes[].available (null = sin tope).ticketTypeId, sessionId?, seatIds?, attendeeName, attendeeEmail, company?, promoCode?, UTMs. Devuelve la inscripción.El campo ticketTypes[] de la edición trae, por tipo: id, name, description, kind, price, currency, available, saleStartsAt, saleEndsAt. Con eso armás las tarjetas de entrada. El ejemplo completo está en Ejemplos y como plantilla cargable en la app (“Cargar ejemplo: Venta de entradas”).
Tipos de negocio · Agencias de autos e inmuebles
Los verticales de catálogo (autos, inmuebles, servicios) no tienen una API aparte: se modelan sobre el mismo producto público, apoyándose en tres campos:
attributes[]— la ficha técnica libre: Año, Kilómetros, Combustible, Transmisión, Motor para un auto; Ambientes, m², Cochera, Expensas para un inmueble.requiresShipping: false— no se envía: es retiro, visita o coordinación. El checkout puede usarse como seña / reserva, o reemplazarlo por un formulario de consulta.categoryId— para filtrar por segmento (0km / usados, o tipología de inmueble) con el árbol de/categories.
Así, una agencia de autos arma su showroom leyendo GET /products, dibujando cada unidad con su galería y su ficha de attributes, y ofreciendo “Reservar” (checkout de seña) o “Consultar” (lead al CRM). El mismo patrón sirve para inmobiliarias y prestadores de servicios.
El Módulo Web es genérico: los verticales se expresan con categoría + atributos + requiresShipping, no con endpoints nuevos. La única excepción con API propia es Eventos, por su lógica de entradas, funciones y butacas.
Límites y seguridad
Solo lectura + checkout
La API pública expone catálogo, config, promos y reseñas, y permite cotizar/checkout. Nunca datos internos: sin costos, sin márgenes, sin flags.
Sin token, CORS abierto
Los endpoints públicos no piden auth y responden CORS sin credenciales. No pongas secretos en tu HTML: es 100% visible.
Escapá el contenido
pagesJson, socialJson y demás vienen saneados server-side, pero renderizalos escapados. No inyectes HTML de terceros sin sanitizar.
Precios del servidor
El total lo recalcula MOBU en quote/checkout. Nunca confíes en un precio calculado en el cliente para cobrar.
Rate-limit & kill-switch
Checkout apagado por defecto, con límite de intentos (429) y disponibilidad (503). Contemplá esos estados en tu UI.
Límite del HTML
Hasta 500.000 caracteres. Cargá librerías pesadas por CDN, no las pegues inline.
Ejemplos completos
Dos plantillas listas para pegar. Ambas están también disponibles como “Cargar ejemplo” dentro del editor de Custom HTML en la app.
A · Tienda de productos (SDK window.MOBU)
Grilla de productos desde el catálogo, botón de agregar por producto y carrito flotante en vivo. Carrito y checkout nativos de MOBU.
B · Venta de entradas (API de Eventos)
Carga una edición, lista tipos de entrada y funciones, toma los datos del comprador y arranca el pago con Stripe. Reemplazá EDITION_ID por el de tu edición. (Versión condensada; la plantilla extendida está en la app.)
Próximos capítulos del portal: Webhooks, referencia del resto de los módulos, y plugins & OAuth para integraciones autenticadas. ¿Falta un endpoint o un caso? Es la base para seguir documentando.