Abilitare gli acquisti di beni consumabili in-app

Offrire prodotti in-app di consumo (elementi che possono essere acquistati, usati e acquistati di nuovo) attraverso la piattaforma di commercio dello Store per fornire ai clienti un'esperienza di acquisto efficace e affidabile. Questo è particolarmente utile per elementi quali il denaro usato nel gioco (oro, monete e così via) che possono essere acquistati e poi usati per acquistare potenziamenti specifici.

Importante

Questo articolo illustra come usare i membri dello spazio dei nomi Windows.ApplicationModel.Store per abilitare gli acquisti di prodotti in-app di consumo. Questo spazio dei nomi non viene più aggiornato con nuove funzionalità ed è consigliabile usare invece lo spazio dei nomi Windows.Services.Store. Lo spazio dei nomi Windows.Services.Store supporta i tipi di componenti aggiuntivi più recenti, quali i componenti aggiuntivi di consumo gestiti dallo Store e le sottoscrizioni, ed è progettato per essere compatibile con tipi futuri di prodotti e funzionalità supportati dal Centro per i partner e dallo Store. Lo spazio dei nomi Windows.Services.Store è stato introdotto in Windows 10, versione 1607, e può essere usato solo nei progetti destinati a Windows 10 Anniversary Edition (10.0; Build 14393) o versione successiva in Visual Studio. Per ulteriori informazioni sull'abilitazione degli acquisti di prodotti in-app di consumo usando lo spazio dei nomi Windows.Services.Store, vedere questo articolo.

Prerequisiti

  • Questo argomento illustra la segnalazione degli acquisti e dell'evasione di prodotti in-app di consumo. Se non si ha familiarità con i prodotti in-app, vedere Abilitare gli acquisiti di prodotti in-app per informazioni sulle licenze e su come elencare correttamente i prodotti in-app nello Store.
  • La prima volta che si scrive il codice di nuovi prodotti in-app e li si testano, è necessario usare l'oggetto CurrentAppSimulator anziché l'oggetto CurrentApp. In questo modo è possibile verificare la logica di licenza usando chiamate simulate al server licenze anziché chiamare il server live. A tale scopo, è necessario personalizzare il file denominato WindowsStoreProxy.xml in %userprofile%\AppData\local\packages\<nome pacchetto>\LocalState\Microsoft\Windows Store\ApiData. Il simulatore di Microsoft Visual Studio crea questo file la prima volta che si esegue l'app, in alternativa è possibile caricarne uno personalizzato in fase di runtime. Per ulteriori informazioni, vedere Uso del file WindowsStoreProxy.xml con CurrentAppSimulator.
  • Questo argomento fa riferimento anche agli esempi di codice forniti nell'esempio di Store. Questo esempio è un ottimo modo per acquisire esperienza pratica con le diverse opzioni di monetizzazione fornite per le app UWP (Universal Windows Platform).

Passaggio 1: effettuare la richiesta di acquisto

La richiesta di acquisto iniziale si effettua con RequestProductPurchaseAsync come qualsiasi altro acquisto eseguito tramite lo Store. La differenza per i prodotti in-app di consumo è che dopo un acquisto effettuato, un cliente non può acquistare di nuovo lo stesso prodotto fino a quando l'app non comunica allo Store che l'acquisto precedente è stato evaso. Spetta all'app evadere i prodotti di consumo acquistati e comunicare l'evasione allo Store.

L'esempio seguente mostra una richiesta di acquisto di prodotti in-app di consumo. Sono presenti commenti del codice che indicano quando l'app deve eseguire l'evasione locale del prodotto in-app di consumo per due diversi scenari: quando la richiesta ha esito positivo e quando la richiesta ha esito negativo a causa di un acquisto non evaso dello stesso prodotto.

