Analizzare gli abbandoni degli acquisti di prodotti in Fatturazione Play

1. Introduzione

In questo codelab ti concentrerai sulla creazione di un prodotto a pagamento singolo, sull'integrazione della tua app con la libreria Fatturazione Play (PBL) e sull'analisi dei motivi dell'abbandono degli acquisti.

Pubblico

Questo codelab è rivolto agli sviluppatori di app per Android che utilizzano la Libreria Fatturazione Play o che vogliono utilizzarla per monetizzare i propri prodotti una tantum.

Cosa imparerai…

  • Come creare prodotti a pagamento singolo in Google Play Console.
  • Come integrare la tua app con l'apprendimento basato su progetti.
  • Come elaborare gli acquisti di prodotti a pagamento singolo di consumo e non di consumo nella Libreria Fatturazione Play.
  • Come analizzare gli abbandoni degli acquisti.

Cosa ti serve…

2. Crea l'app di esempio

L'app di esempio è progettata per essere un'app per Android completamente funzionante con il codice sorgente completo che mostra i seguenti aspetti:

  • Integrazione dell'app con PBL
  • Recupera i prodotti a pagamento singolo
  • Avviare i flussi di acquisto per i prodotti a pagamento singolo
  • Scenari di acquisto che portano alle seguenti risposte di fatturazione:
    • BILLING_UNAVAILABLE
    • USER_CANCELLED
    • OK
    • ITEM_ALREADY_OWNED

Il seguente video dimostrativo mostra l'aspetto e il comportamento dell'app di esempio dopo il deployment e l'esecuzione.

Prerequisiti

Prima di creare ed eseguire il deployment dell'app di esempio:

Build

L'obiettivo di questo passaggio di compilazione è generare un file Android App Bundle firmato dell'app di esempio.

Per generare l'Android App Bundle, svolgi i seguenti passaggi:

  1. Scarica l'app di esempio da GitHub.
  2. Crea l'app di esempio. Prima di creare, modifica il nome del pacchetto dell'app di esempio e poi crea. Se hai pacchetti di altre app in Play Console, assicurati che il nome del pacchetto che fornisci per l'app di esempio sia univoco.

    Nota: la creazione dell'app di esempio genera solo un file APK che puoi utilizzare per i test locali. Tuttavia, l'esecuzione dell'app non recupera prodotti e prezzi perché i prodotti non sono stati configurati in Play Console, cosa che farai più avanti in questo codelab.
  3. Genera un Android App Bundle firmato.
    1. Generare una chiave di caricamento e un archivio chiavi
    2. Firmare l'app con la chiave di caricamento
    3. Configurare la firma dell'app di Google Play

Il passaggio successivo consiste nel caricare l'app bundle Android su Google Play Console.

3. Creare un prodotto a pagamento singolo in Play Console

Per creare prodotti una tantum in Google Play Console, devi avere un'app in Play Console. Crea un'app in Play Console, poi carica l'app bundle firmato creato in precedenza.

Crea un'app

Per creare un'app:

  1. Accedi a Google Play Console utilizzando il tuo account sviluppatore.
  2. Fai clic su Crea app. Si aprirà la pagina Crea app.
  3. Inserisci un nome dell'app, seleziona la lingua predefinita e altri dettagli relativi all'app.
  4. Fai clic su Crea app. In questo modo viene creata un'app in Google Play Console.

Ora puoi caricare l'app bundle firmato dell'app di esempio.

Carica l'app bundle firmato

  1. Carica l'app bundle firmato nel canale di test interno di Google Play Console. Solo dopo il caricamento puoi configurare le funzionalità relative alla monetizzazione in Play Console.
  2. Fai clic su Testa e rilascia > Test > Release interna > Crea nuova release.
  3. Inserisci un nome per la release e carica il file del pacchetto dell'app firmato.
  4. Fai clic su Avanti e poi su Salva e pubblica.

Ora puoi creare i tuoi prodotti a pagamento singolo.

Creare un prodotto a pagamento singolo

