SubSovereign en Web & React Native — guía de integración
Esta guía cubre el SDK de JavaScript/TypeScript, que funciona en tres entornos desde una misma biblioteca: React Native (iOS + Android), React Native TV y la web (con Stripe). Lleva tu app de "no tengo ni idea de quién me ha pagado" a "mi app desbloquea las funciones correctas para el usuario correcto, verificadas en mi propio servidor".
Qué hace SubSovereign por ti
Tus usuarios se suscriben a través de una tienda de aplicaciones (Apple, Google) o, en la web, mediante Stripe. SubSovereign responde a una única pregunta para tu app, de forma fiable: ¿qué ha pagado realmente este usuario?
- Tu app pregunta a SubSovereign por el derecho de acceso del usuario — lo que ha desbloqueado.
- La validación de recibo se realiza en el servidor, directamente con la tienda (o Stripe), por lo que un cliente manipulado no puede falsificar una suscripción.
- El muro de pago se configura de forma remota, así que puedes cambiar precios, pruebas y redacción sin necesidad de redeploy.
- Es autoalojado: se ejecuta en tu infraestructura, los datos de tus usuarios se quedan contigo y no hay porcentaje de ingresos — te quedas con el 100 % de lo que pagan tus usuarios.
Nunca confíes en el cliente. El cliente pregunta; el servidor decide.
Antes de empezar
Necesitarás un servidor SubSovereign en ejecución, una app registrada en el panel de control (que te proporcionará un appId y una clave de API), y tus niveles de acceso (rangos, por ejemplo, pro) creados y vinculados a los productos que compran tus usuarios: productos de App Store / Google Play para React Native, o precios de Stripe para web. Gestiona la compra en sí como lo harías normalmente (bibliotecas de compras integradas en React Native, Stripe Checkout/Billing en web); SubSovereign verifica y registra la compra después.
Paso 1 — Instalar el SDK
npm install @subsovereign/js-sdk
import SubSovereign from '@subsovereign/js-sdk';
Paso 2 — Configurar una vez, al iniciar la app
SubSovereign.configure({
apiKey: 'YOUR_APP_API_KEY', // del panel de control
appId: 'your-app-id', // del panel de control
baseUrl: 'https://subs.yourdomain.com/api/v1', // TU servidor autoalojado
userId: currentUser.id, // tu propio ID de usuario estable
locale: 'es', // el idioma del usuario
});
Usa un userId estable para el usuario conectado: el mismo valor en todas partes, para que el acceso le siga en todos los dispositivos y plataformas. Vuelve a ejecutar configure si un usuario diferente inicia sesión.
Paso 3 — Comprobar a qué puede acceder el usuario
La imagen completa se obtiene con checkEntitlements():
try {
const result = await SubSovereign.checkEntitlements();
if (result.hasAccess) unlockProFeatures();
else showFreeExperience();
} catch (err) {
// Mantén al usuario con su último acceso conocido y vuelve a intentarlo más tarde.
console.warn('Error al comprobar el derecho de acceso:', err);
}
Para una puerta sencilla hay un asistente de conveniencia, hasAccess(), que se cierra por defecto (devuelve false) en caso de error de red para que un fallo puntual nunca desbloquee funciones de pago por error:
if (await SubSovereign.hasAccess('pro')) unlockProFeatures();
Cada derecho de acceso en result.entitlements incluye accessLevelId, isActive, expiresAt, willRenew y su store. result.fromCache es true si la respuesta provino de la última caché conocida durante una breve interrupción.
Paso 4 — Vender una suscripción
Mostrar el muro de pago
const paywall = await SubSovereign.getPaywallConfig('web'); // o 'ios' | 'android' | 'firetv' | 'roku'
if (paywall) renderPaywall(paywall); // titular, funciones, productos…
else renderFallbackPaywall();
Completar la compra y luego verificarla
Ejecuta la compra de la forma habitual para la plataforma y, a continuación, pasa el resultado a SubSovereign para que el servidor valide la compra y conceda el nivel de acceso. Elige la llamada que coincida con dónde se realizó la compra:
// Web (Stripe)
await SubSovereign.validateStripeSubscription({
subscriptionId, productId, accessLevelId: 'pro',
});
// React Native — iOS (StoreKit)
await SubSovereign.validateApplePurchase({ transactionId, productId, accessLevelId: 'pro' });
// React Native — Android (Play Billing)
await SubSovereign.validateGooglePurchase({ purchaseToken, productId, accessLevelId: 'pro' });
Cada una devuelve true una vez que el servidor ha confirmado la compra. Vuelve a ejecutar checkEntitlements() después y desbloquea.
Banderas de funciones
Lanza funciones desde el servidor sin necesidad de deploy:
const flags = await SubSovereign.getFeatureFlags(); // { newPlayer: true, ... }
if (flags.newPlayer) showNewPlayer();
Paso 5 — Privacidad: GDPR y CCPA
await SubSovereign.recordConsent({ purpose: 'analytics', granted: true });
await SubSovereign.requestErasure(); // "olvídame"
const myData = await SubSovereign.exportMyData(); // exportación de datos
await SubSovereign.setDoNotSell(true); // señal "No vender" de CCPA / GPC
Gestión de errores
checkEntitlements y las llamadas validate… lanzan excepciones en caso de fallo — envuélvelas en try/catch y, en caso de error, mantén al usuario con su último acceso conocido y vuelve a intentarlo más tarde; nunca bloquees a un usuario de pago por un fallo puntual. Los asistentes de conveniencia (hasAccess, getPaywallConfig, getFeatureFlags) en cambio se cierran por defecto, devolviendo false/null/{}, por lo que es seguro llamarlos en línea.
Buenas prácticas
- Comprobar al montar / iniciar para que el bloqueo sea justo antes de que el usuario llegue a una función bloqueada.
- Volver a comprobar después de comprar para que la interfaz se actualice inmediatamente.
- Nunca confíes en el cliente — pregunta al servidor; es quien verificó el recibo.
- Un
userIdpor usuario real, mantenido estable en web y móvil.
Referencia rápida
| Quieres… | Llama a… |
|---|---|
| Configurar el SDK | SubSovereign.configure(config) |
| Ver qué ha desbloqueado el usuario | await checkEntitlements() → EntitlementResult |
| Puerta sencilla (cerrado por defecto) | await hasAccess('pro') → boolean |
| Mostrar el muro de pago remoto | await getPaywallConfig(platform) → PaywallConfig | null |
| Verificar una compra de Stripe / Apple / Google | await validateStripeSubscription / validateApplePurchase / validateGooglePurchase(…) |
| Leer banderas de funciones | await getFeatureFlags() |
| GDPR / CCPA | recordConsent · requestErasure · exportMyData · setDoNotSell |
Pasos siguientes
- Las plataformas nativas tienen sus propias guías: Android, iOS, Roku.
- ¿Nuevo en estos conceptos? Lee Cómo funciona SubSovereign.