RevenueView

Live-Tracking: das SDK in eine App einbauen

Das ist der optionale Weg B (Live-Zahlen wie RevenueCat). Es ist ein privates Flutter-Package, das du in jede App einbaust. Pro App sind es genau drei Stellen im Code und ein app-eigener Schlüssel – sonst nichts. popart ist bereits fertig eingebaut und dient hier als Vorlage.

Wichtig zu verstehen: Der Code ist in jeder App identisch – die einzige Sache, die sich pro App unterscheidet, ist der apiKey in Schritt 3.
Springe zu: ① Key holen ② pubspec.yaml ③ main.dart ④ Kauf-Handler ⑤ Bauen & Prüfen Apps mit anderem IAP-Code

① App-Schlüssel holen 1× pro App

  1. Auf Einrichtung → Teil B die App im Dropdown wählen → „Key erzeugen" → Kopieren. Sieht so aus: rv_appname_ab12cd34…
  2. Diesen Key brauchst du gleich in Schritt 3. Er ist kein Geheimnis (steckt in der App), die eigentliche Prüfung passiert serverseitig gegen Apple/Google.

② Package als Abhängigkeit pubspec.yaml

In der Datei <app>/app/pubspec.yaml, im Block dependencies:, diese Zeilen ergänzen:

dependencies:
  # … deine bestehenden Pakete …
  in_app_purchase: ^3.3.0
  # RevenueView – lokales Package (kein pub.dev). Pfad relativ von <app>/app/
  revenueview_sdk:
    path: ../../revenueview_sdk
Der Pfad ../../revenueview_sdk stimmt, wenn deine App unter ~/projects/<app>/app/ liegt (Package liegt unter ~/projects/revenueview_sdk).

Danach einmal flutter pub get im App-Ordner ausführen.

③ Einmal initialisieren main.dart

Oben bei den Imports:

import 'package:revenueview_sdk/revenueview_sdk.dart';

Und in main() vor runApp(...) (nur der apiKey ist pro App verschieden – hier poparts echter Key als Beispiel):

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // … deine bestehende Initialisierung …

  // WARUM: sagt dem SDK, wohin Käufe gemeldet werden. Ohne diesen Aufruf
  // passiert nichts. Crash-safe, blockiert die UI nicht.
  await RevenueView.configure(
    apiKey: 'rv_popart_eaf2d6b9fc7387bd096b706e', // <-- der Key aus Schritt 1
    baseUrl: 'https://revenueview.glowiszyn.com',
  );

  runApp(const MyApp());
}

④ Eine Zeile im Kauf-Handler dein IAP-Service

Dort, wo dein purchaseStream einen Kauf als erfolgreich meldet (PurchaseStatus.purchased / restored) – so sieht es in popart aus:

void _onPurchaseUpdated(List<PurchaseDetails> list) {
  for (final purchaseDetails in list) {
    switch (purchaseDetails.status) {
      case PurchaseStatus.purchased:
        // WARUM HIER: nur im Status purchased/restored liegt ein gültiger
        // Kauf-Token vor, den der Server gegen Apple/Google prüfen kann.
        _reportToRevenueView(purchaseDetails);
        _deliver(IapOutcome.purchased);
        break;
      case PurchaseStatus.restored:
        _reportToRevenueView(purchaseDetails); // Restores dedupliziert der Server
        _deliver(IapOutcome.restored);
        break;
      // pending / canceled / error: nichts melden
    }
    if (purchaseDetails.pendingCompletePurchase) {
      _iap.completePurchase(purchaseDetails);
    }
  }
}

Und diese kleine Hilfsmethode dazu (schickt Preis + Währung aus den bereits geladenen ProductDetails mit – Google liefert serverseitig keinen Preis):

void _reportToRevenueView(PurchaseDetails purchaseDetails) {
  ProductDetails? pd;
  for (final p in products.value) {        // deine geladene Produktliste
    if (p.id == purchaseDetails.productID) { pd = p; break; }
  }
  RevenueView.report(
    purchaseDetails,
    price: pd?.rawPrice,
    currencyCode: pd?.currencyCode,
  );
}
Das war alles im Code. RevenueView.report() ist „feuern und vergessen": läuft asynchron, hat eine Offline-Warteschlange (Käufe gehen nie verloren) und blockiert den Kauf nie.

⑤ Bauen, einreichen, prüfen

  1. App normal bauen und in den Store hochladen. Das ist der einzige Schritt, den nur du machen kannst (Store-Release).
  2. Nach Freigabe einen (Sandbox-)Kauf auslösen.
  3. Im Dashboard → Übersicht erscheint oben die Live-Karte (roter Puls) mit dem Kauf. Bis der Server ihn validiert hat, steht er auf pending.
  4. Sobald der passende Store-Zugang gesetzt ist (Apple nutzt den .p8 aus Teil A), wird aus pending bestätigter Umsatz und fließt in Live-MRR & aktive Abos.
Nichts zu sehen? Häufigste Ursachen: falscher/fehlender apiKey, configure() wird nicht erreicht (steht es vor runApp?), oder die report()-Zeile steht nicht im purchased-Zweig.

Apps mit anderem IAP-Code

Deine Apps heißen intern unterschiedlich (iap_service.dart, purchase_service.dart, purchase_manager.dart …). Das Prinzip bleibt immer gleich:

  1. Finde die Stelle, an der ein Kauf als erfolgreich gilt (Suche nach PurchaseStatus.purchased oder completePurchase).
  2. Rufe dort RevenueView.report(purchaseDetails, price: …, currencyCode: …) auf. Preis/Währung nur, wenn du die passenden ProductDetails zur Hand hast – sonst weglassen, der Server ergänzt den Betrag später aus den Reports:
// Minimalfassung, wenn du keine ProductDetails griffbereit hast:
RevenueView.report(purchaseDetails);

Und natürlich Schritt ② (pubspec) + ③ (configure in main) – die sind für jede App identisch.

← Zur Einrichtung · Store-Zugänge-Anleitung · Zum Dashboard