Come gestire un catalogo di prodotti in-app di grandi dimensioni (HTML)

[ Questo articolo è rivolto agli sviluppatori per Windows 8.x e Windows Phone 8.x che realizzano app di Windows Runtime. Gli sviluppatori che usano Windows 10 possono vedere Documentazione aggiornata ]

Con Windows 8.1 e Windows Phone 8.1 viene introdotta una nuova soluzione per le app che offrono cataloghi di prodotti in-app grazie alla quale si supera l'attuale limitazione di 200 articoli prevista dallo Store per ogni account per sviluppatore. Questa soluzione permette di creare poche voci di prodotto per specifiche fasce di prezzo, ognuna in grado di rappresentare centinaia di prodotti in un catalogo.

Per rendere possibile l'uso di tale funzionalità, è stato introdotto un nuovo overload del metodo RequestProductPurchaseAsync per l'acquisto di un'offerta definita dall'app, associata a un prodotto in-app elencato nello Store. Oltre a specificare un'associazione tra offerta e prodotto durante la chiamata, la tua app deve anche passare un oggetto ProductPurchaseDisplayProperties contenente i dettagli dell'offerta del catalogo di grandi dimensioni. Se questi dettagli non vengono forniti, vengono invece usati i dettagli del prodotto elencato.

Lo Store userà solo l'OfferId della richiesta di acquisto nell'elemento PurchaseResults risultante. Questo processo non modifica direttamente le informazioni fornite originariamente quando il prodotto in-app viene presentato nello Store.

Cosa sapere

Tecnologie

Prerequisiti

  • Questo argomento tratta il supporto per la rappresentazione di più prodotti in-app con una singola presentazione di prodotto in-app nello Store. Se non hai familiarità con i prodotti in-app, vedi Abilitare gli acquisti di prodotti in-app per informazioni sulle licenze e su come presentare correttamente il tuo prodotto in-app nello Store.

  • Questo argomento fa inoltre riferimento agli esempi di codice illustrati nell'esempio sulle app di prova e gli acquisti in-app disponibile nella raccolta di codice MSDN. Questo esempio è molto utile per acquisire un'esperienza pratica con le diverse opzioni per realizzare profitti disponibili per le app di Windows Runtime.

  • Quando scrivi il codice ed esegui il testing per nuovi prodotti in-app per la prima volta, devi usare l'oggetto CurrentAppSimulator invece dell'oggetto CurrentApp. In questo modo puoi verificare la logica della licenza usando chiamate simulate al server licenze anziché effettuare chiamate al server reale. A tale scopo, devi personalizzare il file denominato "WindowsStoreProxy.xml" in %userprofile%\AppData\local\packages\<package name>\LocalState\Microsoft\Windows Store\ApiData. Questo file viene creato dal simulatore di Microsoft Visual Studio la prima volta che esegui l'app. In alternativa, puoi caricare un file personalizzato in fase di esecuzione. Per altre informazioni, vedi la documentazione di CurrentAppSimulator.

Effettuare la richiesta di acquisto per il prodotto in-app

La richiesta di acquisto per uno specifico prodotto all'interno di un catalogo di grandi dimensioni viene gestita praticamente come qualsiasi altra richiesta di acquisto all'interno di un'app. Quando l'app chiama il nuovo overload del metodo RequestProductPurchaseAsync, fornisce sia un OfferId che un oggetto ProductPurchaseDisplayProperties in cui è stato inserito il nome del prodotto in-app.

function purchaseAndFulfillOfferAsProduct() {
    var offerId = "1234";
    var displayPropertiesName = "MusicOffer1";
    var displayProperties = new ProductPurchaseDisplayProperties(displayPropertiesName);

    currentApp.requestProductPurchaseAsync("product1", offerId, displayProperties).done(
        function (purchaseResults) {
            if (purchaseResults.status === ProductPurchaseStatus.succeeded) {
                grantFeatureLocally("product1", purchaseResults.transactionId);
                fulfillProduct1("product1", purchaseResults.transactionId, purchaseResults.offerId);
            } else if (purchaseResults.status === ProductPurchaseStatus.notFulfilled) {
                if (isNotLocallyFulfilled("product1", purchaseResults.transactionId)) {
                    grantFeatureLocally("product1", purchaseResults.transactionId);
                }
                fulfillProduct1("product1", purchaseResults.transactionId, purchaseResults.offerId);
            } else if (purchaseResults.status === ProductPurchaseStatus.notPurchased) {
                log("Product 1 was not purchased.", "sample", "status");
            }
        },
        function () {
            log("Unable to buy product 1.", "sample", "error");
        });
}

Segnalare l'evasione del prodotto in-app

Non appena l'offerta viene evasa livello locale, l'app dovrà segnalare questa condizione del prodotto allo Store. Nel caso di un catalogo di grandi dimensioni, se l'app non segnala l'evasione dell'offerta, l'utente non potrà acquistare offerte in-app tramite lo stesso prodotto nello Store.

Come abbiamo spiegato in precedenza, lo Store usa solo le info fornite sull'offerta per inserire i dati in PurchaseResults e non crea un'associazione permanente tra un'offerta di un catalogo di grandi dimensioni e il prodotto nello Store. Devi perciò tenere traccia del fatto che l'utente abbia diritto o meno ai prodotti e garantire all'utente un contesto specifico per il prodotto (ad esempio il nome o i dettagli dell'articolo da acquistare) al di fuori dell'operazione RequestProductPurchaseAsync.

Il codice seguente offre una dimostrazione della chiamata di evasione e di uno schema di messaggi dell'interfaccia utente in cui sono inserite le info specifiche dell'offerta. In assenza di queste info specifiche sul prodotto, nell'esempio vengono usate le info provenienti dall'elemento ListingInformation del prodotto.

function fulfillProduct1(productId, transactionId, offerId) {
    var displayPropertiesName = document.getElementById("displayPropertiesName").value;
    if (displayPropertiesName === "") {
        displayPropertiesName = product1ListingName;
    }
    var offerIdMsg = " with offer id " + offerId;
    if (!offerId) {
        offerIdMsg = " with no offer id";
    }

    currentApp.reportConsumableFulfillmentAsync(productId, transactionId).done(
        function (result) {
            switch (result) {
                case FulfillmentResult.succeeded:
                    log("You bought and fulfilled " + displayPropertiesName  + offerIdMsg, "sample", "status");
                    break;
                case FulfillmentResult.nothingToFulfill:
                    log("There is no purchased product 1 to fulfill.", "sample", "status");
                    break;
                case FulfillmentResult.purchasePending:
                    log("You bought product 1. The purchase is pending so we cannot fulfill the product.", "sample", "status");
                    break;
                case FulfillmentResult.purchaseReverted:
                    log("You bought product 1. But your purchase has been reverted.", "sample", "status");
                    // Since the user's purchase was revoked, they got their money back.
                    // You may want to revoke the user's access to the consumable content that was granted.
                    break;
                case FulfillmentResult.serverError:
                    log("You bought product 1. There was an error when fulfilling.", "sample", "status");
                    break;
            }
        },
        function (error) {
            log("You bought Product 1. There was an error when attempting to fulfill.", "sample", "error");
        });
}

Argomenti correlati

Esempio sulle app di prova e gli acquisti in-app

Abilitare gli acquisti di prodotti in-app

Abilitare gli acquisti di prodotti di consumo in-app

La descrizione della tua app

RequestProductPurchaseAsync

ProductPurchaseDisplayProperties