Integra la Libreria Fatturazione Google Play nella tua app

Questo argomento descrive come integrare Libreria Fatturazione Google Play in la tua app per iniziare a vendere prodotti.

La vita di un acquisto

Di seguito è riportato un tipico flusso di acquisto per un acquisto una tantum o per un abbonamento.

  1. Mostrare all'utente cosa può acquistare.
  2. Lancia il flusso di acquisto per fare in modo che l'utente accetti l'acquisto.
  3. Verifica l'acquisto sul tuo server.
  4. Fornisci contenuti all'utente.
  5. Conferma il caricamento dei contenuti. Per i prodotti di consumo, utilizza acquista in modo che l'utente possa acquistare di nuovo l'articolo.

Gli abbonamenti si rinnovano automaticamente fino all'annullamento. Un abbonamento può passare tramite i seguenti stati:

  • Attivo:l'utente ha una buona reputazione e può accedere all'abbonamento.
  • Annullato:l'utente ha annullato l'abbonamento, ma può ancora accedervi fino alla scadenza.
  • Durante il periodo di tolleranza: l'utente ha riscontrato un problema con il pagamento, ma può ancora accedervi. mentre Google riprova a utilizzare il metodo di pagamento.
  • In attesa:l'utente ha riscontrato un problema con il pagamento e non ha più accesso durante Google sta proverà di nuovo a utilizzare il metodo di pagamento.
  • In pausa: l'utente ha messo in pausa l'accesso e non può accedervi finché non ha riprendi.
  • Scaduto:l'utente ha annullato l'abbonamento e ha perso l'accesso all'abbonamento. La l'utente viene considerato abbandonato alla scadenza.

Inizializzare una connessione a Google Play

Il primo passaggio per l'integrazione con il sistema di fatturazione di Google Play consiste nell'aggiungere Libreria Fatturazione Google Play alla tua app e inizializza una connessione.

Aggiungere la dipendenza Libreria Fatturazione Google Play

Aggiungi la dipendenza Libreria Fatturazione Google Play a build.gradle della tua app come mostrato:

Alla moda

dependencies {
    def billing_version = "7.0.0"

    implementation "com.android.billingclient:billing:$billing_version"
}

Kotlin

dependencies {
    val billing_version = "7.0.0"

    implementation("com.android.billingclient:billing:$billing_version")
}

Se utilizzi Kotlin, il modulo KTX della Libreria Fatturazione Google Play contiene Supporto delle estensioni Kotlin e delle coroutine che consentono di scrivere espressioni idiomatiche Kotlin quando utilizzi Libreria Fatturazione Google Play. Per includere questi nel tuo progetto, aggiungi la seguente dipendenza build.gradle file come mostrato:

Alla moda

dependencies {
    def billing_version = "7.0.0"

    implementation "com.android.billingclient:billing-ktx:$billing_version"
}

Kotlin

dependencies {
    val billing_version = "7.0.0"

    implementation("com.android.billingclient:billing-ktx:$billing_version")
}

Inizializzare un client di fatturazione

Dopo aver aggiunto una dipendenza alla Libreria Fatturazione Google Play, devi per inizializzare un'istanza BillingClient. BillingClient è il livello principale per la comunicazione tra la Libreria Fatturazione Google Play e resto dell'app. BillingClient offre metodi pratici, sia sincrono e asincrona, per molte operazioni di fatturazione comuni. È vivamente consigliato di avere una connessione BillingClient attiva aperta alla volta per evita più callback PurchasesUpdatedListener per un singolo evento.

Per creare un BillingClient, utilizza newBuilder(). Puoi passare qualsiasi contesto a newBuilder() e BillingClient lo utilizza per ottenere il contesto dell'applicazione. Ciò significa che non dovrai preoccuparti di perdite di memoria. Per ricevere aggiornamenti su acquisti, devi anche richiamare setListener() per trasmettere un riferimento a un PurchasesUpdatedListener. Questo listener riceve aggiornamenti per tutti acquisti nella tua app.

Kotlin

private val purchasesUpdatedListener =
   PurchasesUpdatedListener { billingResult, purchases ->
       // To be implemented in a later section.
   }

private var billingClient = BillingClient.newBuilder(context)
   .setListener(purchasesUpdatedListener)
   // Configure other settings.
   .build()

Java