Per creare un prodotto a pagamento singolo:

  1. Nella console Google Play, dal menu di navigazione a sinistra, vai a Monetizza con Google Play > Prodotti > Prodotti a pagamento singolo.
  2. Fai clic su Crea prodotto a pagamento singolo.
  3. Inserisci i seguenti dettagli del prodotto:
    • ID prodotto:inserisci un ID prodotto univoco. Inserisci one_time_product_01.
    • (Facoltativo) Tag: aggiungi tag pertinenti.
    • Nome:inserisci un nome del prodotto. Ad esempio, Product name.
    • Descrizione:inserisci una descrizione del prodotto. Ad esempio, Product description.
    • (Facoltativo) Aggiungi un'immagine dell'icona:carica un'icona che rappresenti il tuo prodotto.
    Nota: ai fini di questo codelab, puoi saltare la configurazione della sezione Imposte, conformità e programmi.
  4. Fai clic su Avanti.
  5. Aggiungi un'opzione di acquisto e configura la sua disponibilità a livello regionale. Un prodotto a pagamento singolo richiede almeno un'opzione di acquisto, che definisce in che modo viene concesso il diritto, il relativo prezzo e la disponibilità a livello regionale. Per questo codelab, aggiungeremo l'opzione standard Acquista per il prodotto.Nella sezione Opzione di acquisto, inserisci i seguenti dettagli:
    • ID opzione di acquisto:inserisci un ID opzione di acquisto. Ad esempio, buy.
    • Tipo di acquisto:seleziona Acquista.
    • (Facoltativo) Tag: aggiungi tag specifici per questa opzione di acquisto.
    • (Facoltativo) Fai clic su Opzioni avanzate per configurare le opzioni avanzate. Ai fini di questo codelab, puoi saltare la configurazione delle opzioni avanzate.
  6. Nella sezione Disponibilità e prezzi, fai clic su Imposta prezzi > Modifica collettivamente i prezzi.
  7. Seleziona l'opzione Paese / regione. In questo modo vengono selezionate tutte le regioni.
  8. Fai clic su Continua. Si apre una finestra di dialogo per inserire un prezzo. Inserisci 10 € e poi fai clic su Applica.
  9. Fai clic su Salva e poi su Attiva. In questo modo l'opzione di acquisto viene creata e attivata.

Ai fini di questo codelab, crea altri tre prodotti a pagamento singolo con i seguenti ID prodotto:

  • consumable_product_01
  • consumable_product_02
  • consumable_product_03

L'app di esempio è configurata per utilizzare questi ID prodotto. Puoi fornire ID prodotto diversi, nel qual caso dovrai modificare l'app di esempio per utilizzare l'ID prodotto che hai fornito.

Apri l'app di esempio in Google Play Console e vai a Monetizza con Google Play > Prodotti > Prodotti a pagamento singolo. Poi fai clic su Crea prodotto a pagamento singolo e ripeti i passaggi da 3 a 9.

Video sulla creazione di prodotti a pagamento singolo

Il seguente video di esempio mostra i passaggi per la creazione una tantum del prodotto descritti in precedenza.

4. Integrazione con PBL

Ora vedremo come integrare la tua app con la Libreria Fatturazione Play (PBL). Questa sezione descrive i passaggi generali per l'integrazione e fornisce uno snippet di codice per ciascun passaggio. Puoi utilizzare questi snippet come guida per implementare l'integrazione effettiva.

Per integrare la tua app con PBL, segui questi passaggi:

  1. Aggiungi la dipendenza della libreria Fatturazione Play all'app di esempio.
    dependencies {
    val billing_version = "8.0.0"
    
    implementation("com.android.billingclient:billing-ktx:$billing_version")
    }
    
  2. Inizializza BillingClient. BillingClient è l'SDK client che risiede nella tua app e comunica con la Libreria Fatturazione Play. Il seguente snippet di codice mostra come inizializzare il client di fatturazione.
    protected BillingClient createBillingClient() {
    return BillingClient.newBuilder(activity)
        .setListener(purchasesUpdatedListener)
        .enablePendingPurchases(PendingPurchasesParams.newBuilder().enableOneTimeProducts().build())
        .enableAutoServiceReconnection()
        .build();
    }
    
  3. Connettiti a Google Play.Il seguente snippet di codice mostra come connettersi a Google Play.
    public void startBillingConnection(ImmutableList<Product> productList) {
    Log.i(TAG, "Product list sent: " + productList);
    Log.i(TAG, "Starting connection");
    billingClient.startConnection(
        new BillingClientStateListener() {
          @Override
          public void onBillingSetupFinished(BillingResult billingResult) {
            if (billingResult.getResponseCode() == BillingResponseCode.OK) {
              // Query product details to get the product details list.
              queryProductDetails(productList);
            } else {
              // BillingClient.enableAutoServiceReconnection() will retry the connection on
              // transient errors automatically.
              // We don't need to retry on terminal errors (e.g., BILLING_UNAVAILABLE,
              // DEVELOPER_ERROR).
              Log.e(TAG, "Billing connection failed: " + billingResult.getDebugMessage());
              Log.e(TAG, "Billing response code: " + billingResult.getResponseCode());
            }
          }
    
          @Override
          public void onBillingServiceDisconnected() {
            Log.e(TAG, "Billing Service connection lost.");
          }
        });
    }
    
  4. Recupera i dettagli del prodotto a pagamento singolo.Dopo aver integrato l'app con PBL, devi recuperare i dettagli del prodotto a pagamento singolo nella tua app. Lo snippet di codice seguente mostra come recuperare i dettagli del prodotto a pagamento singolo nella tua app.
    private void queryProductDetails(ImmutableList<Product> productList) {
    Log.i(TAG, "Querying products for: " + productList);
    QueryProductDetailsParams queryProductDetailsParams =
        QueryProductDetailsParams.newBuilder().setProductList(productList).build();
    billingClient.queryProductDetailsAsync(
        queryProductDetailsParams,
        new ProductDetailsResponseListener() {
          @Override
          public void onProductDetailsResponse(
              BillingResult billingResult, QueryProductDetailsResult productDetailsResponse) {
            // check billingResult
            Log.i(TAG, "Billing result after querying: " + billingResult.getResponseCode());
            // process returned productDetailsList
            Log.i(
                TAG,
                "Print unfetched products: " + productDetailsResponse.getUnfetchedProductList());
            setupProductDetailsMap(productDetailsResponse.getProductDetailsList());
            billingServiceClientListener.onProductDetailsFetched(productDetailsMap);
          }
        });
    }
    
    Il recupero di ProductDetails restituisce una risposta simile alla seguente:
    {
        "productId": "consumable_product_01",
        "type": "inapp",
        "title": "Shadow Coat (Yolo's Realm | Play Samples)",
        "name": "Shadow Coat",
        "description": "A sleek, obsidian coat for stealth and ambushes",
        "skuDetailsToken": "<---skuDetailsToken--->",
        "oneTimePurchaseOfferDetails": {},
        "oneTimePurchaseOfferDetailsList": [
            {
                "priceAmountMicros": 1990000,
                "priceCurrencyCode": "USD",
                "formattedPrice": "$1.99",
                "offerIdToken": "<--offerIdToken-->",
                "purchaseOptionId": "buy",
                "offerTags": []
            }
        ]
    },
    {
        "productId": "consumable_product_02",
        "type": "inapp",
        "title": "Emperor Den (Yolo's Realm | Play Samples)",
        "name": "Emperor Den",
        "description": "A fair lair glowing with molten rock and embers",
        "skuDetailsToken": "<---skuDetailsToken--->",
        "oneTimePurchaseOfferDetails": {},
        "oneTimePurchaseOfferDetailsList": [
            {
                "priceAmountMicros": 2990000,
                "priceCurrencyCode": "USD",
                "formattedPrice": "$2.99",
                "offerIdToken": "<--offerIdToken-->",
                "purchaseOptionId": "buy",
                "offerTags": []
            }
        ]
    }
    
  5. Avvia il flusso di fatturazione.
    public void launchBillingFlow(String productId) {
    ProductDetails productDetails = productDetailsMap.get(productId);
    if (productDetails == null) {
      Log.e(
          TAG, "Cannot launch billing flow: ProductDetails not found for productId: " + productId);
      billingServiceClientListener.onBillingResponse(
          BillingResponseCode.ITEM_UNAVAILABLE,
          BillingResult.newBuilder().setResponseCode(BillingResponseCode.ITEM_UNAVAILABLE).build());
      return;
    }
    ImmutableList<ProductDetailsParams> productDetailsParamsList =
        ImmutableList.of(
            ProductDetailsParams.newBuilder().setProductDetails(productDetails).build());
    
    BillingFlowParams billingFlowParams =
        BillingFlowParams.newBuilder()
            .setProductDetailsParamsList(productDetailsParamsList)
            .build();
    
    billingClient.launchBillingFlow(activity, billingFlowParams);
    }
    
  6. Rilevare ed elaborare gli acquisti. Nell'ambito di questo passaggio, devi:
    1. Verificare l'acquisto
    2. Concedere il diritto all'utente
    3. Notificare all'utente
    4. Notificare a Google la procedura di acquisto
    Di questi, i passaggi a, b e c devono essere eseguiti nel backend e pertanto non rientrano nell'ambito di questo codelab.Il seguente snippet mostra come notificare a Google un prodotto monouso consumabile:
    private void handlePurchase(Purchase purchase) {
    // Step 1: Send the purchase to your secure backend to verify the purchase following
    // https://developer.android.com/google/play/billing/security#verify
    
    // Step 2: Update your entitlement storage with the purchase. If purchase is
    // in PENDING state then ensure the entitlement is marked as pending and the
    // user does not receive benefits yet. It is recommended that this step is
    // done on your secure backend and can combine in the API call to your
    // backend in step 1.
    
    // Step 3: Notify the user using appropriate messaging.
    if (purchase.getPurchaseState() == PurchaseState.PURCHASED) {
      for (String product : purchase.getProducts()) {
        Log.d(TAG, product + " purchased successfully! ");
      }
    }
    
    // Step 4: Notify Google the purchase was processed.
    // For one-time products, acknowledge the purchase.
    // This sample app (client-only) uses billingClient.acknowledgePurchase().
    // For consumable one-time products, consume the purchase
    // This sample app (client-only) uses billingClient.consumeAsync()
    // If you have a secure backend, you must acknowledge purchases on your server using the
    // server-side API.
    // See https://developer.android.com/google/play/billing/security#acknowledge
    if (purchase.getPurchaseState() == PurchaseState.PURCHASED && !purchase.isAcknowledged()) {
    
      if (shouldConsume(purchase)) {
        ConsumeParams consumeParams =
            ConsumeParams.newBuilder().setPurchaseToken(purchase.getPurchaseToken()).build();
        billingClient.consumeAsync(consumeParams, consumeResponseListener);
    
      } else {
        AcknowledgePurchaseParams acknowledgePurchaseParams =
            AcknowledgePurchaseParams.newBuilder()
                .setPurchaseToken(purchase.getPurchaseToken())
                .build();
        billingClient.acknowledgePurchase(
            acknowledgePurchaseParams, acknowledgePurchaseResponseListener);
      }
     }
    }
    

5. Analizzare gli abbandoni degli acquisti

Finora nel codelab, le risposte di Fatturazione Play si sono concentrate su scenari limitati come USER_CANCELLED, BILLING_UNAVAILABLE, OK e ITEM_ALREADY_OWNED. Tuttavia, Play Billing può restituire 13 diversi codici di risposta che possono essere attivati da vari fattori reali.

Questa sezione illustra in dettaglio le cause delle risposte di errore USER_CANCELLED e BILLING_UNAVAILABLE e suggerisce possibili azioni correttive che puoi implementare.

Codice di errore di risposta USER_CANCELED

Questo codice di risposta indica che l'utente ha abbandonato l'interfaccia utente del flusso di acquisto prima di completare l'acquisto.

Cause probabili

Quali azioni puoi intraprendere?

  • Potrebbe indicare utenti con bassa intenzione che sono sensibili ai prezzi.
  • L'acquisto è in attesa o il pagamento è stato rifiutato.

Codice di errore di risposta BILLING_UNAVAILABLE

Questo codice di risposta indica che l'acquisto non è stato completato a causa di un problema con il fornitore di servizi di pagamento dell'utente o con la forma di pagamento scelta. Ad esempio, la carta di credito dell'utente è scaduta o l'utente si trova in un paese non supportato. Questo codice non indica un errore nel sistema di fatturazione di Google Play.

Cause probabili

Quali azioni puoi intraprendere?

  • L'app Play Store sul dispositivo dell'utente non è aggiornata.
  • L'utente si trova in un paese in cui Google Play non è supportato.
  • L'utente è un utente aziendale e il suo amministratore aziendale ha disattivato gli acquisti per gli utenti.
  • Google Play non è in grado di addebitare l'importo sul metodo di pagamento dell'utente. Ad esempio, la carta di credito dell'utente potrebbe essere scaduta.
  • Monitorare le tendenze relative ai problemi di sistema e in regioni specifiche
  • Valuta la possibilità di eseguire la migrazione a PBL 8, in quanto supporta il codice di risposta secondario PAYMENT_DECLINED_DUE_TO_INSUFFICIENT_FUNDS più granulare. Se ricevi questo codice di risposta, valuta la possibilità di comunicare agli utenti l'errore o suggerisci metodi di pagamento alternativi.
  • Questo codice di risposta è progettato per i nuovi tentativi, consentendoti di implementare strategie di ripetizione adeguate.
    È improbabile che i tentativi automatici aiutino in questo caso. Tuttavia, un nuovo tentativo manuale può essere utile se l'utente risolve la condizione che ha causato il problema. Ad esempio, se l'utente aggiorna la versione del Play Store a una versione supportata, un nuovo tentativo manuale dell'operazione iniziale potrebbe funzionare.

    Se ricevi questo codice di risposta quando l'utente non è in sessione, il nuovo tentativo potrebbe non avere senso. Quando ricevi una risposta `BILLING_UNAVAILABLE` a seguito del flusso di acquisto, è molto probabile che l'utente abbia ricevuto un feedback da Google Play durante la procedura di acquisto e potrebbe essere consapevole di cosa è andato storto. In questo caso, potresti mostrare un messaggio di errore che specifica che si è verificato un problema e offrire un pulsante "Riprova" per dare all'utente la possibilità di riprovare manualmente dopo aver risolto il problema.

Strategie di ripetizione per i codici di errore di risposta

Le strategie di ripetizione efficaci per gli errori recuperabili della libreria Play Billing (PBL) variano in base al contesto, ad esempio le interazioni degli utenti in sessione (come durante un acquisto) rispetto alle operazioni in background (come l'interrogazione degli acquisti alla ripresa dell'app). È importante implementare queste strategie perché alcuni valori di BillingResponseCode indicano problemi temporanei che possono essere risolti riprovando, mentre altri sono permanenti e non richiedono tentativi.

Per gli errori riscontrati quando l'utente è in sessione, è consigliabile una semplice strategia di nuovi tentativi con un numero massimo di tentativi impostato per ridurre al minimo l'interruzione dell'esperienza utente. Al contrario, per le operazioni in background, come il riconoscimento di nuovi acquisti, che non richiedono l'esecuzione immediata, l'exponential backoff è l'approccio consigliato.

Per informazioni dettagliate su codici di risposta specifici e sulle strategie di ripetizione corrispondenti consigliate, consulta Gestire i codici di risposta BillingResult.

6. Passaggi successivi

Documenti di riferimento

7. Complimenti!

Complimenti! Hai navigato correttamente in Google Play Console per creare un nuovo prodotto una tantum, testare i codici di risposta alla fatturazione e analizzare gli abbandoni degli acquisti.

Sondaggio

Il tuo feedback su questo codelab è molto importante. Ti invitiamo a dedicare qualche minuto per completare il nostro sondaggio.