Unterstützen verbrauchsbasierter Add-On-Käufe

In diesem Artikel wird veranschaulicht, wie Methoden der StoreContext-Klasse im Windows.Services.Store Namespace verwendet werden, um die Erfüllung von Konsum-Add-Ons des Benutzers in Ihren UWP-Apps zu verwalten. Verwenden Sie Verbrauchs-Add-Ons für Artikel, die gekauft, verwendet und erneut gekauft werden können. Dies ist besonders nützlich für Dinge wie In-Game-Währung (Gold, Münzen usw.), die gekauft und dann zum Kauf bestimmter Power-Ups verwendet werden können.

Hinweis

Der Windows.Services.Store-Namespace wurde in der Version 1607 von Windows 10 eingeführt und kann ausschließlich in Projekten verwendet werden, die auf Windows 10 Anniversary Edition (Build 14393 der Version 10.0) oder ein späteres Release in Visual Studio ausgelegt ist. Wenn Ihre App auf eine frühere Version von Windows 10 ausgerichtet ist, müssen Sie den Namespace Windows.ApplicationModel.Store anstelle von Windows.Services.Store verwenden. Weitere Informationen finden Sie in diesem Artikel.

Übersicht über Verbrauchs-Add-Ons

Apps können zwei Arten von Konsum-Add-Ons anbieten, die sich in der Art und Weise unterscheiden, wie Erfüllungen verwaltet werden:

  • Vom Entwickler verwalteter Verbrauchsartikel. Für diese Art von Verbrauchsartikel sind Sie dafür verantwortlich, das Guthaben des Benutzers von Elementen, die das Add-On darstellt, nachzuverfolgen und den Kauf des Add-Ons als erfüllt an den Store zu melden, nachdem der Benutzer alle Elemente verbraucht hat. Benutzer*innen können das Add-On erst dann erneut kaufen, wenn die App den vorherigen Add-On-Kauf als erfüllt gemeldet hat.

    Ein Beispiel: Wenn Ihr Add-On 100 Münzen in einem Spiel darstellt und Benutzer*innen zehn Münzen verbrauchen, muss Ihre App oder Ihr Dienst den neuen Saldo von 90 Münzen für die Benutzer*innen speichern. Wenn Benutzer*innen alle 100 Münzen verbraucht haben, muss Ihre App das Add-On als erfüllt melden, und die Benutzer*innen können das Add-On mit den 100 Münzen erneut kaufen.

  • Vom Store verwalteter Verbrauchsartikel. Für diese Art von Verbrauchsartikel verfolgt der Store das Guthaben des Benutzers an Elementen, die das Add-On darstellt. Wenn der Benutzer Elemente nutzt, sind Sie dafür verantwortlich, diese Elemente als erfüllt an den Store zu melden, und der Store aktualisiert das Guthaben des Benutzers. Benutzer*innen können das Add-On beliebig oft kaufen (ohne die Elemente zuvor zu verbrauchen). Ihre App kann den Store jederzeit nach dem aktuellen Saldo für den Benutzer abfragen.

    Wenn das Add-On beispielsweise eine anfängliche Menge von 100 Münzen in einem Spiel darstellt und Benutzer*innen 50 Münzen verbrauchen, meldet die App dem Store, dass 50 Einheiten des Add-Ons erfüllt wurden, und der Store aktualisiert den Restsaldo. Wenn Benutzer*innen Ihr Add-On nun erneut kaufen, um weitere 100 Münzen zu erwerben, verfügen sie über insgesamt 150 Münzen.

    Hinweis

    Vom Store verwaltete Verbrauchsartikel wurden in Windows 10, Version 1607, eingeführt.

Gehen Sie wie folgt vor, um einem Benutzer ein Verbrauchs-Add-On anzubieten:

  1. Ermöglichen Sie Benutzern das Kauf des Add-Ons über Ihre App.
  2. Wenn der Benutzer das Add-On nutzt (z. B. sie ausgeben Münzen in einem Spiel), melden Sie das Add-On als erfüllt.

Sie können jederzeit auch den Restbetrag für einen vom Store verwalteten Verbrauchsartikel erhalten.

Voraussetzungen

Diese Beispiele haben die folgenden Voraussetzungen:

  • Ein Visual Studio-Projekt für eine UWP-App (Universelle Windows-Plattform), die auf Windows 10 Anniversary Edition (Build 14393 der Version 10.0) oder ein späteres Release ausgerichtet ist
  • Erstellen einer App-Übermittlung in Partner Center: Diese App wurde im Store veröffentlicht. Sie können die App optional so konfigurieren, dass sie während der Testphase nicht im Store auffindbar ist. Weitere Informationen finden Sie im Testleitfaden.
  • Sie haben ein Verbrauchs-Add-On für die App im Partner Center erstellt.

Der Code in diesen Beispielen geht davon aus:

  • Der Code wird im Kontext einer Seite ausgeführt, die eine ProgressRing-Klasse mit dem Namen workingProgressRing und eine TextBlock-Klasse mit dem Namen textBlock enthält. Diese Objekte werden verwendet, um anzugeben, dass ein asynchroner Vorgang auftritt, und um die entsprechenden Ausgabemeldungen anzuzeigen.
  • Die Codedatei verfügt über eine using-Anweisung für den Windows.Services.Store-Namespace.
  • Die App ist eine Einzelbenutzer-App, die nur im Kontext des Benutzers ausgeführt wird, der die App gestartet hat. Weitere Informationen finden Sie unter In-App-Käufe und Testversionen.

Eine vollständige Beispielanwendung finden Sie im Store-Beispiel.

Hinweis

