Capítulo pagos de la guía Neblla — productos, checkout Stripe, validación y consumo. BETA. El contrato base está en core.txt. # Compras (BETA) Integración de Stripe en beta. El desarrollador no procesa pagos, no monta endpoints de Stripe, no gestiona webhooks. Dos tipos de producto: `one_time` y `consumable`. ## API ```javascript neblla.getProducts(); // listar lo que tienes en venta neblla.buy('skin_dorado'); // abre checkout de Stripe neblla.buy('monedas_pack', 100); // consumible con cantidad neblla.consume('monedas_pack', 10); // consumir unidades neblla.validatePurchase(userId, 'vip_pass'); // verificar (también desde server) ``` Firmas: - `neblla.buy(productId, amount?)` **(CLIENT, login)** — abre el checkout de Stripe en una ventana. Llámalo dentro del gesto del usuario (un click) para que el navegador no bloquee la ventana. La promesa se resuelve cuando la ventana está abierta, NO cuando se ha pagado: lo comprado llega después con el evento `'purchase'`. Rechaza con el código del servidor (`login_required` si el jugador no ha entrado con su cuenta Neblla, `feature_disabled`, …). Los datos de tarjeta nunca pasan por el código de la app. Los productos no se pueden comprar hasta que la cuenta de cobros del dev (Stripe Connect) está activa. - En modo servidor `infra` (`serverMode: 'infra'`), `validatePurchase` y `getProducts` desde `room.js` aún no están disponibles (devuelven `{ valid: false }` / `[]`); en el modo por defecto funcionan. - `neblla.consume(productId, amount)` **(CLIENT)** — consume unidades. - `neblla.validatePurchase(userId, productId)` **(BOTH)** — verifica posesión. - `neblla.getProducts()` **(BOTH)** — lista productos. ## Evento purchase Cuando la compra se confirma, el evento `'purchase'` (`{ userId, productId, type, purchases }`) se dispara en todos los clientes de la sala donde esté el comprador. Útil para reaccionar en tiempo real (animación, desbloqueo del skin). Propiedad: `neblla.purchases` **(CLIENT)** — shortcut a `neblla.me.purchases`. ## Validación autoritaria `validatePurchase` también se puede llamar desde `room.js` — útil para gatear acciones autoritarias detrás de la posesión de un producto. Ejemplo: para entrar a la sala VIP, `room.js` valida que el usuario tenga `vip_pass` antes de admitirlo, sin que pueda fingirlo desde su cliente. ## Schema de producto Al crear un producto desde el dashboard (o desde el MCP): ```javascript { name: { en: 'Gold skin', es: 'Skin dorado' }, // i18n map o string description: { en: '...', es: '...' }, // opcional image: 'https://.../skin.png', // opcional type: 'one_time' | 'consumable', price: 499, // céntimos, sólo one_time pricePerUnit: 10, // céntimos, sólo consumable step: 1, // tamaño del bundle (consumable) min: 1, max: 1000, // límites del slider (consumable) published: true, // visible en getProducts() currency: 'usd', // ISO-4217 defaultLang: 'en', // fallback i18n } ``` ## Garantías Los pagos están mediados: `room.js` solo ve el resultado (la compra confirmada), nunca datos de tarjeta, ni tiene capacidad de regalar ítems gratis o falsificar compras de otro usuario.