private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
    @Override
    public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
        // To be implemented in a later section.
    }
};

private BillingClient billingClient = BillingClient.newBuilder(context)
    .setListener(purchasesUpdatedListener)
    // Configure other settings.
    .build();

Connettersi a Google Play

Dopo aver creato un BillingClient, devi stabilire una connessione a su Google Play.

Per connetterti a Google Play, chiama il numero startConnection(). La connessione è asincrono e devi implementare BillingClientStateListener per ricevere una richiamata dopo la configurazione della completo ed è pronto a inviare ulteriori richieste.

Devi inoltre implementare la logica dei nuovi tentativi per gestire le connessioni perse a Google Play. Per implementare la logica dei nuovi tentativi, esegui l'override di onBillingServiceDisconnected() di callback e assicurati che BillingClient chiami il startConnection() per riconnetterti a Google Play prima di effettuare ulteriori richieste.

L'esempio seguente mostra come avviare una connessione e testare la sua pronto per l'uso:

Kotlin

billingClient.startConnection(object : BillingClientStateListener {
    override fun onBillingSetupFinished(billingResult: BillingResult) {
        if (billingResult.responseCode ==  BillingResponseCode.OK) {
            // The BillingClient is ready. You can query purchases here.
        }
    }
    override fun onBillingServiceDisconnected() {
        // Try to restart the connection on the next request to
        // Google Play by calling the startConnection() method.
    }
})

Java

billingClient.startConnection(new BillingClientStateListener() {
    @Override
    public void onBillingSetupFinished(BillingResult billingResult) {
        if (billingResult.getResponseCode() ==  BillingResponseCode.OK) {
            // The BillingClient is ready. You can query purchases here.
        }
    }
    @Override
    public void onBillingServiceDisconnected() {
        // Try to restart the connection on the next request to
        // Google Play by calling the startConnection() method.
    }
});

Mostra i prodotti disponibili per l'acquisto

Dopo aver stabilito una connessione a Google Play, puoi iniziare a chiedere per i prodotti disponibili e mostrali agli utenti.

Eseguire query sui dettagli del prodotto è un passaggio importante prima di visualizzare i prodotti agli utenti, in quanto restituisce informazioni localizzate sui prodotti. Per assicurati che la visualizzazione del tuo prodotto rispetti tutte le norme di Google Play.

Per richiedere i dettagli del prodotto in-app, chiama il numero queryProductDetailsAsync().

Per gestire il risultato dell'operazione asincrona, devi specificare anche un listener che implementa l'interfaccia ProductDetailsResponseListener. Puoi quindi eseguire l'override di onProductDetailsResponse(), che invia una notifica listener al termine della query, come mostrato nell'esempio seguente:

Kotlin

val queryProductDetailsParams =
    QueryProductDetailsParams.newBuilder()
        .setProductList(
            ImmutableList.of(
                Product.newBuilder()
                    .setProductId("product_id_example")
                    .setProductType(ProductType.SUBS)
                    .build()))
        .build()

billingClient.queryProductDetailsAsync(queryProductDetailsParams) {
    billingResult,
    productDetailsList ->
      // check billingResult
      // process returned productDetailsList
}

Java

QueryProductDetailsParams queryProductDetailsParams =
    QueryProductDetailsParams.newBuilder()
        .setProductList(
            ImmutableList.of(
                Product.newBuilder()
                    .setProductId("product_id_example")
                    .setProductType(ProductType.SUBS)
                    .build()))
        .build();

billingClient.queryProductDetailsAsync(
    queryProductDetailsParams,
    new ProductDetailsResponseListener() {
        public void onProductDetailsResponse(BillingResult billingResult,
                List<ProductDetails> productDetailsList) {
            // check billingResult
            // process returned productDetailsList
        }
    }
)

Quando esegui query sui dettagli del prodotto, passa un'istanza QueryProductDetailsParams che specifica un elenco di stringhe di ID prodotto creato in Google Play Console insieme a un ProductType. La ProductType può essere ProductType.INAPP per i prodotti a pagamento singolo o ProductType.SUBS per gli abbonamenti.

Esecuzione di query con le estensioni Kotlin

Se utilizzi le estensioni Kotlin, puoi eseguire una query per il prodotto in-app richiamando la funzione di estensione queryProductDetails().