Wenn Sie über eine Desktopanwendung verfügen, die die Desktop-Brücke verwendet, müssen Sie möglicherweise zusätzlichen Code hinzufügen, der in diesen Beispielen nicht zum Konfigurieren des StoreContext-Objekts angezeigt wird. Weitere Informationen finden Sie unter Verwenden der StoreContext-Klasse in einer Desktopanwendung, die die Desktop-Brücke verwendet.

Melden eines Verbrauchs-Add-Ons als erfüllt

Nachdem der Benutzer das Add-On von Ihrer App gekauft hat und das Add-On nutzt, muss ihre App das Add-On als erfüllt melden, indem die ReportConsumableFulfillmentAsync-Methode der StoreContext-Klasse aufgerufen wird. Sie müssen die folgenden Informationen an diese Methode übergeben:

  • Die Store-ID des Add-Ons, das Sie als erfüllt melden möchten.
  • Die Einheiten des Add-Ons, das Sie als erfüllt melden möchten.
    • Geben Sie für einen vom Entwickler verwalteten Verbrauchsartikel "1" für den Parameter "Menge " an. Dadurch wird der Store benachrichtigt, dass der Verbrauchsartikel erfüllt wurde, und der Kunde kann dann den Verbrauchsartikel erneut kaufen. Der Benutzer kann den Verbrauchsartikel erst wieder kaufen, nachdem Ihre App den Store benachrichtigt hat, dass er erfüllt wurde.
    • Geben Sie für einen vom Store verwalteten Verbrauchsartikel die tatsächliche Anzahl der verbrauchten Einheiten an. Der Store aktualisiert den Restbetrag für den Verbrauchsartikel.
  • Die Tracking-ID für die Erfüllung. Dies ist eine vom Entwickler bereitgestellte GUID, die die spezifische Transaktion identifiziert, der der Erfüllungsvorgang zu Tracking-Zwecken zugeordnet ist. Weitere Informationen finden Sie in den Hinweisen in ReportConsumableFulfillmentAsync.

In diesem Beispiel wird veranschaulicht, wie ein vom Store verwalteter Verbrauchsartikel als erfüllt angezeigt wird.

private StoreContext context = null;

public async void ConsumeAddOn(string addOnStoreId)
{
    if (context == null)
    {
        context = StoreContext.GetDefault();
        // If your app is a desktop app that uses the Desktop Bridge, you
        // may need additional code to configure the StoreContext object.
        // For more info, see https://aka.ms/storecontext-for-desktop.
    }

    // This is an example for a Store-managed consumable, where you specify the actual number
    // of units that you want to report as consumed so the Store can update the remaining
    // balance. For a developer-managed consumable where you maintain the balance, specify 1
    // to just report the add-on as fulfilled to the Store.
    uint quantity = 10;
    Guid trackingId = Guid.NewGuid();

    workingProgressRing.IsActive = true;
    StoreConsumableResult result = await context.ReportConsumableFulfillmentAsync(
        addOnStoreId, quantity, trackingId);
    workingProgressRing.IsActive = false;

    // Capture the error message for the operation, if any.
    string extendedError = string.Empty;
    if (result.ExtendedError != null)
    {
        extendedError = result.ExtendedError.Message;
    }

    switch (result.Status)
    {
        case StoreConsumableStatus.Succeeded:
            textBlock.Text = "The fulfillment was successful. " + 
                $"Remaining balance: {result.BalanceRemaining}";
            break;

        case StoreConsumableStatus.InsufficentQuantity:
            textBlock.Text = "The fulfillment was unsuccessful because the remaining " +
                $"balance is insufficient. Remaining balance: {result.BalanceRemaining}";
            break;

        case StoreConsumableStatus.NetworkError:
            textBlock.Text = "The fulfillment was unsuccessful due to a network error. " +
                "ExtendedError: " + extendedError;
            break;

        case StoreConsumableStatus.ServerError:
            textBlock.Text = "The fulfillment was unsuccessful due to a server error. " +
                "ExtendedError: " + extendedError;
            break;

        default:
            textBlock.Text = "The fulfillment was unsuccessful due to an unknown error. " +
                "ExtendedError: " + extendedError;
            break;
    }
}

Abrufen des Restguthabens für einen vom Store verwalteten Verbrauchsartikel

In diesem Beispiel wird veranschaulicht, wie Die GetConsumableBalanceRemainingAsync-Methode der StoreContext-Klasse verwendet wird, um den Restsaldo für ein vom Store verwaltetes Verbrauchs-Add-On abzurufen.

private StoreContext context = null;

public async void GetRemainingBalance(string addOnStoreId)
{
    if (context == null)
    {
        context = StoreContext.GetDefault();
        // If your app is a desktop app that uses the Desktop Bridge, you
        // may need additional code to configure the StoreContext object.
        // For more info, see https://aka.ms/storecontext-for-desktop.
    }

    workingProgressRing.IsActive = true;
    StoreConsumableResult result = await context.GetConsumableBalanceRemainingAsync(addOnStoreId);
    workingProgressRing.IsActive = false;

    // Capture the error message for the operation, if any.
    string extendedError = string.Empty;
    if (result.ExtendedError != null)
    {
        extendedError = result.ExtendedError.Message;
    }

    switch (result.Status)
    {
        case StoreConsumableStatus.Succeeded:
            textBlock.Text = "Remaining balance: " + result.BalanceRemaining;
            break;

        case StoreConsumableStatus.NetworkError:
            textBlock.Text = "Could not retrieve balance due to a network error. " +
                "ExtendedError: " + extendedError;
            break;

        case StoreConsumableStatus.ServerError:
            textBlock.Text = "Could not retrieve balance due to a server error. " +
                "ExtendedError: " + extendedError;
            break;

        default:
            textBlock.Text = "Could not retrieve balance due to an unknown error. " +
                "ExtendedError: " + extendedError;
            break;
    }
}