PurchaseResults purchaseResults = await CurrentAppSimulator.RequestProductPurchaseAsync("product1");
switch (purchaseResults.Status)
{
    case ProductPurchaseStatus.Succeeded:
        product1TempTransactionId = purchaseResults.TransactionId;

        // Grant the user their purchase here, and then pass the product ID and transaction ID to
        // CurrentAppSimulator.ReportConsumableFulfillment to indicate local fulfillment to the
        // Windows Store.
        break;

    case ProductPurchaseStatus.NotFulfilled:
        product1TempTransactionId = purchaseResults.TransactionId;

        // First check for unfulfilled purchases and grant any unfulfilled purchases from an
        // earlier transaction. Once products are fulfilled pass the product ID and transaction ID
        // to CurrentAppSimulator.ReportConsumableFulfillment to indicate local fulfillment to the
        // Windows Store.
        break;
}

Passaggio 2: tenere traccia dell'evasione locale del prodotto di consumo

Quando si concede al cliente l'accesso al prodotto in-app di consumo, è importante tenere traccia del prodotto evaso (productId) e della transazione a cui l'evasione è associata (transactionId).

Importante

L'app è responsabile di segnalare accuratamente l'evasione allo Store. Questo passaggio è essenziale per offrire un'esperienza di acquisto equa e affidabile ai clienti.

L'esempio seguente mostra l'uso delle proprietà PurchaseResults della chiamata RequestProductPurchaseAsync nel passaggio precedente per identificare il prodotto acquistato per l'evasione. Si usa una raccolta per archiviare le informazioni sul prodotto in una posizione a cui sia possibile fare riferimento in seguito per verificare che l'evasione locale ha avuto esito positivo.

private void GrantFeatureLocally(string productId, Guid transactionId)
{
    if (!grantedConsumableTransactionIds.ContainsKey(productId))
    {
        grantedConsumableTransactionIds.Add(productId, new List<Guid>());
    }
    grantedConsumableTransactionIds[productId].Add(transactionId);

    // Grant the user their content. You will likely increase some kind of gold/coins/some other asset count.
}

Questo esempio mostra come usare la matrice dell'esempio precedente per accedere alle coppie ID prodotto/ID transazione usate successivamente per segnalare l'evasione allo Store.

Importante

Indipendentemente dalla metodologia usata dall'app per tenere traccia dell'evasione e confermarla, l'app deve dimostrare la due diligence per assicurarsi che ai clienti non vengano addebitati prodotti che non hanno ricevuto.

private Boolean IsLocallyFulfilled(string productId, Guid transactionId)
{
    return grantedConsumableTransactionIds.ContainsKey(productId) &&
        grantedConsumableTransactionIds[productId].Contains(transactionId);
}

Passaggio 3: segnalare l'evasione dei prodotti allo Store

Dopo il completamento dell'evasione locale, l'app deve eseguire una chiamata ReportConsumableFulfillmentAsync che include productId e la transazione in cui è incluso l'acquisto del prodotto.

Importante

La mancata segnalazione allo Store dei prodotti in-app di consumo evasi fa sì che l'utente non possa acquistare nuovamente il prodotto finché non viene segnalata l'evasione per l'acquisto precedente.

FulfillmentResult result = await CurrentAppSimulator.ReportConsumableFulfillmentAsync(
    "product2", product2TempTransactionId);

Passaggio 4: identificare gli acquisti non evasi

L'app può usare il metodo GetUnfulfilledConsumablesAsync per controllare la presenza di prodotti in-app di consumo non evasi in qualsiasi momento. Questo metodo deve essere chiamato regolarmente per verificare la presenza di prodotti di consumo non evasi dovuti a eventi imprevisti dell'app, quali un'interruzione della connettività di rete o la chiusura dell'app.

L'esempio seguente mostra come è possibile usare GetUnfulfilledConsumablesAsync per enumerare i prodotti di consumo non evasi e come l'app può scorrere questo elenco per completare l'evasione locale.

private async void GetUnfulfilledConsumables()
{
    products = await CurrentApp.GetUnfulfilledConsumablesAsync();

    foreach (UnfulfilledConsumable product in products)
    {
        logMessage += "\nProduct Id: " + product.ProductId + " Transaction Id: " + product.TransactionId;
        // This is where you would pass the product ID and transaction ID to
        // currentAppSimulator.reportConsumableFulfillment to indicate local fulfillment to the Windows Store.
    }
}