queryProductDetails() sfrutta le coroutine Kotlin per evitare che tu debba definire un listener separato. La funzione viene invece sospesa fino a quando , dopodiché potrai elaborare il risultato:

suspend fun processPurchases() {
    val productList = listOf(
        QueryProductDetailsParams.Product.newBuilder()
            .setProductId("product_id_example")
            .setProductType(BillingClient.ProductType.SUBS)
            .build()
    )
    val params = QueryProductDetailsParams.newBuilder()
    params.setProductList(productList)

    // leverage queryProductDetails Kotlin extension function
    val productDetailsResult = withContext(Dispatchers.IO) {
        billingClient.queryProductDetails(params.build())
    }

    // Process the result.
}

Raramente, alcuni dispositivi non sono in grado di supportare ProductDetails e queryProductDetailsAsync(), generalmente a causa di versioni obsolete di Google Play Servizi. Per garantire un'adeguata assistenza per questo scenario, scopri come utilizzare funzionalità di compatibilità con le versioni precedenti nella migrazione alla Libreria Fatturazione Play 5 .

Elabora il risultato

La Libreria Fatturazione Google Play archivia i risultati della query in un List di ProductDetails oggetti. Puoi quindi chiamare diversi metodi su ogni ProductDetails oggetto nell'elenco per visualizzare le informazioni pertinenti su un'app in-app prodotto, come il prezzo o la descrizione. Per visualizzare i dettagli del prodotto disponibili informazioni, consulta l'elenco dei metodi della classe ProductDetails.

Prima di mettere in vendita un articolo, verifica che l'utente non possieda già molto utile. Se l'utente ha un consumabile ancora nella raccolta di elementi, devono consumare l'articolo prima di poterlo acquistare di nuovo.

Prima di offrire un abbonamento, verifica che l'utente non sia già abbonato. Tieni inoltre presente quanto segue:

  • queryProductDetailsAsync() restituisce i dettagli del prodotto in abbonamento e un un massimo di 50 offerte per abbonamento.
  • queryProductDetailsAsync() restituisce solo le offerte per le quali l'utente è idonei. Se l'utente cerca di acquistare un'offerta per la quale non idonea (ad esempio, se l'app mostra un elenco di offerte idonee), Google Play comunica all'utente di non essere idoneo e l'utente può scegliere di acquistare il piano base.
di Gemini Advanced.

Avviare il flusso di acquisto

Per avviare una richiesta di acquisto dalla tua app, chiama il launchBillingFlow() dal thread principale dell'app. Questo metodo prende un riferimento a un BillingFlowParams oggetto che contiene l'oggetto pertinente Oggetto ProductDetails ottenuto dalla chiamata queryProductDetailsAsync() Per creare un oggetto BillingFlowParams, utilizza la classe BillingFlowParams.Builder.

Kotlin

// An activity reference from which the billing flow will be launched.
val activity : Activity = ...;

val productDetailsParamsList = listOf(
    BillingFlowParams.ProductDetailsParams.newBuilder()
        // retrieve a value for "productDetails" by calling queryProductDetailsAsync()
        .setProductDetails(productDetails)
        // For One-time product, "setOfferToken" method shouldn't be called.
        // For subscriptions, to get an offer token, call ProductDetails.subscriptionOfferDetails()
        // for a list of offers that are available to the user
        .setOfferToken(selectedOfferToken)
        .build()
)

val billingFlowParams = BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(productDetailsParamsList)
    .build()

// Launch the billing flow
val billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)

Java

// An activity reference from which the billing flow will be launched.
Activity activity = ...;

ImmutableList<ProductDetailsParams> productDetailsParamsList =
    ImmutableList.of(
        ProductDetailsParams.newBuilder()
             // retrieve a value for "productDetails" by calling queryProductDetailsAsync()
            .setProductDetails(productDetails)
            // For one-time products, "setOfferToken" method shouldn't be called.
            // For subscriptions, to get an offer token, call
            // ProductDetails.subscriptionOfferDetails() for a list of offers
            // that are available to the user.
            .setOfferToken(selectedOfferToken)
            .build()
    );

BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(productDetailsParamsList)
    .build();

// Launch the billing flow
BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);

Il metodo launchBillingFlow() restituisce uno dei vari codici di risposta elencati in BillingClient.BillingResponseCode Controlla questo risultato per assicurati che non si siano verificati errori nell'avvio del flusso di acquisto. BillingResponseCode di OK indica un lancio riuscito.

In una chiamata a launchBillingFlow() riuscita, il sistema mostra Schermata di acquisto di Play. La figura 1 mostra una schermata di acquisto di un abbonamento:

la schermata di acquisto su Google Play mostra un abbonamento
            disponibile per l&#39;acquisto
Figura 1. La schermata di acquisto di Google Play mostra disponibile per l'acquisto.

Google Play chiama il numero onPurchasesUpdated() per consegnare il risultato dell'acquisto per un listener che implementa l'elemento PurchasesUpdatedListener a riga di comando. Il listener viene specificato utilizzando il metodo setListener() quando inizializzato il client.

Devi implementare onPurchasesUpdated() per gestire i possibili codici di risposta. La l'esempio seguente mostra come eseguire l'override di onPurchasesUpdated():

Kotlin

override fun onPurchasesUpdated(billingResult: BillingResult, purchases: List<Purchase>?) {
   if (billingResult.responseCode == BillingResponseCode.OK && purchases != null) {
       for (purchase in purchases) {
           handlePurchase(purchase)
       }
   } else if (billingResult.responseCode == BillingResponseCode.USER_CANCELED) {
       // Handle an error caused by a user cancelling the purchase flow.
   } else {
       // Handle any other error codes.
   }
}

Java

@Override
void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
    if (billingResult.getResponseCode() == BillingResponseCode.OK
        && purchases != null) {
        for (Purchase purchase : purchases) {
            handlePurchase(purchase);
        }
    } else if (billingResult.getResponseCode() == BillingResponseCode.USER_CANCELED) {
        // Handle an error caused by a user cancelling the purchase flow.
    } else {
        // Handle any other error codes.
    }
}

Un acquisto eseguito correttamente genera una schermata di acquisto riuscito su Google Play simile a: figura 2.

schermata di acquisto riuscito di google play
Figura 2. Acquisto andato a buon fine di Google Play schermo.

Un acquisto riuscito genera anche un token di acquisto, che è un identificatore che rappresenta l'utente e l'ID prodotto del prodotto in-app acquistato. Le tue app possono memorizzare il token di acquisto localmente, anche se ti consigliamo di passare il token al server di backend sicuro, dove potrai verificare l'acquisto e proteggere da attività fraudolente. Questo processo è descritto più dettagliatamente nella sezione seguente.

All'utente viene inoltre inviata via email una ricevuta della transazione contenente un ID ordine o un ID univoco della transazione. Gli utenti ricevono un'email con un ID ordine univoco per ogni acquisto di un prodotto una tantum e anche per l'abbonamento iniziale acquisti e successivi rinnovi automatici ricorrenti. Puoi utilizzare l'ID ordine per gestire i rimborsi in Google Play Console.

Indica un prezzo personalizzato

Se la tua app può essere distribuita agli utenti nell'Unione Europea, utilizza la setIsOfferPersonalized() metodo per comunicare agli utenti che il prezzo di un articolo era personalizzati mediante il processo decisionale automatizzato.

La schermata di acquisto su Google Play in cui viene indicato che il prezzo è stato personalizzato per l&#39;utente.
Figura 3. La schermata di acquisto di Google Play che indica in modo che il prezzo sia stato personalizzato per l'utente.

Devi consultare l'articolo 6 (1) (ea) CRD della direttiva sui diritti dei consumatori 2011/83/UE per determinare se il prezzo che offri agli utenti è personalizzati.

setIsOfferPersonalized() accetta un input booleano. Quando true, l'UI di Google Play include l'informativa. Quando false, l'interfaccia utente omette l'informativa. Il valore predefinito è false.

Consulta il Centro assistenza per i consumatori per ulteriori informazioni.

Elaborazione degli acquisti

Una volta che l'utente completa un acquisto, la tua app deve elaborarlo. Nella maggior parte dei casi, l'app riceve una notifica relativa agli acquisti tramite PurchasesUpdatedListener Tuttavia, in alcuni casi la tua app verrà effettuato acquisti chiamando il numero BillingClient.queryPurchasesAsync() come descritto nella sezione Recupero degli acquisti.

Inoltre, se disponi di un client Notifiche in tempo reale per lo sviluppatore in tuo backend sicuro, puoi registrare nuovi acquisti ricevendo un subscriptionNotification o oneTimeProductNotification che ti avvisa di un nuovo acquisto. Dopo aver ricevuto queste notifiche, chiama il team di Google Play l'API Developer per ottenere lo stato completo e aggiornare il tuo stato del backend.

La tua app dovrebbe elaborare un acquisto nel seguente modo:

  1. Verifica l'acquisto.
  2. Fornisci contenuti all'utente e conferma la consegna. (Facoltativo) Contrassegna l'articolo come consumato in modo che l'utente possa acquistarlo di nuovo.

Per verificare un acquisto, controlla innanzitutto che lo stato di acquisto sia PURCHASED Se l'acquisto è PENDING, devi elaborare effettuare un acquisto come descritto in Gestione delle transazioni in sospeso. Per gli acquisti ricevuto da onPurchasesUpdated() o queryPurchasesAsync(), Devi verificare ulteriormente l'acquisto per garantirne la legittimità prima che l'app ti conceda e il diritto di accesso. Per scoprire come verificare correttamente un acquisto, consulta l'articolo Verificare gli acquisti prima di concedere i diritti.

Una volta verificato l'acquisto, la tua app è pronta per concedere il diritto ai utente. L'account utente associato all'acquisto può essere identificato con ProductPurchase.obfuscatedExternalAccountId restituito da Purchases.products:get per gli acquisti di prodotti in-app e per SubscriptionPurchase.obfuscatedExternalAccountId restituito da Purchases.subscriptions:get per gli abbonamenti lato server oppure obfuscatedAccountId di Purchase.getAccountIdentifiers() su lato client, se uno dei due è stato impostato con setObfuscatedAccountId quando è stato effettuato l'acquisto.

Dopo aver concesso il diritto, l'app deve confermare l'acquisto. Questo conferma comunica a Google Play che hai concesso il diritto per l'acquisto.

La procedura per concedere il diritto e confermare l'acquisto dipende dal fatto che l'acquisto è un prodotto di consumo, non consumabile o un abbonamento.

Prodotti di consumo

Per i materiali di consumo, se la tua app ha un backend sicuro, ti consigliamo di usare Purchases.products:consume per consumare i tuoi acquisti in modo affidabile. Assicurati che acquisto non sia già stato consumato controllando l'elemento consumptionState di il risultato della chiamata a Purchases.products:get. Se la tua app è solo client senza backend, utilizza consumeAsync() Libreria Fatturazione Google Play. Entrambi i metodi soddisfano i criteri di riconoscimento e indicare che la tua app ha concesso diritto all'utente. Questi metodi consentono inoltre alla tua app di rendere il prodotto a pagamento singolo corrispondente il token di acquisto inserito disponibile per il riacquisto. Con consumeAsync() tu deve anche passare un oggetto che implementa ConsumeResponseListener a riga di comando. Questo oggetto gestisce il risultato dell'operazione di consumo. Puoi sostituisce il metodo onConsumeResponse(), che Libreria Fatturazione Google Play al termine dell'operazione.

L'esempio seguente illustra il consumo di un prodotto con Libreria Fatturazione Google Play utilizzando il token di acquisto associato:

Kotlin

suspend fun handlePurchase(purchase: Purchase) {
    // Purchase retrieved from BillingClient#queryPurchasesAsync or your PurchasesUpdatedListener.
    val purchase : Purchase = ...;

    // Verify the purchase.
    // Ensure entitlement was not already granted for this purchaseToken.
    // Grant entitlement to the user.

    val consumeParams =
        ConsumeParams.newBuilder()
            .setPurchaseToken(purchase.getPurchaseToken())
            .build()
    val consumeResult = withContext(Dispatchers.IO) {
        client.consumePurchase(consumeParams)
    }
}

Java

void handlePurchase(Purchase purchase) {
    // Purchase retrieved from BillingClient#queryPurchasesAsync or your PurchasesUpdatedListener.
    Purchase purchase = ...;

    // Verify the purchase.
    // Ensure entitlement was not already granted for this purchaseToken.
    // Grant entitlement to the user.

    ConsumeParams consumeParams =
        ConsumeParams.newBuilder()
            .setPurchaseToken(purchase.getPurchaseToken())
            .build();

    ConsumeResponseListener listener = new ConsumeResponseListener() {
        @Override
        public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
            if (billingResult.getResponseCode() == BillingResponseCode.OK) {
                // Handle the success of the consume operation.
            }
        }
    };

    billingClient.consumeAsync(consumeParams, listener);
}

Prodotti non consumabili

Per confermare gli acquisti non consumabili, se la tua app ha un backend sicuro, consiglia di utilizzare Purchases.products:acknowledge per confermare in modo affidabile acquisti. Assicurati che l'acquisto non sia stato precedentemente confermato da controllando acknowledgementState dal risultato della chiamata Purchases.products:get.

Se la tua app è solo client, utilizza BillingClient.acknowledgePurchase() da alla Libreria Fatturazione Google Play nella tua app. Prima di confermare che l'acquisto, la tua app deve controllare se è già stata confermata utilizzando isAcknowledged() nella Libreria Fatturazione Google Play.

L'esempio seguente mostra come confermare un acquisto utilizzando il Libreria Fatturazione Google Play:

Kotlin

val client: BillingClient = ...
val acknowledgePurchaseResponseListener: AcknowledgePurchaseResponseListener = ...

suspend fun handlePurchase() {
    if (purchase.purchaseState === PurchaseState.PURCHASED) {
        if (!purchase.isAcknowledged) {
            val acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder()
                    .setPurchaseToken(purchase.purchaseToken)
            val ackPurchaseResult = withContext(Dispatchers.IO) {
               client.acknowledgePurchase(acknowledgePurchaseParams.build())
            }
        }
     }
}

Java

BillingClient client = ...
AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener = ...

void handlePurchase(Purchase purchase) {
    if (purchase.getPurchaseState() == PurchaseState.PURCHASED) {
        if (!purchase.isAcknowledged()) {
            AcknowledgePurchaseParams acknowledgePurchaseParams =
                AcknowledgePurchaseParams.newBuilder()
                    .setPurchaseToken(purchase.getPurchaseToken())
                    .build();
            client.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener);
        }
    }
}

Iscrizioni

Gli abbonamenti vengono gestiti in modo simile ai beni non consumabili. Se possibile, utilizza Purchases.subscriptions.acknowledge dal l'API Google Play Developer per confermare in modo affidabile l'acquisto dal tuo un backend sicuro. Verifica che l'acquisto non sia stato precedentemente confermato da controllando acknowledgementState nella risorsa di acquisto da Purchases.subscriptions:get. In caso contrario, puoi confermare di abbonamento utilizzando BillingClient.acknowledgePurchase() dal Libreria Fatturazione Google Play dopo aver controllato isAcknowledged(). Tutti gli acquisti iniziali degli abbonamenti devono essere confermati. Rinnovi dell'abbonamento senza necessità di riconoscimento. Per ulteriori informazioni su quando gli abbonamenti devono essere confermati, consulta l'argomento Vendere abbonamenti.

Recupero acquisti in corso...

Ascoltare gli aggiornamenti sugli acquisti utilizzando un PurchasesUpdatedListener non è sufficienti per assicurarti che la tua app elabori tutti gli acquisti. È possibile che il tuo potrebbe non essere a conoscenza di tutti gli acquisti effettuati da un utente. Ecco alcuni esempi scenari in cui la tua app potrebbe perdere traccia o non essere a conoscenza degli acquisti:

  • Problemi di rete durante l'acquisto: un utente effettua un acquisto. e riceve conferma da Google, ma il suo dispositivo perde la rete di connettività prima che il dispositivo riceva la notifica dell'acquisto tramite PurchasesUpdatedListener.
  • Più dispositivi: un utente acquista un articolo su un dispositivo e poi si aspetta di farlo vedere l'elemento quando cambia dispositivo.
  • Gestire gli acquisti effettuati al di fuori dell'app: alcuni acquisti, ad esempio utilizzo delle promozioni, possono essere effettuati al di fuori dell'app.

Per gestire queste situazioni, assicurati che la tua app chiami BillingClient.queryPurchasesAsync() nel metodo onResume() per verifica che tutti gli acquisti vengano elaborati correttamente come descritto nella sezione Elaborazione acquisti.

L'esempio seguente mostra come recuperare gli acquisti di un abbonamento da un utente. Tieni presente che queryPurchasesAsync() restituisce solo gli abbonamenti attivi e acquisti una tantum non consumati.

Kotlin

val params = QueryPurchasesParams.newBuilder()
               .setProductType(ProductType.SUBS)

