aisplice

In Ihre App einbauen

Google-Play-Abos

Für Android-Apps, die Abos über Google Play verkaufen und kein eigenes Backend haben. Ihre App sendet das Kauftoken mit einem API-Schlüssel an das Gateway; das Gateway fragt mit Ihrem Dienstkonto bei Google nach und antwortet, ob das Abo aktiv ist. Die Prüfung ist kostenlos.

#Bevor Sie beginnen

  • Ein Play-Console-Login als Kontoinhaber oder Administrator, damit Sie Nutzer einladen können.
  • Ein Google-Konto, mit dem sich in der Google Cloud Console ein Projekt erstellen lässt (das kann jedes Google-Konto).
  • Den Paketnamen Ihrer App (applicationId), zum Beispiel com.example.app, und mindestens ein in der Play Console angelegtes Abo-Produkt.
  • Etwa 15 Minuten Klickarbeit, dann bis zu einem Tag, bis Google die Berechtigung aktiviert.

#1. JSON des Dienstkontos besorgen

Die JSON-Datei ist der Schlüssel des Dienstkontos. Mit ihr kann das Gateway Google nach den Käufen Ihrer App fragen und nach nichts anderem. Google nennt sie Dienstkontoschlüssel; sie ist nicht die OAuth-Client-Datei (client_secret_….json).

  1. 1

    Google Cloud Console öffnen und ein Projekt wählen

    console.cloud.google.com

    Nutzen Sie die Projektauswahl oben. Jedes Projekt funktioniert; ein neues nur für Play-Prüfungen hält die Dinge übersichtlich.

  2. 2

    Play API aktivieren

    APIs und Dienste → Bibliothek → Google Play Android Developer API → Aktivieren

    Suchen Sie nach genau diesem Namen. Steht auf der Schaltfläche „Verwalten“, ist die API bereits aktiv.

  3. 3

    Dienstkonto erstellen

    IAM und Verwaltung → Dienstkonten → Dienstkonto erstellen

    Geben Sie einen beliebigen Namen ein, etwa play-verify. Überspringen Sie die optionalen Schritte für Projektrollen und Nutzerzugriff: Es braucht keine Cloud-Rolle. Klicken Sie auf „Fertig“.

  4. 4

    JSON-Schlüssel herunterladen

    Dienstkonto öffnen → Schlüssel → Schlüssel hinzufügen → Neuen Schlüssel erstellen → JSON → Erstellen

    Der Browser lädt eine .json-Datei herunter. Bewahren Sie sie sicher auf: Google zeigt sie nie wieder an, und jeder, der sie hat, kann die Käufe Ihrer App lesen.

  5. 5

    E-Mail-Adresse des Dienstkontos kopieren

    Sie sieht aus wie play-verify@your-project.iam.gserviceaccount.com und steht auf der Seite des Dienstkontos sowie in der Datei als client_email. Sie brauchen sie im nächsten Schritt.

„Neuen Schlüssel erstellen“ ist ausgegraut oder wird abgelehnt?

Ihre Google-Cloud-Organisation blockiert Schlüssel-Downloads mit der Richtlinie iam.disableServiceAccountKeyCreation (bei neuen Organisationen standardmäßig aktiv). Ein Organisationsadministrator kann sie für dieses Projekt unter IAM und Verwaltung → Organisationsrichtlinien deaktivieren, oder Sie verwenden ein Projekt außerhalb der Organisation.

#2. Zugriff in der Play Console gewähren

  1. 1

    Dienstkonto einladen

    play.google.com/console → Nutzer und Berechtigungen → Neue Nutzer einladen

    Fügen Sie die E-Mail-Adresse des Dienstkontos als E-Mail-Adresse ein. Ein Dienstkonto muss die Einladung nicht annehmen.

  2. 2

    Diese zwei Berechtigungen erteilen

    App-Berechtigungen → App hinzufügen → Ihre App auswählen

    Aktivieren Sie „Finanzdaten, Bestellungen und Antworten auf Kündigungsumfragen ansehen“ sowie „Bestellungen und Abos verwalten“. Lassen Sie alles andere deaktiviert. Wenn Sie dieselben zwei stattdessen unter Kontoberechtigungen aktivieren, gelten sie für alle Ihre Apps.

  3. 3

    Einladung senden

    Übernehmen → Nutzer einladen

    Das Dienstkonto erscheint jetzt unter Nutzer und Berechtigungen als Aktiv.

