SubSovereign
All guides

SubSovereign auf Web & React Native — Integrationsanleitung

Dieser Leitfaden behandelt das JavaScript/TypeScript-SDK, das mit einer einzigen Bibliothek an drei Stellen funktioniert: React Native (iOS + Android), React Native TV und das Web (mit Stripe). Es bringt deine App von „Ich habe keine Ahnung, wer mir etwas bezahlt hat“ zu „Meine App entsperrt für den richtigen Nutzer die richtigen Funktionen – auf meinem eigenen Server überprüft.“

Was SubSovereign für dich tut

Deine Nutzer abonnieren über einen App Store (Apple, Google) oder auf dem Web über Stripe. SubSovereign beantwortet für deine App zuverlässig eine Frage: Wofür hat dieser Nutzer tatsächlich bezahlt?

  • Deine App fragt SubSovereign nach der Berechtigung des Nutzers – also dem Zugang, den er erworben hat.
  • Die serverseitige Überprüfung der Kaufbestätigung erfolgt direkt beim Store (oder Stripe), sodass ein manipulierter Client keine Abonnement fälschen kann.
  • Die Paywall wird remote konfiguriert, sodass du Preise, Testversionen und Texte ohne erneutes Bereitstellen ändern kannst.
  • Es ist selbst gehostet: Es läuft auf deiner Infrastruktur, die Nutzerdaten bleiben bei dir, und es gibt keine Umsatzbeteiligung – du behältst 100 % von dem, was deine Nutzer zahlen.

Du vertraust dem Client nie. Der Client fragt; der Server entscheidet.

Bevor du startest

Du benötigst einen laufenden SubSovereign-Server, eine im Dashboard registrierte App (die dir eine appId und einen API-Schlüssel gibt) sowie deine Zugangsebenen (Stufen, z. B. pro), die mit den Produkten verknüpft sind, die deine Nutzer kaufen – App-Store-/Google-Play-Produkte für React Native oder Stripe-Preise für das Web. Die eigentliche Kaufabwicklung übernimmst du wie gewohnt (In-App-Kauf-Bibliotheken bei React Native, Stripe Checkout/Billing auf dem Web); SubSovereign überprüft und erfasst sie anschließend.

Schritt 1 — SDK installieren

npm install @subsovereign/js-sdk
import SubSovereign from '@subsovereign/js-sdk';

Schritt 2 — Einmalige Konfiguration beim Start deiner App

SubSovereign.configure({
  apiKey:  'YOUR_APP_API_KEY',                  // aus dem Dashboard
  appId:   'your-app-id',                       // aus dem Dashboard
  baseUrl: 'https://subs.yourdomain.com/api/v1', // DEIN selbst gehosteter Server
  userId:  currentUser.id,                      // deine eigene stabile Nutzer-ID
  locale:  'de',                                // die Sprache des Nutzers
});

Verwende eine stabile userId für den angemeldeten Nutzer – denselben Wert überall, damit der Zugang über Geräte und Plattformen hinweg folgt. Führe configure erneut aus, wenn sich ein anderer Nutzer anmeldet.

Schritt 3 — Prüfen, auf was der Nutzer zugreifen kann

Das vollständige Bild liefert checkEntitlements():

try {
  const result = await SubSovereign.checkEntitlements();
  if (result.hasAccess) unlockProFeatures();
  else showFreeExperience();
} catch (err) {
  // Halte den Nutzer auf seinem letzten bekannten Zugang und versuche es später erneut.
  console.warn('Berechtigungsprüfung fehlgeschlagen:', err);
}

Für eine einfache Sperre gibt es eine praktische Hilfsfunktion, hasAccess(), die bei einem Netzwerkfehler abgeschlossen fehlschlägt (gibt false zurück), sodass ein kurzer Ausfall nie versehentlich kostenpflichtige Funktionen freischaltet:

if (await SubSovereign.hasAccess('pro')) unlockProFeatures();

Jede Berechtigung in result.entitlements enthält accessLevelId, isActive, expiresAt, willRenew und ihren store. result.fromCache ist true, wenn die Antwort während eines kurzen Ausfalls aus dem letzten bekannten Cache stammt.

Schritt 4 — Ein Abonnement verkaufen

Paywall anzeigen

const paywall = await SubSovereign.getPaywallConfig('web'); // oder 'ios' | 'android' | 'firetv' | 'roku'
if (paywall) renderPaywall(paywall);   // Überschrift, Funktionen, Produkte…
else renderFallbackPaywall();

Kauf abschließen, dann überprüfen

Führe den Kauf wie gewohnt für die Plattform durch und übergebe das Ergebnis an SubSovereign, damit der Server es überprüft und die Zugangsebene gewährt. Wähle den Aufruf, der zum Kaufort passt:

// 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' });

Jeder Aufruf gibt true zurück, sobald der Server den Kauf bestätigt hat. Führe danach checkEntitlements() erneut aus und schalte frei.

Feature-Flags

Funktionen serverseitig ohne erneutes Bereitstellen ausrollen:

const flags = await SubSovereign.getFeatureFlags(); // { newPlayer: true, ... }
if (flags.newPlayer) showNewPlayer();

Schritt 5 — Datenschutz: GDPR und CCPA

await SubSovereign.recordConsent({ purpose: 'analytics', granted: true });

await SubSovereign.requestErasure();            // „Vergiss mich“
const myData = await SubSovereign.exportMyData(); // Datenexport
await SubSovereign.setDoNotSell(true);          // CCPA „Do Not Sell“ / GPC-Signal

Fehlerbehandlung

checkEntitlements und die validate…-Aufrufe werfen bei Fehlern – umschließe sie mit try/catch und halte den Nutzer im Fehlerfall auf seinem letzten bekannten Zugang und versuche es später erneut; sperre nie einen zahlenden Nutzer wegen eines kurzen Ausfalls aus. Die praktischen Hilfsfunktionen (hasAccess, getPaywallConfig, getFeatureFlags) schlagen stattdessen abgeschlossen fehl und geben false/null/{} zurück, sodass sie sicher inline aufgerufen werden können.

Best Practices

  • Bei jedem Laden/Start prüfen, damit die Sperre direkt vor dem Erreichen einer gesperrten Funktion greift.
  • Nach einem Kauf erneut prüfen, damit sich die Oberfläche sofort aktualisiert.
  • Dem Client nie vertrauen – frage den Server; er hat die Kaufbestätigung überprüft.
  • Eine userId pro echter Nutzer, stabil über Web und Mobile hinweg.

Schnellreferenz

Du möchtest… Aufruf
SDK einrichten SubSovereign.configure(config)
Sehen, was der Nutzer freigeschaltet hat await checkEntitlements()EntitlementResult
Einfache Sperre (abgeschlossen fehlschlagend) await hasAccess('pro')boolean
Remote-Paywall anzeigen await getPaywallConfig(platform)PaywallConfig | null
Stripe-/Apple-/Google-Kauf überprüfen await validateStripeSubscription / validateApplePurchase / validateGooglePurchase(…)
Feature-Flags lesen await getFeatureFlags()
GDPR / CCPA recordConsent · requestErasure · exportMyData · setDoNotSell

Nächste Schritte