Umgehen mit API-Kauflogikfehlern für Verbrauchsmaterialien in der Abrechnungs-API v3 von Google Play (relevant für alle, die Verbrauchsmaterialien mit API v3 verwenden)

Mit Version 3 der Abrechnungs-APIGoogle hat die Unterscheidung zwischen Verbrauchsgütern und Nichtverbrauchsgütern aufgehoben.. Beide wurden zu einem neuen Typ namens "verwaltet" kombiniert und verhalten sich wie ein Hybrid: Ihre App muss aktiv eine Methode aufrufen, um die Elemente "zu konsumieren". Wenn dies für einen Satz Skus niemals durchgeführt wird, verhalten sich diese Gegenstände grundsätzlich so, als wären sie nicht verbrauchbar.

DasDokumentatio beschreibt den beabsichtigten Einkaufsfluss wie folgt:

Starten Sie einen Kaufvorgang mit einemgetBuyIntent AnrufHol dir eine AntwortBundle von Google Play zeigt an, ob der Kauf erfolgreich abgeschlossen wurde.Wenn der Kauf erfolgreich war, verbrauchen Sie den Kauf, indem Sie ein @ eingebeconsumePurchase AnrufHolen Sie sich einen Antwortcode von Google Play, der angibt, ob der Verbrauch erfolgreich abgeschlossen wurde.Wenn der Verbrauch erfolgreich war, stellen Sie das Produkt in Ihrer Anwendung bereit.

Ich sehe zwei Probleme mit diesem Ansatz. Einer ist ziemlich offensichtlich und eher ein "Fehler" in der Dokumentation als in der API, der andere ist jedoch eher subtil und ich habe immer noch nicht herausgefunden, wie ich am besten damit umgehen soll. Beginnen wir der Vollständigkeit halber mit dem Offensichtlichen:

Problem 1: Verlorene Einkäufe auf einem Gerät:

Die Dokumentation sagt, dass eine App @ aufrufen sogetPurchases Jedes Mal, wenn es gestartet wird, um zu überprüfen, ob der Benutzer über ausstehende In-App-Verbrauchsartikel verfügt. In diesem Fall sollte die App diese konsumieren und das zugehörige Objekt bereitstellen. Dies gilt für den Fall, dass der Kaufvorgang unterbrochen wird, nachdem der Kauf abgeschlossen wurde, aber bevor der Artikel verbraucht ist (d. H. Um Schritt 2 herum

Aber was ist, wenn der Kaufvorgang zwischen Schritt 4 und 5 unterbrochen wird? Das heißt Die App hat den Kauf erfolgreich verbraucht, wurde jedoch beendet (Telefonanruf eingegangen und nicht genügend Speicher vorhanden, Akku leer, Absturz, was auch immer), bevor das Produkt dem Benutzer zur Verfügung gestellt werden konnte. In diesem Fall ist der Kauf nicht mehr in @ enthaltegetPurchases und im Grunde erhält der Benutzer nie das, wofür er bezahlt hat (Geben Sie hier eine wütende Support-E-Mail und eine Bewertung mit einem Stern ein.) ...

Glücklicherweise lässt sich dieses Problem durch die Einführung eines "Journals" wie in einem Dateisystem), um den Kaufvorgang in etwas Ähnliches zu ändern (Schritte 1 und 2 wie oben):

Wenn der Kauf erfolgreich war, tragen Sie in das Journal ein: "Erhöhen Sie die Münzen von 300 auf 400 nach dem Kauf. <Bestell-ID hier> wird erfolgreich verbraucht. "

Nachdem der Journaleintrag bestätigt wurde, verbrauchen Sie den Kauf, indem Sie ein @ eingebeconsumePurchase Anruf

Holen Sie sich einen Antwortcode von Google Play, der angibt, ob der Verbrauch erfolgreich abgeschlossen wurde.Wenn der Verbrauch erfolgreich war, stellen Sie das Produkt in Ihrer Anwendung bereit.Wenn die Bereitstellung bestätigt wurde, ändern Sie den Journaleintrag in "purchase @" <Bestell-ID hier> abgeschlossen"

