Questo documento descrive come integrare la Libreria Fatturazione Google Play nella tua app per iniziare a vendere prodotti.
Durata di un acquisto
Di seguito è riportato un flusso di acquisto tipico per un acquisto singolo o un abbonamento.
- Mostra all'utente cosa può acquistare.
- Avvia il flusso di acquisto per consentire all'utente di accettare l'acquisto.
- Verifica l'acquisto sul tuo server.
- Fornire contenuti all'utente.
- Conferma la ricezione dei contenuti. Per i prodotti di consumo, consuma l'acquisto in modo che l'utente possa acquistare di nuovo l'articolo.
Gli abbonamenti si rinnovano automaticamente finché non vengono annullati. Un abbonamento può passare attraverso i seguenti stati:
- Attivo: l'utente è in regola e ha accesso all'abbonamento.
- Annullato: l'utente ha annullato l'abbonamento, ma ha ancora accesso fino alla scadenza.
- Nel periodo di tolleranza: l'utente ha riscontrato un problema di pagamento, ma ha ancora accesso mentre Google riprova a utilizzare il metodo di pagamento.
- In attesa: l'utente ha riscontrato un problema di pagamento e non ha più accesso mentre Google sta riprovando a utilizzare il metodo di pagamento.
- In pausa: l'utente ha messo in pausa l'accesso e non potrà riprenderlo finché non lo riattiva.
- Scaduto: l'utente ha annullato l'abbonamento e ha perso l'accesso. L'utente viene considerato perso 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 la libreria Fatturazione Google Play alla tua app e inizializzare una connessione.
Aggiungi la dipendenza della Libreria Fatturazione Google Play
Aggiungi la dipendenza della Libreria Fatturazione Google Play al file build.gradle
della tua app come mostrato di seguito:
Groovy
dependencies { def billing_version = "8.0.0" implementation "com.android.billingclient:billing:$billing_version" }
Kotlin
dependencies { val billing_version = "8.0.0" implementation("com.android.billingclient:billing:$billing_version") }
Se utilizzi Kotlin, il modulo KTX della Libreria Fatturazione Google Play contiene
estensioni e supporto delle coroutine Kotlin che ti consentono di scrivere codice Kotlin
idiomatico quando utilizzi la Libreria Fatturazione Google Play. Per includere queste
estensioni nel tuo progetto, aggiungi la seguente dipendenza al file
build.gradle
della tua app, come mostrato:
Groovy
dependencies { def billing_version = "8.0.0" implementation "com.android.billingclient:billing-ktx:$billing_version" }
Kotlin
dependencies { val billing_version = "8.0.0" implementation("com.android.billingclient:billing-ktx:$billing_version") }
Inizializzare un oggetto BillingClient
Dopo aver aggiunto una dipendenza dalla Libreria Fatturazione Google Play, devi inizializzare un'istanza di BillingClient
. BillingClient
è l'interfaccia principale per la comunicazione tra la Libreria Fatturazione Google Play e il resto dell'app. BillingClient
fornisce metodi pratici, sincroni e asincroni, per molte operazioni di fatturazione comuni. Prendi nota di quanto segue:
- Ti consigliamo di avere una sola connessione
BillingClient
attiva aperta alla volta per evitare più callbackPurchasesUpdatedListener
per un singolo evento. - Ti consigliamo di avviare una connessione per BillingClient quando la tua
app viene avviata o portata in primo piano per assicurarti che elabori
gli acquisti in modo tempestivo. Puoi farlo utilizzando
ActivityLifecycleCallbacks
registrato daregisterActivityLifecycleCallbacks
e ascoltando onActivityResumed per inizializzare una connessione quando rilevi per la prima volta la ripresa di un'attività. Per ulteriori dettagli sul motivo per cui è consigliabile seguire questa best practice, consulta la sezione relativa all'elaborazione degli acquisti. Ricordati anche di terminare la connessione quando l'app è chiusa.
Per creare un BillingClient
, utilizza newBuilder
. Puoi passare qualsiasi contesto a
newBuilder()
e BillingClient
lo utilizza per ottenere un contesto dell'applicazione. Ciò
significa che non devi preoccuparti delle perdite di memoria. Per ricevere aggiornamenti sugli
acquisti, devi anche chiamare setListener
, passando un riferimento a un
PurchasesUpdatedListener
. Questo listener riceve aggiornamenti per tutti gli 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();
Collegati a Google Play
Dopo aver creato un BillingClient
, devi stabilire una connessione a
Google Play.
Per connetterti a Google Play, chiama il numero startConnection
. Il processo di connessione
è asincrono e devi implementare un BillingClientStateListener
per
ricevere un callback una volta completata la configurazione del client e quando è pronto per
effettuare ulteriori richieste.
Devi anche implementare la logica di ripetizione per gestire le connessioni perse a Google Play.
Per implementare la logica di ripetizione, esegui l'override del metodo di callback onBillingServiceDisconnected()
e assicurati che BillingClient
chiami il metodo startConnection()
per riconnettersi a Google Play prima di effettuare ulteriori richieste.
L'esempio seguente mostra come avviare una connessione e verificare che sia pronta 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. } });
Ristabilire automaticamente una connessione
Con l'introduzione del metodo enableAutoServiceReconnection()
in
BillingClient.Builder
nella versione 8.0.0, la libreria Play Billing può
ora ristabilire automaticamente la connessione al servizio se viene effettuata una chiamata API
mentre il servizio è disconnesso. Ciò può comportare una riduzione delle risposte SERVICE_DISCONNECTED
poiché la riconnessione viene gestita internamente prima di effettuare la chiamata API.
Come attivare la riconnessione automatica
Quando crei un'istanza BillingClient
, utilizza il metodo
enableAutoServiceReconnection()
in BillingClient.Builder
per
attivare la riconnessione automatica.
Kotlin
val billingClient = BillingClient.newBuilder(context)
.setListener(listener)
.enablePendingPurchases()
.enableAutoServiceReconnection() // Add this line to enable reconnection
.build()
Java
BillingClient billingClient = BillingClient.newBuilder(context)
.setListener(listener)
.enablePendingPurchases()
.enableAutoServiceReconnection() // Add this line to enable reconnection
.build();
Mostra i prodotti disponibili per l'acquisto
Dopo aver stabilito una connessione a Google Play, puoi eseguire query per i tuoi prodotti disponibili e mostrarli agli utenti.
La query per i dettagli del prodotto è un passaggio importante prima di mostrare i tuoi prodotti agli utenti, in quanto restituisce informazioni localizzate sul prodotto. Per gli abbonamenti, verifica che la visualizzazione del prodotto rispetti tutte le norme di Google Play.
Per eseguire una query per i dettagli del prodotto a pagamento singolo, chiama il metodo queryProductDetailsAsync
. Questo metodo può restituire più offerte in base alla configurazione del prodotto
a pagamento singolo. Per maggiori informazioni, consulta la sezione Offerte e opzioni di acquisto multiple
per i prodotti a pagamento singolo.
Per gestire il risultato dell'operazione asincrona, devi anche specificare un
listener che implementi l'interfaccia ProductDetailsResponseListener
.
Puoi quindi eseguire l'override di onProductDetailsResponse
, che invia una notifica al
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, queryProductDetailsResult -> if (billingResult.getResponseCode() == BillingResponseCode.OK) { for (ProductDetails productDetails : queryProductDetailsResult.getProductDetailsList()) { // Process successfully retrieved product details here. } for (UnfetchedProduct unfetchedProduct : queryproductDetailsResult.getUnfetchedProductList()) { // Handle any unfetched products as appropriate. } } }
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, QueryProductDetailsResult queryProductDetailsResult) { if (billingResult.getResponseCode() == BillingResponseCode.OK) { for (ProductDetails productDetails : queryProductDetailsResult().getProductDetailsList()) { // Process success retrieved product details here. } for (UnfetchedProduct unfetchedProduct : queryproductDetailsResult.getUnfetchedProductList()) { // Handle any unfetched products as appropriate. } } } } )
Quando esegui una query per i dettagli del prodotto, passa un'istanza di
QueryProductDetailsParams
che specifica un elenco di stringhe ID prodotto
create in Google Play Console insieme a un ProductType
. Il
ProductType
può essere ProductType.INAPP
per i prodotti a pagamento singolo o
ProductType.SUBS
per gli abbonamenti.
Eseguire query con le estensioni Kotlin
Se utilizzi le estensioni Kotlin, puoi eseguire query per i dettagli dei prodotti a pagamento singolo chiamando la funzione di estensione queryProductDetails()
.
queryProductDetails()
utilizza le coroutine Kotlin, quindi non è necessario
definire un listener separato. La funzione viene sospesa fino al completamento della query, dopodiché puoi 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()
, in genere a causa di versioni obsolete di Google Play
Services. Per fornire un supporto adeguato a questo scenario, scopri come utilizzare le funzionalità di compatibilità con le versioni precedenti nella guida alla migrazione della Libreria Fatturazione Play 7.
Elaborare il risultato
La Libreria Fatturazione Google Play memorizza i risultati della query in un oggetto
QueryProductDetailsResult
. QueryProductDetailsResult
contiene un List
di oggetti ProductDetails
. Puoi quindi chiamare una
varietà di metodi su ogni oggetto ProductDetails
nell'elenco per visualizzare le
informazioni pertinenti su un prodotto una tantum recuperato correttamente, ad esempio il
prezzo o la descrizione. Per visualizzare le informazioni dettagliate sui prodotti disponibili, consulta
l'elenco dei metodi nella classe ProductDetails
.
QueryProductDetailsResult
contiene anche un List
di oggetti
UnfetchedProduct
. Puoi quindi eseguire query su ogni UnfetchedProduct
per ottenere un codice di stato corrispondente al motivo dell'errore di recupero.
Per visualizzare le informazioni sui prodotti disponibili non recuperate,
consulta l'elenco dei metodi nella classe UnfetchedProduct
.
Prima di offrire un articolo in vendita, verifica che l'utente non lo possieda già. Se l'utente ha un consumabile ancora nella sua raccolta di articoli, deve consumarlo prima di poterlo acquistare di nuovo.
Prima di offrire un abbonamento, verifica che l'utente non abbia già sottoscritto un abbonamento. Tieni presente anche quanto segue:
Per gli abbonamenti, il metodo
queryProductDetailsAsync()
restituisce i dettagli del prodotto in abbonamento e un massimo di 50 offerte idonee per utente per abbonamento. Se l'utente tenta di acquistare un'offerta non idonea (ad esempio, se l'app mostra un elenco obsoleto di offerte idonee), Play informa l'utente che non è idoneo e può scegliere di acquistare il piano base.Per i prodotti a pagamento singolo, il metodo
queryProductDetailsAsync()
restituisce solo le offerte idonee per l'utente. Se l'utente tenta di acquistare un'offerta per cui non è idoneo (ad esempio, se ha raggiunto il limite di quantità di acquisto), Play lo informa che non è idoneo e l'utente può scegliere di acquistare invece l'offerta di opzione di acquisto.
Avviare il flusso di acquisto
Per avviare una richiesta di acquisto dalla tua app, chiama il metodo launchBillingFlow()
dal thread principale dell'app. Questo metodo accetta un riferimento a un oggetto
BillingFlowParams
che contiene l'oggetto
ProductDetails
pertinente ottenuto chiamando
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) // Get the offer token: // a. For one-time products, call ProductDetails.getOneTimePurchaseOfferDetailsList() // for a list of offers that are available to the user. // b. For subscriptions, 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) // Get the offer token: // a. For one-time products, call ProductDetails.getOneTimePurchaseOfferDetailsList() // for a list of offers that are available to the user. // b. For subscriptions, 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
. Assicurati di controllare questo risultato per
verificare che non si siano verificati errori durante l'avvio del flusso di acquisto. Un BillingResponseCode
di OK
indica un lancio riuscito.
Se la chiamata a launchBillingFlow()
va a buon fine, il sistema visualizza la schermata di acquisto di Google Play. La figura 1 mostra una schermata di acquisto di un abbonamento:

Google Play chiama onPurchasesUpdated()
per fornire il risultato dell'operazione di acquisto
a un listener che implementa l'interfaccia PurchasesUpdatedListener
. Il listener viene specificato utilizzando il metodo setListener()
quando hai
inizializzato il client.
Devi implementare onPurchasesUpdated()
per gestire i possibili codici di risposta. 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) { // Process the purchase as described in the next section. } } else if (billingResult.responseCode == BillingResponseCode.USER_CANCELED) { // Handle an error caused by a user canceling 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) { // Process the purchase as described in the next section. } } else if (billingResult.getResponseCode() == BillingResponseCode.USER_CANCELED) { // Handle an error caused by a user canceling the purchase flow. } else { // Handle any other error codes. } }
Un acquisto riuscito genera una schermata di conferma dell'acquisto su Google Play simile a quella della figura 2.

Un acquisto riuscito genera anche un token di acquisto, ovvero un identificatore univoco che rappresenta l'utente e l'ID prodotto del prodotto a pagamento singolo acquistato. Le tue app possono archiviare il token di acquisto localmente, anche se consigliamo vivamente di passarlo al server di backend sicuro, dove puoi verificare l'acquisto e proteggerti dalle frodi. Questa procedura è descritta in dettaglio nella sezione Rilevamento ed elaborazione degli acquisti.
L'utente riceve anche 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, nonché per l'acquisto dell'abbonamento iniziale e per i successivi rinnovi automatici ricorrenti. Puoi utilizzare l'ID ordine per gestire i rimborsi in Google Play Console.
Indicare un prezzo personalizzato
Se la tua app può essere distribuita agli utenti dell'Unione Europea, utilizza il metodo
setIsOfferPersonalized()
quando chiami launchBillingFlow
per comunicare
agli utenti che il prezzo di un articolo è stato personalizzato utilizzando il processo decisionale automatizzato.

Devi consultare l'articolo 6 (1) (ea) della direttiva sui diritti dei consumatori 2011/83/UE per stabilire se il prezzo che offri agli utenti è personalizzato.
setIsOfferPersonalized()
accetta un input booleano. Quando true
, l'interfaccia utente di Play
include l'informativa. Quando false
, l'interfaccia utente omette l'informativa. Il valore predefinito è false
.
Per ulteriori informazioni, consulta il Centro assistenza per i consumatori.
Allegare identificatori utente
Quando avvii il flusso di acquisto, la tua app può allegare qualsiasi identificatore utente in tuo possesso per l'utente che effettua l'acquisto utilizzando obfuscatedAccountId o obfuscatedProfileId. Un esempio di identificatore potrebbe essere una versione offuscata dell'accesso dell'utente nel tuo sistema. L'impostazione di questi parametri può aiutare Google a rilevare le frodi. Inoltre, può aiutarti a garantire che gli acquisti vengano attribuiti all'utente giusto, come descritto in Concessione di diritti agli utenti.
Rilevare ed elaborare gli acquisti
Il rilevamento e l'elaborazione di un acquisto descritti in questa sezione si applicano a tutti i tipi di acquisti, inclusi quelli fuori dall'app come il riscatto di promozioni.
La tua app rileva nuovi acquisti e acquisti in attesa completati in uno dei seguenti modi:
- Quando
onPurchasesUpdated
viene chiamato in seguito alla chiamatalaunchBillingFlow
della tua app (come descritto nella sezione precedente) o se la tua app è in esecuzione con una connessione attiva alla Libreria Fatturazione quando viene effettuato un acquisto al di fuori della tua app o un acquisto in attesa viene completato. Ad esempio, un membro del gruppo Famiglia approva un acquisto in attesa su un altro dispositivo. - Quando la tua app chiama queryPurchasesAsync per eseguire query sugli acquisti dell'utente.
Per il punto 1, onPurchasesUpdated
verrà chiamato automaticamente per gli acquisti nuovi o completati
finché la tua app è in esecuzione e ha una connessione attiva alla libreria
Fatturazione Google Play. Se la tua applicazione non è in esecuzione o non ha
una connessione attiva alla libreria Fatturazione Google Play, onPurchasesUpdated
non verrà
richiamato. Ricorda che è consigliabile che la tua app tenti di mantenere una connessione attiva
finché è in primo piano, in modo da ricevere aggiornamenti tempestivi
sugli acquisti.
Per il punto 2, devi chiamare BillingClient.queryPurchasesAsync() per assicurarti che la tua app elabori tutti gli acquisti. Ti consigliamo di farlo quando la tua app stabilisce correttamente una connessione con la Libreria Fatturazione Google Play (operazione consigliata quando l'app viene avviata o portata in primo piano, come descritto in inizializzare un BillingClient. Questa operazione può essere eseguita chiamando queryPurchasesAsync quando si riceve un risultato positivo per onServiceConnected. Seguire questo consiglio è fondamentale per gestire eventi e situazioni come:
- Problemi di rete durante l'acquisto: un utente può effettuare un acquisto
e ricevere la conferma da Google, ma il suo dispositivo perde
la connettività di rete prima che il dispositivo e la tua app ricevano la notifica
dell'acquisto tramite
PurchasesUpdatedListener
. - Più dispositivi: un utente potrebbe acquistare un articolo su un dispositivo e poi aspettarsi di vederlo quando cambia dispositivo.
- Gestione degli acquisti effettuati al di fuori della tua app: alcuni acquisti, come il riscatto di promozioni, possono essere effettuati al di fuori della tua app.
- Gestione delle transizioni di stato dell'acquisto: un utente può completare il pagamento di un acquisto IN ATTESA mentre l'applicazione non è in esecuzione e si aspetta di ricevere la conferma del completamento dell'acquisto quando apre l'app.
Una volta che l'app rileva un acquisto nuovo o completato, deve:
- Verifica l'acquisto.
- Concedere all'utente i contenuti per gli acquisti completati.
- Notifica all'utente.
- Comunica a Google che la tua app ha elaborato gli acquisti completati.
Questi passaggi sono descritti in dettaglio nelle sezioni seguenti, seguite da una sezione che riepiloga tutti i passaggi.
Verifica l'acquisto
La tua app deve sempre verificare la legittimità degli acquisti prima di concedere vantaggi a un utente. A questo scopo, segui le linee guida descritte in Verificare gli acquisti prima di concedere i diritti. Solo dopo aver verificato l'acquisto, l'app deve continuare a elaborare l'acquisto e concedere i diritti all'utente, come descritto nella sezione successiva.
Concedere il diritto all'utente
Una volta verificato un acquisto, l'app può continuare a concedere il diritto all'utente e inviargli una notifica. Prima di concedere il diritto, verifica che la tua
app controlli che lo stato dell'acquisto sia PURCHASED
. Se l'acquisto è in stato PENDING, la tua app deve comunicare all'utente che deve ancora completare le azioni per completare l'acquisto prima che venga concesso il diritto.
Concedi il diritto solo quando l'acquisto passa da PENDING a SUCCESS.
Per ulteriori informazioni, consulta Gestione delle transazioni in sospeso.
Se hai allegato identificatori utente all'acquisto, come descritto in Allegare identificatori utente, puoi recuperarli e utilizzarli per attribuirli all'utente corretto nel tuo sistema. Questa tecnica è utile per la riconciliazione degli acquisti quando la tua app potrebbe aver perso il contesto relativo all'utente per cui è stato effettuato un acquisto. Nota: gli acquisti effettuati al di fuori della tua app non avranno questi identificatori impostati. In questo caso, la tua app può concedere il diritto all'utente che ha eseguito l'accesso o chiedere <x0A>all'utente di selezionare un account preferito.
Per le prenotazioni, l'acquisto è in stato IN ATTESA prima del raggiungimento dell'orario di uscita. L'acquisto in preordine verrà completato al momento del rilascio e lo stato diventerà ACQUISTATO senza ulteriori azioni.
Notificare all'utente
Dopo aver concesso i diritti all'utente, l'app deve mostrare una notifica per confermare l'acquisto. Grazie alla notifica, l'utente non ha dubbi sul fatto che l'acquisto sia andato a buon fine, il che potrebbe portare l'utente a smettere di utilizzare la tua app, a contattare l'assistenza utenti o a lamentarsi sui social media. Tieni presente che la tua app potrebbe rilevare aggiornamenti degli acquisti in qualsiasi momento del ciclo di vita dell'applicazione. Ad esempio, un genitore approva un acquisto in attesa su un altro dispositivo, nel qual caso la tua app potrebbe voler ritardare la notifica all'utente a un momento opportuno. Alcuni esempi in cui un ritardo sarebbe appropriato sono:
- Durante la parte di azione di un gioco o le scene di intermezzo, la visualizzazione di un messaggio può distrarre l'utente. In questo caso, devi informare l'utente al termine della parte dell'azione.
- Durante il tutorial iniziale e le parti di configurazione dell'utente del gioco. Ad esempio, un utente potrebbe aver effettuato un acquisto al di fuori della tua app prima di installarla. Ti consigliamo di comunicare ai nuovi utenti il premio subito dopo l'apertura del gioco o durante la configurazione iniziale dell'utente. Se la tua app richiede all'utente di creare un account o di accedere prima di concedere il diritto all'utente, è consigliabile comunicare all'utente i passaggi da completare per richiedere l'acquisto. Questo è fondamentale perché gli acquisti vengono rimborsati dopo 3 giorni se la tua app non ha elaborato l'acquisto.
Quando invia una notifica all'utente in merito a un acquisto, Google Play consiglia i seguenti meccanismi:
- Mostra una finestra di dialogo in-app.
- Invia il messaggio a una casella di messaggi in-app, indicando chiaramente che è presente un nuovo messaggio nella casella di messaggi in-app.
- Utilizzare un messaggio di notifica del sistema operativo.
La notifica deve informare l'utente del vantaggio che ha ricevuto. Ad esempio, "Hai acquistato 100 gettoni d'oro!". Inoltre, se l'acquisto è il risultato di un vantaggio di un programma come Play Pass, la tua app lo comunica all'utente. Ad esempio, "Articoli ricevuti. Hai appena ricevuto 100 Gemme con Play Pass. Continua." Ogni programma può fornire indicazioni sul testo consigliato da mostrare agli utenti per comunicare i vantaggi.
Comunicare a Google che l'acquisto è stato elaborato
Dopo che l'app ha concesso i diritti all'utente e lo ha informato della transazione riuscita, deve comunicare a Google che l'acquisto è stato elaborato correttamente. A questo scopo, devi confermare l'acquisto entro tre giorni, in modo che l'acquisto non venga rimborsato automaticamente e il diritto non venga revocato. La procedura per confermare i diversi tipi di acquisti è descritta nelle sezioni seguenti.
Prodotti di consumo
Per i consumabili, se la tua app ha un backend sicuro, ti consigliamo di utilizzare
Purchases.products:consume
per consumare in modo affidabile gli acquisti. Assicurati che l'acquisto non sia già stato consumato controllando consumptionState
dal risultato della chiamata Purchases.products:get
. Se la tua app è solo client
senza backend, utilizza consumeAsync()
della
Libreria Fatturazione Google Play. Entrambi i metodi soddisfano il requisito di conferma e indicano che la tua app ha concesso il diritto all'utente.
Questi metodi consentono inoltre alla tua app di rendere disponibile per il riacquisto il prodotto a pagamento singolo corrispondente
al token di acquisto inserito. Con consumeAsync()
devi
anche passare un oggetto che implementa l'interfaccia
ConsumeResponseListener
. Questo oggetto gestisce il risultato dell'operazione di consumo. Puoi
eseguire l'override del metodo onConsumeResponse()
, che la
Libreria Fatturazione Google Play chiama al termine dell'operazione.
L'esempio seguente illustra l'utilizzo di un prodotto con la libreria Fatturazione Google Play utilizzando il token di acquisto associato:
Kotlin
val consumeParams = ConsumeParams.newBuilder() .setPurchaseToken(purchase.getPurchaseToken()) .build() val consumeResult = withContext(Dispatchers.IO) { client.consumePurchase(consumeParams) }
Java
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, ti
consigliamo di utilizzare Purchases.products:acknowledge
per confermare in modo affidabile gli
acquisti. Assicurati che l'acquisto non sia stato precedentemente riconosciuto
controllando acknowledgementState
dal risultato della chiamata a
Purchases.products:get
.
Se la tua app è solo client, utilizza BillingClient.acknowledgePurchase()
della
Libreria Fatturazione Google Play nella tua app. Prima di confermare un
acquisto, la tua app deve verificare se è già stato confermato utilizzando il
metodo isAcknowledged()
nella Libreria Fatturazione Google Play.
Il seguente esempio mostra come confermare un acquisto utilizzando la libreria Fatturazione Google Play:
Kotlin
val client: BillingClient = ... val acknowledgePurchaseResponseListener: AcknowledgePurchaseResponseListener = ... val acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder() .setPurchaseToken(purchase.purchaseToken) val ackPurchaseResult = withContext(Dispatchers.IO) { client.acknowledgePurchase(acknowledgePurchaseParams.build()) }
Java
BillingClient client = ... AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener = ... AcknowledgePurchaseParams acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder() .setPurchaseToken(purchase.getPurchaseToken()) .build(); client.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener);
Abbonamenti
Gli abbonamenti vengono gestiti in modo simile ai non consumabili. Se possibile, utilizza
Purchases.subscriptions.acknowledge
dall'API
Google Play Developer per confermare in modo affidabile l'acquisto dal tuo
backend sicuro. Verifica che l'acquisto non sia stato precedentemente riconosciuto
controllando acknowledgementState
nella risorsa di acquisto da
Purchases.subscriptions:get
. In caso contrario, puoi confermare un
abbonamento utilizzando BillingClient.acknowledgePurchase()
dalla
libreria Fatturazione Google Play dopo aver controllato isAcknowledged()
. Tutti
gli acquisti iniziali di abbonamenti devono essere riconosciuti. I rinnovi degli abbonamenti
non devono essere confermati. Per maggiori informazioni su quando è necessario confermare gli abbonamenti, consulta l'argomento Vendere abbonamenti.
Riepilogo
Il seguente snippet di codice mostra un riepilogo di questi passaggi.
Kotlin
fun handlePurchase(Purchase purchase) { // Purchase retrieved from BillingClient#queryPurchasesAsync or your // onPurchasesUpdated. 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 (delaying // notification if needed as discussed above). // Step 4: Notify Google the purchase was processed using the steps // discussed in the processing purchases section. }
Java
void handlePurchase(Purchase purchase) { // Purchase retrieved from BillingClient#queryPurchasesAsync or your // onPurchasesUpdated. 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 (delaying // notification if needed as discussed above). // Step 4: Notify Google the purchase was processed using the steps // discussed in the processing purchases section. }
Per verificare che la tua app abbia implementato correttamente questi passaggi, puoi seguire la guida ai test.
Gestire le transazioni in attesa
Google Play supporta le transazioni in attesa, ovvero le transazioni che richiedono uno o più passaggi aggiuntivi tra il momento in cui un utente avvia un acquisto e il momento in cui viene elaborato il metodo di pagamento per l'acquisto. La tua app non deve concedere il diritto a questi tipi di acquisti finché Google non ti comunica che l'addebito sul metodo di pagamento dell'utente è andato a buon fine.
Ad esempio, un utente può avviare una transazione scegliendo un negozio fisico in cui pagherà in contanti in un secondo momento. L'utente riceve un codice tramite notifica ed email. Quando l'utente arriva nel negozio fisico, può riscattare il codice con il cassiere e pagare in contanti. Google invia una notifica sia a te sia all'utente per comunicare che il pagamento è stato ricevuto. La tua app può quindi concedere il diritto all'utente.
Chiama enablePendingPurchases()
nell'ambito dell'inizializzazione di
BillingClient
per attivare le transazioni in attesa per la tua app. La tua app deve
attivare e supportare le transazioni in attesa per i prodotti a pagamento singolo. Prima di aggiungere
l'assistenza, assicurati di comprendere il ciclo di vita dell'acquisto per le transazioni
in attesa.
Quando la tua app riceve un nuovo acquisto, tramite il tuo
PurchasesUpdatedListener
o in seguito alla chiamata di
queryPurchasesAsync
, utilizza il metodo getPurchaseState()
per
determinare se lo stato dell'acquisto è PURCHASED
o PENDING
. Devi
concedere il diritto solo quando lo stato è PURCHASED
.
Se la tua app è in esecuzione e hai una connessione attiva alla libreria Fatturazione Play
quando l'utente completa l'acquisto, il tuo PurchasesUpdatedListener
viene
richiamato e PurchaseState
ora è PURCHASED
. A questo punto, la tua app può elaborare l'acquisto utilizzando il metodo standard per rilevare ed elaborare gli acquisti. La tua 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 client
real_time_developer_notifications riceve una notifica
ONE_TIME_PRODUCT_PURCHASED
o SUBSCRIPTION_PURCHASED
. Se l'acquisto viene annullato, riceverai una notifica ONE_TIME_PRODUCT_CANCELED
o SUBSCRIPTION_PENDING_PURCHASE_CANCELED
. Ciò può verificarsi se il tuo
cliente non completa il pagamento entro il periodo di tempo richiesto. Tieni presente che puoi
sempre utilizzare l'API Google Play Developer per controllare lo stato attuale di un
acquisto.
Gestire gli acquisti di più quantità
Supportato nelle versioni 4.0 e successive della libreria Google Play Billing, Google Play consente ai clienti di acquistare più quantità dello stesso prodotto a pagamento singolo in un'unica transazione specificando una quantità dal carrello degli acquisti. La tua app deve gestire gli acquisti di più quantità e concedere il diritto in base alla quantità di acquisto specificata.
Per rispettare gli acquisti di più quantità, la logica di provisioning dell'app deve verificare
la quantità di un articolo. Puoi accedere a un campo quantity
da una delle seguenti API:
getQuantity()
dalla Libreria Fatturazione Google Play.Purchases.products.quantity
dall'API Google Play Developer
Dopo aver aggiunto la logica per gestire gli acquisti di più quantità, devi attivare la funzionalità per più quantità per il prodotto corrispondente nella pagina di gestione dei prodotti a pagamento singolo in Google Play Developer Console.
Esegui query sulla configurazione di fatturazione dell'utente
getBillingConfigAsync()
indica il paese che l'utente utilizza per Google
Play.
Puoi eseguire query sulla configurazione di fatturazione dell'utente dopo aver creato un
BillingClient
. Il seguente snippet di codice descrive come effettuare una chiamata
a getBillingConfigAsync()
. Gestisci la risposta implementando
BillingConfigResponseListener
. Questo listener riceve aggiornamenti per tutte le query di configurazione
di fatturazione avviate dalla tua app.
Se il valore BillingResult
restituito non contiene errori, puoi controllare il campo
countryCode
nell'oggetto BillingConfig
per ottenere il paese Play
dell'utente.
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 } } });
Promemoria relativi all'abbandono del carrello nella home page di Google Play Giochi (attivati per impostazione predefinita)
Per gli sviluppatori di giochi che monetizzano tramite prodotti una tantum, un modo in cui le unità di gestione scorte (SKU) attive in Google Play Console possono essere vendute al di fuori della tua app è la funzionalità di promemoria di abbandono del carrello, che spinge gli utenti a completare gli acquisti abbandonati in precedenza mentre navigano nel Google Play Store. Questi acquisti vengono effettuati al di fuori dell'app, dalla home page di Google Play Giochi nel Google Play Store.
Questa funzionalità è abilitata per impostazione predefinita per aiutare gli utenti a riprendere la lettura da dove l'avevano interrotta e per aiutare gli sviluppatori a massimizzare le vendite. Tuttavia, puoi disattivare questa funzionalità per la tua app inviando il modulo di disattivazione del promemoria di abbandono del carrello. Per le best practice sulla gestione degli SKU in Google Play Console, consulta Creare un prodotto in-app.
Le seguenti immagini mostrano il promemoria di abbandono del carrello visualizzato sul Google Play Store:

