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
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_requiredsi 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'),validatePurchaseygetProductsdesderoom.jsaú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):
{
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.