Then, jedes Mal, wenn die App startet, sollte es nicht nur @ überprüfgetPurchases, aber auch das Tagebuch. Wenn es dort einen Eintrag für einen unvollständigen Kauf gibt, der nicht von @ gemeldet wurgetPurchases, fahren Sie mit Schritt 6 fort. Wenn ein späteresgetPurchase sollte diese Bestell-ID jemals wieder als Eigentum zurückgeben (z. B. wenn der Verbrauch doch fehlgeschlagen ist), ignorieren Sie einfach die Transaktion, wenn das Journal diese Bestell-ID als vollständig aufführt.

Diessollt Problem 1 beheben, aber bitte lassen Sie mich wissen, wenn Sie Fehler in diesem Ansatz finden.

Problem 2: Probleme, wenn mehrere Geräte beteiligt sind:

Nehmen wir an, ein Benutzer besitzt zwei Geräte (z. B. ein Telefon und ein Tablet) mit demselben Konto auf beiden.

Er (oder sie - um von nun an angedeutet zu werden) könnte versuchen, mehr Münzen auf seinem @ zu kaufTelefo und die App könnte nach dem Kauf getötet werden, aber bevor sie verbraucht wird. Nun, wenn er die App auf seinem @ öffnTablett Nächster,getPurchases meldet das Produkt als Eigentum.

Die App auf dem Tabl muss davon ausgehen, dass der Kauf dort initiiert wurde und dass sie vor dem Erstellen des Journaleintrags gestorben ist, sodass der Journaleintrag erstellt, das Produkt konsumiert und die Münzen bereitgestellt werden.

Wenn die Telefon-App gestorben ist, bevor der Journaleintrag möglich war, werden die Münzen niemals auf dem Telefon bereitgestellt (Geben Sie hier eine wütende Support-E-Mail und eine Bewertung mit einem Stern ein.). Und wenn die Telefon-App nach dem Erstellen des Journaleintrags nicht mehr funktioniert, werden die Münzenebenfall am Telefon bereitgestellt werden und dem Benutzer im Grunde einen kostenlosen Kauf auf dem Tablet ermöglichen (verlorene Einnahmen hier einfügen).

Dazu müssen Sie dem Kauf eine eindeutige Installations- oder Geräte-ID als Nutzlast hinzufügen, um zu überprüfen, ob der Kauf für dieses Gerät bestimmt war. Dann kann das Tablet den Kauf einfach ignorieren und nur das Telefon wird die Münzen jemals gutschreiben und den Gegenstand verbrauchen.

ABER Da sich die SKU zu diesem Zeitpunkt noch im Besitz des Benutzers befindet, kann der Benutzer im Play Store keine weitere Kopie kaufen. Im Grunde genommen ist dies so lange nicht möglich, bis der Benutzer die App erneut auf seinem Telefon startet, um die ausstehende Transaktion abzuschließen in der Lage, mehr virtuelle Münzen auf dem Tablet zu kaufen (Geben Sie hier eine verärgerte Support-E-Mail, eine Bewertung mit einem Stern und verlorene Einnahmen ein.).

ibt es eine elegante Möglichkeit, mit diesem Szenario umzugehen? Die einzigen Lösungen, die ich mir vorstellen kann, sind:

Schicken Sie dem Benutzer eine Nachricht, um die App zuerst auf dem anderen Gerät zu starten (yuck!)oder füge mehrere Skus für den gleichen Verbrauchsartikel hinzu (sollte funktionieren, aber trotzdem igitt!)

ibt es einen besseren Weg? Oder verstehe ich etwas nur grundlegend und es gibt hier wirklich kein Problem? (Mir ist klar, dass die Chancen, dass dieses Problem jemals auftritt, gering sind, aber mit einer ausreichend großen Benutzerbasis wird "unwahrscheinlich" letztendlich zu "ständig".)

Antworten auf die Frage(4)

Ihre Antwort auf die Frage