Warum diese Berechtigungen

Das Gateway liest ein Abo nur über Googles purchases.subscriptionsv2.get. Google verlangt für diesen Lesezugriff die Berechtigungen für Finanzdaten und Bestellungen. Das Gateway bestätigt, erstattet oder storniert nie etwas.

Google kann bis zu einem Tag zur Aktivierung brauchen

Bis dahin antworten Prüfungen mit google_play_permission_denied. Wenn Sie ein beliebiges Abo-Produkt in der Play Console bearbeiten (Beschreibung ändern, speichern, zurückändern), greift die neue Berechtigung oft schneller.

#3. Auf einem API-Schlüssel hinterlegen

  1. 1

    Den Schlüssel Ihrer App öffnen

    Konsole → API-Schlüssel → Bearbeiten

    Verwenden Sie einen eigenen Schlüssel für die App (siehe unten).

  2. 2

    Google-Play-Abo-Prüfung ausfüllen

    Google-Play-Prüfung einrichten

    Geben Sie den Paketnamen genau wie in der build.gradle Ihrer App (applicationId) ein, wählen Sie die JSON-Datei aus Schritt 1 und speichern Sie.

  3. 3

    Meldung nach dem Speichern lesen

    Das Gateway testet die Datei bei Google, bevor es sie speichert. Lehnt Google weiterhin ab, nennt der Dialog, was fehlt — meist die API aus Schritt 1 oder die Berechtigung aus Schritt 2. Die Datei wird verschlüsselt gespeichert und nie wieder angezeigt; laden Sie sie erneut hoch, um sie zu ersetzen.

Einen eigenen Schlüssel für die App verwenden

Google-Play-Einstellungen gehören zu einem Schlüssel. Erstellen Sie einen separaten Schlüssel für die App, beschränken Sie ihn auf die Modelle, die die App nutzt, und geben Sie ihm ein Kontingentlimit.

#4. Aus der App prüfen

Prüfen Sie direkt nach einem Kauf und erneut beim Öffnen der App mit dem gespeicherten Token. Blockieren Sie den App-Start nicht, bis die Antwort da ist: Zeigen Sie das zuletzt gespeicherte Ergebnis und aktualisieren Sie es, wenn die Prüfung zurückkommt. Dasselbe Token wird aus einem Cache mit einer Minute Laufzeit beantwortet. Jeder Schlüssel darf standardmäßig 120-mal pro Minute prüfen; die Google-Play-Einstellungen des Schlüssels zeigen das aktuelle Limit, und der Support kann es für einen Schlüssel anheben. Aufrufe über dem Limit erhalten 429 und werden nicht protokolliert, behalten Sie also die zuletzt gespeicherte Antwort.

google_play.dart
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:in_app_purchase/in_app_purchase.dart';

const apiKey = 'sk-YOUR_KEY';

Future<Map<String, dynamic>?> checkSubscription(String purchaseToken) async {
  final res = await http.post(
    Uri.parse('https://www.aisplice.store/v1/google-play/verify'),
    headers: {
      'Authorization': 'Bearer $apiKey',
      'Content-Type': 'application/json',
      // Request signing on for this key? Then this call must be signed too:
      // ...signedHeaders('POST', '/v1/google-play/verify'),
    },
    body: jsonEncode({'purchase_token': purchaseToken}),
  );
  if (res.statusCode != 200) return null; // keep the last saved answer
  return jsonDecode(res.body) as Map<String, dynamic>;
}

// In your purchaseStream listener:
Future<void> onPurchase(PurchaseDetails purchase) async {
  if (purchase.status != PurchaseStatus.purchased &&
      purchase.status != PurchaseStatus.restored) return;
  final token = purchase.verificationData.serverVerificationData;
  final status = await checkSubscription(token);
  if (status != null && status['active'] == true) {
    await saveEntitlement(token, status); // your local storage
    unlockPaidFeatures();
  }
  if (purchase.pendingCompletePurchase) {
    await InAppPurchase.instance.completePurchase(purchase); // acknowledges on Android
  }
}