// uses queryPurchasesAsync Kotlin extension function
val purchasesResult = billingClient.queryPurchasesAsync(params.build())

// check purchasesResult.billingResult
// process returned purchasesResult.purchasesList, e.g. display the plans user owns

Java

billingClient.queryPurchasesAsync(
    QueryPurchasesParams.newBuilder()
      .setProductType(ProductType.SUBS)
      .build(),
    new PurchasesResponseListener() {
      public void onQueryPurchasesResponse(BillingResult billingResult, List<Purchase> purchases) {
        // check billingResult
        // process returned purchase list, e.g. display the plans user owns

      }
    }
);

Gestione degli acquisti effettuati al di fuori dell'app

Alcuni acquisti, come l'utilizzo delle promozioni, possono avvenire al di fuori dell'app. Quando un utente effettua un acquisto al di fuori della tua app, si aspetta che venga visualizzata la tua app un messaggio in-app o utilizzare un qualche tipo di meccanismo di notifica per consentire all'utente che l'app abbia ricevuto ed elaborato correttamente l'acquisto. Abbastanza accettabile meccanismi sono:

  • Mostra un popup in-app.
  • Consegnare il messaggio a un messaggio in-app indicando chiaramente è un nuovo messaggio nella casella del messaggio in-app.
  • Utilizza un messaggio di notifica del sistema operativo.

Tieni presente che è possibile che la tua app si trovi in qualsiasi stato quando viene riconosce l'acquisto. È persino possibile che la tua app non venga installata al momento dell'acquisto. Gli utenti si aspettano di ricevere l'acquisto quando riprendono l'app, indipendentemente dallo stato in cui si trova.

Devi rilevare gli acquisti indipendentemente dallo stato in cui si trova l'app quando è stato effettuato l'acquisto. Tuttavia, ci sono alcune eccezioni in cui può essere accettabile per non informare immediatamente l'utente della ricezione dell'articolo. Ad esempio:

  • Durante l'azione di un gioco, in cui mostrare un messaggio potrebbe distrarre utente. In questo caso, è necessario informare l'utente al termine della parte dell'azione.
  • Durante gli intermezzi, in cui la visualizzazione di un messaggio potrebbe distrarre l'utente. In questo devi avvisare l'utente al termine della scena.
  • Durante il tutorial iniziale e le parti del gioco per la configurazione dell'utente. I nostri suggerimenti devi avvisare i nuovi utenti del premio subito dopo aver aperto il gioco oppure durante la configurazione iniziale dell'utente. Tuttavia, è accettabile attendere che l'istanza principale la sequenza di gioco per inviare una notifica all'utente.

Tieni sempre presente l’utente quando decidi quando e come informare gli utenti della acquisti effettuati al di fuori della tua app. Ogni volta che un utente non riceve immediatamente una notifica, potrebbero essere confusi, smettere di usare la tua app, contattare l'utente assistenza o si lamenta sui social media. Nota: PurchasesUpdatedListener è registrato con la tua applicazione contesto per gestire gli aggiornamenti sugli acquisti, inclusi gli acquisti avviati al di fuori della tua app. Ciò significa che se la procedura di richiesta non esiste, PurchasesUpdatedListener non riceverà alcuna notifica. Ecco perché la tua app dovrebbe chiama BillingClient.queryPurchasesAsync() nel metodo onResume() come menzionato in Recupera acquisti.

Gestione delle transazioni in sospeso

Google Play supporta le transazioni in attesa o le transazioni che richiedono uno o altri passaggi aggiuntivi tra il momento in cui un utente avvia un acquisto e il momento in cui metodo di pagamento usato per l'acquisto. La tua app non deve concedere diritto a questi tipi di acquisti finché Google non ti avvisa che il l'addebito sul metodo di pagamento dell'utente è stato eseguito correttamente.

Ad esempio, un utente può avviare una transazione scegliendo un negozio fisico dove pagherà in seguito in contanti. L'utente riceve un codice tramite notifica ed email. Quando l'utente arriva nel negozio fisico, puoi utilizzare il codice presso il cassiere e pagare in contanti. Google invia una notifica sia a te che all'utente che il pagamento è stato ricevuto. L'app può quindi concedere diritto all'utente.

Chiama enablePendingPurchases() durante l'inizializzazione della BillingClient per attivare le transazioni in attesa per la tua app. L'app deve attivare e supportare le transazioni in attesa per i prodotti a pagamento singolo. Prima del giorno aggiungendo l'assistenza, assicurati di comprendere il ciclo di vita di acquisto per gli account transazioni.

Quando la tua app riceve un nuovo acquisto, tramite PurchasesUpdatedListener o a seguito della chiamata queryPurchasesAsync(), utilizza il metodo getPurchaseState() per determina se lo stato di acquisto è PURCHASED o PENDING. Dovresti concedi il diritto solo quando lo stato è PURCHASED.

Se l'app è in esecuzione quando l'utente completa l'acquisto, i tuoi PurchasesUpdatedListener è stato richiamato e PurchaseState è ora PURCHASED. A questo punto, la tua app può elaborare l'acquisto utilizzando la per elaborare gli acquisti. L'app deve anche chiamare queryPurchasesAsync() nel metodo onResume() della tua app per gestire gli acquisti che sono passati allo stato PURCHASED mentre l'app non era in esecuzione.

Quando l'acquisto passa da PENDING a PURCHASED, il tuo client Notifiche in tempo reale per lo sviluppatore riceve un ONE_TIME_PRODUCT_PURCHASED o SUBSCRIPTION_PURCHASED notifica. Se l'acquisto viene annullato, riceve un ONE_TIME_PRODUCT_CANCELED o Notifica SUBSCRIPTION_PENDING_PURCHASE_CANCELED. Ciò può accadere se le tue Il cliente non completa il pagamento nel periodo di tempo richiesto. Tieni presente che puoi sempre usare l'API Google Play Developer per verificare lo stato attuale di una acquisto.

Gestione degli acquisti di più quantità

Funzionalità supportata nelle versioni 4.0 e successive di Libreria Fatturazione Google Play, Google Play consente ai clienti di acquistare più prodotti in-app uguali prodotto in una transazione specificando una quantità dal carrello degli acquisti. Il tuo l'app deve gestire acquisti di più quantità e concedere in base al diritto sulla quantità di acquisto specificata.

Per rispettare gli acquisti di più quantità, la logica di provisioning della tua app deve controllare per una quantità di articoli. Puoi accedere a un campo quantity da una delle le seguenti API:

Dopo aver aggiunto la logica per gestire gli acquisti di più quantità, devi Attiva la funzionalità di più quantità per il prodotto corrispondente nell'app pagina di gestione dei prodotti nella Console per gli sviluppatori di Google Play.

Esegui una query sulla configurazione di fatturazione dell'utente

getBillingConfigAsync() indica il paese utilizzato dall'utente su Google Play.

Puoi eseguire query sulla configurazione di fatturazione dell'utente dopo creazione di un BillingClient. Lo snippet di codice riportato di seguito descrive come chiamare getBillingConfigAsync(). Per gestire la risposta, implementando BillingConfigResponseListener. Questo listener riceve aggiornamenti per tutte le query sulla configurazione di fatturazione avviate dalla tua app.

Se l'oggetto BillingResult restituito non contiene errori, puoi controllare il valore Campo countryCode nell'oggetto BillingConfig per ottenere la Play dell'utente Paese.

Kotlin

// Use the default GetBillingConfigParams.
val getBillingConfigParams = GetBillingConfigParams.newBuilder().build()
billingClient.getBillingConfigAsync(getBillingConfigParams,
    object : BillingConfigResponseListener {
        override fun onBillingConfigResponse(
            billingResult: BillingResult,
            billingConfig: BillingConfig?
        ) {
            if (billingResult.responseCode == BillingResponseCode.OK
                && billingConfig != null) {
                val countryCode = billingConfig.countryCode
                ...
            } else {
                // TODO: Handle errors
            }
        }
    })

Java

// Use the default GetBillingConfigParams.
GetBillingConfigParams getBillingConfigParams = GetBillingConfigParams.newBuilder().build();
billingClient.getBillingConfigAsync(getBillingConfigParams,
    new BillingConfigResponseListener() {
      public void onBillingConfigResponse(
          BillingResult billingResult, BillingConfig billingConfig) {
        if (billingResult.getResponseCode() == BillingResponseCode.OK
            && billingConfig != null) {
            String countryCode = billingConfig.getCountryCode();
            ...
         } else {
            // TODO: Handle errors
        }
      }
    });