#5. Entscheiden, was freigeschaltet wird

PrüfergebnisWas die App tutTypische Ursache
active: true, in_trial: trueFreischalten. „Test endet“ mit expiry_time anzeigen.Testzeitraum
active: trueBis expiry_time freischalten.Bezahlt, auch gekündigte Abos, die noch nicht abgelaufen sind
subscribed: true, active: falseSperren und einen Verlängerungsbildschirm anzeigen.Abgelaufen, pausiert, ausgesetzt
subscribed: falseSperren und den Abo-Bildschirm anzeigen.Unbekanntes Token, ausstehende Zahlung
HTTP 502 / 503Die zuletzt gespeicherte Antwort behalten und später erneut prüfen.Google oder das Dienstkonto antwortet nicht

Speichern Sie expiry_time mit der Antwort. Behandeln Sie das Abo zwischen den Prüfungen bis zu diesem Zeitpunkt als nutzbar, damit ein Handy ohne Verbindung weiter funktioniert.

#6. Jeden Kauf bestätigen

Nicht bestätigte Käufe werden nach 3 Tagen erstattet

Das Gateway liest das Abo nur; es bestätigt es nie. Ihre App muss completePurchase (Flutter) oder acknowledgePurchase (Play Billing) aufrufen. Liefert die Prüfung acknowledged: false für einen Kauf, der älter als ein paar Minuten ist, hat die App das noch nicht getan.

#7. Den Schlüssel in der App schützen

Ein Schlüssel in einer App lässt sich aus mitgeschnittenem Datenverkehr auslesen. Aktivieren Sie für diesen Schlüssel die Anfragesignierung, damit ein kopierter Schlüssel allein nicht nutzbar ist, verschleiern Sie den Build und behalten Sie ein Kontingentlimit für den Schlüssel bei.

Die Signierung gilt für jeden Aufruf mit dem Schlüssel

Sobald die Signierung aktiv ist, braucht /v1/google-play/verify wie jede andere Anfrage mit diesem Schlüssel X-Timestamp, X-Nonce und X-Signature, sonst antwortet es mit 401 signature_required. Signieren Sie mit dem eigenen Pfad: signedHeaders('POST', '/v1/google-play/verify'). Aktivieren Sie die Signierung erst, wenn die signierende App-Version veröffentlicht ist.

Anfragesignierung für Apps →

#8. Nachsehen, was passiert ist

Jede Prüfung, auch zwischengespeicherte Antworten und Fehlschläge, wird unter Konsole → Anfrageprotokoll als kostenlose „Google-Play-Prüfung“ beim Schlüssel aufgeführt. Suchen Sie nach dem vollständigen Kauftoken, seinen letzten Zeichen oder der Bestell-ID (GPA.…), die Ihnen ein Nutzer aus der Beleg-E-Mail von Google schickt.

  • google_play_api_disabled: Die Play API aus Schritt 1 ist im Projekt, zu dem die JSON-Datei gehört, nicht aktiviert.
  • google_play_permission_denied: Die Einladung aus Schritt 2 fehlt, hat nicht die zwei Berechtigungen, gilt für eine andere App oder ist noch nicht aktiv.
  • google_play_credentials_invalid: Der JSON-Schlüssel wurde in Google Cloud gelöscht oder deaktiviert. Erstellen Sie einen neuen Schlüssel und laden Sie ihn beim API-Schlüssel hoch.
  • Beim Speichern heißt es, die Datei sei kein Dienstkontoschlüssel: Sie haben die OAuth-Client-Datei gewählt. Laden Sie stattdessen den Schlüssel über den Tab „Schlüssel“ des Dienstkontos herunter.
  • Jede Prüfung meldet, der Kauf sei nicht gefunden worden: Der Paketname am Schlüssel weicht von der applicationId der App ab, oder das Token stammt aus einer anderen App.
  • Testkäufe von Lizenztestern liefern test_purchase: true.

Alle Felder und Fehlercodes →

Immer noch nicht gelöst?

Senden Sie uns die Anfrage-ID oder die Fehlermeldung, und wir sehen uns das an.