Informazioni sugli abbonamenti

Questo argomento descrive come gestire gli eventi del ciclo di vita degli abbonamenti, come i rinnovi e le scadenze. Descrive inoltre funzionalità di abbonamento aggiuntive, come l'offerta di promozioni e la possibilità per gli utenti di gestire i propri abbonamenti.

Se non hai configurato i prodotti in abbonamento per la tua app, consulta Creare e configurare i prodotti.

Panoramica degli abbonamenti

Un abbonamento rappresenta una serie di vantaggi a cui gli utenti possono accedere durante un periodo di tempo specificato. Ad esempio, un abbonamento può consentire all'utente di accedere a un servizio di streaming musicale.

Puoi avere più abbonamenti all'interno della stessa app, per rappresentare insiemi diversi di vantaggi, oppure diversi livelli di un singolo insieme di vantaggi (ad es. livelli "Argento" e "Oro").

Tramite i piani base e le offerte, puoi creare più configurazioni per lo stesso prodotto in abbonamento. Ad esempio, puoi creare un'offerta di lancio per gli utenti che non si sono mai abbonati alla tua app. Analogamente, puoi creare un'offerta di upgrade per gli utenti già abbonati.

Per una panoramica dettagliata dei prodotti in abbonamento, dei piani base e delle offerte, consulta la documentazione nel Centro assistenza Play Console.

Integrazione con piani prepagati

I piani prepagati non si rinnovano automaticamente alla scadenza. Per estendere il diritto di abbonamento senza interruzioni, l'utente deve ricaricare un piano prepagato per lo stesso abbonamento.

Per le ricariche, avvia il flusso di fatturazione come faresti con l'acquisto originale. Non è necessario indicare che un acquisto è una ricarica.

Le ricariche con piano prepagato utilizzano sempre la modalità di sostituzione CHARGE_FULL_PRICE e non è necessario impostarla esplicitamente. All'utente viene immediatamente addebitato un importo per un periodo di fatturazione completo e il diritto viene esteso per la durata specificata nella ricarica.

Dopo una ricarica, i seguenti campi nell'oggetto risultato Purchase vengono aggiornati in modo da riflettere l'acquisto di questa ricarica più recente:

  • ID ordine
  • Data/ora acquisto
  • Firma
  • Token per l'acquisto
  • Riconosciuti

I seguenti campi Purchase contengono sempre gli stessi dati trovati nell'acquisto originale:

  • Nome pacchetto
  • Stato acquisto
  • Prodotti
  • Rinnovo automatico

Conferma dell'acquisto prepagato

Come per gli abbonamenti con rinnovo automatico, devi confermare i piani prepagati dopo l'acquisto. Sia l'acquisto iniziale che le eventuali ricariche devono essere confermati. Per ulteriori informazioni, consulta la sezione Elaborazione degli acquisti.

Data la possibilità che un piano prepagato di breve durata, è importante confermare l'acquisto il prima possibile.

I piani prepagati con una durata di una settimana o più devono essere confermati entro tre giorni.

I piani prepagati con una durata inferiore a una settimana devono essere confermati entro la metà della durata del piano. Ad esempio, gli sviluppatori hanno 1 giorno e mezzo di giorni per accettare un piano prepagato di 3 giorni.

Utilizza i link diretti per consentire agli utenti di gestire un abbonamento

La tua app deve includere un link in una schermata delle impostazioni o delle preferenze che consenta agli utenti di gestire i propri abbonamenti, che puoi incorporare nel aspetto naturale della tua app.

Puoi includere un link diretto dalla tua app al Centro abbonamenti Google Play per gli abbonamenti non scaduti, che puoi determinare utilizzando il campo subscriptionState della risorsa abbonamento. Sulla base di questi dati, esistono diversi modi per aggiungere link diretti al Centro abbonamenti del Play Store.

Utilizza il seguente URL per indirizzare gli utenti alla pagina che mostra tutti i loro abbonamenti, come mostrato nelle figure 1 e 2:

https://play.google.com/store/account/subscriptions
La schermata Abbonamenti del Play Store mostra lo stato di tutti gli abbonamenti fatturati da Google Play di un utente.
Figura 1. La schermata Abbonamenti del Play Store mostra lo stato di tutti gli abbonamenti fatturati da Google Play di un utente.


Tocca un abbonamento per visualizzare ulteriori dettagli.
Figura 2. Tocca un abbonamento per visualizzare ulteriori dettagli.

Questo link diretto può essere utile per aiutare un utente a ripristinare un abbonamento annullato dal Centro abbonamenti del Play Store.

Per creare un collegamento diretto alla pagina di gestione di un abbonamento non scaduto, indica il nome del pacchetto e i productId associati all'abbonamento acquistato. Per determinare in modo programmatico il valore productId per un abbonamento esistente, esegui una query sul backend dell'app o chiama BillingClient.queryPurchasesAsync() per visualizzare un elenco di abbonamenti associati a un determinato utente. Ogni abbonamento contiene il valore productId corrispondente nelle informazioni sullo stato dell'abbonamento. Ogni oggetto SubscriptionPurchaseLineItem associato all'acquisto di un abbonamento contiene il valore productId associato all'abbonamento che l'utente ha acquistato in quell'elemento pubblicitario.

Utilizza il seguente URL per indirizzare gli utenti a una specifica schermata di gestione degli abbonamenti, sostituendo "your-sub-product-id" e "your-app-package" rispettivamente con i productId e il nome del pacchetto dell'app:

https://play.google.com/store/account/subscriptions?sku=your-sub-product-id&package=your-app-package

L'utente è quindi in grado di gestire i propri metodi di pagamento e accedere a funzionalità tra cui annullamento, nuovo abbonamento e pausa.

Consenti agli utenti di eseguire l'upgrade, il downgrade o modificare il proprio abbonamento

Puoi fornire agli abbonati esistenti varie opzioni per modificare il loro piano di abbonamento in modo da soddisfare meglio le loro esigenze:

  • Se vendi più livelli di abbonamento, ad esempio abbonamenti "base" e "premium", puoi consentire agli utenti di passare da un livello all'altro acquistando un piano base o un'offerta di abbonamento diversi.
  • Puoi consentire agli utenti di modificare il periodo di fatturazione corrente, ad esempio passando da un piano mensile a un piano annuale.
  • Puoi anche consentire agli utenti di passare dal piano con rinnovo automatico a quello prepagato e viceversa.

Puoi incoraggiare qualsiasi di queste modifiche fornendo offerte di abbonamento che offrano uno sconto agli utenti idonei. Ad esempio, potresti creare un'offerta con uno sconto del 50% sul primo anno quando passi da un piano mensile a un piano annuale e limitarla agli utenti abbonati a un piano mensile che non hanno acquistato questa offerta. Ulteriori informazioni sui criteri di idoneità delle offerte sono disponibili nel Centro assistenza

La figura 3 mostra un esempio di app con tre diversi piani:

Questa app ha tre livelli di abbonamento...
Figura 3. Questa app ha tre livelli di abbonamento.

L'app potrebbe mostrare una schermata simile alla Figura 3, che offre agli utenti la possibilità di cambiare l'abbonamento. In tutti i casi, dovrebbe essere chiaro agli utenti qual è il loro piano di abbonamento attuale e quali opzioni hanno a disposizione per modificarlo.

Quando gli utenti decidono di eseguire l'upgrade, il downgrade o modificare l'abbonamento, devi specificare una modalità di sostituzione che determina come viene applicato il valore proporzionale del periodo di fatturazione a pagamento corrente e quando si verifica un'eventuale modifica del diritto.

Modalità di sostituzione

La tabella seguente elenca le modalità di sostituzione disponibili e gli esempi di utilizzo.

Modalità sostituzione

Descrizione

Esempio di utilizzo

WITH_TIME_PRORATION

L'upgrade o il downgrade dell'abbonamento viene eseguito immediatamente. L'eventuale tempo rimanente viene modificato in base alla differenza di prezzo e accreditato al nuovo abbonamento posticipando la data di fatturazione successiva. Questo è il comportamento predefinito.

Esegui l'upgrade a un livello più costoso senza alcun pagamento aggiuntivo immediato.

CHARGE_PRORATED_PRICE

L'upgrade dell'abbonamento viene eseguito immediatamente e il ciclo di fatturazione rimane invariato. La differenza di prezzo per il periodo rimanente viene quindi addebitata all'utente.

Nota: questa opzione è disponibile solo per un upgrade di un abbonamento, in cui aumenta il prezzo per unità di tempo.

Esegui l'upgrade a un livello più costoso senza modificare la data di fatturazione.

CHARGE_FULL_PRICE

L'upgrade o il downgrade dell'abbonamento viene eseguito immediatamente e all'utente viene addebitato immediatamente il prezzo intero per il nuovo diritto. Il valore rimanente dell'abbonamento precedente viene riportato per lo stesso diritto o ripartito proporzionalmente nel tempo se si passa a un diritto diverso.

Nota: se il nuovo abbonamento prevede una prova senza costi o un'offerta di lancio, all'utente vengono addebitati 0 $o il prezzo dell'offerta di lancio, a seconda di quale delle due opzioni si applica, al momento dell'upgrade o del downgrade.

Esegui l'upgrade da un periodo di fatturazione più breve a uno più lungo.

WITHOUT_PRORATION

L'upgrade o il downgrade dell'abbonamento viene eseguito immediatamente e il nuovo prezzo viene addebitato al momento del rinnovo. Il ciclo di fatturazione rimane lo stesso.

Esegui l'upgrade a un livello di abbonamento superiore mantenendo l'eventuale periodo senza costi rimanente.

DEFERRED

L'upgrade o il downgrade dell'abbonamento viene eseguito solo al rinnovo dell'abbonamento, ma il nuovo acquisto viene emesso immediatamente con una data di inizio futura per il nuovo diritto, in modo che lo sviluppatore possa consentire agli utenti di apportare ulteriori modifiche, se lo desiderano. Ad esempio, possono ripristinare il piano originale o avviare una nuova modifica del piano differito.

Esegui il downgrade a un livello meno costoso.

Per ulteriori informazioni sulle diverse applicazioni di upsell e callback di offerte di upgrade o downgrade, leggi la guida alle offerte e alle promozioni.

Impostare la modalità sostitutiva per un acquisto

Puoi utilizzare modalità di sostituzione diverse per tipi diversi di transizioni degli abbonamenti, in base alle tue preferenze e alla logica di business. Questa sezione spiega come impostare una modalità sostitutiva per una modifica a un abbonamento e le limitazioni applicabili.

Riabbonati o cambia piano all'interno dello stesso abbonamento

Puoi specificare una modalità di sostituzione predefinita in Google Play Console. Questa impostazione ti consente di scegliere quando effettuare addebiti agli abbonati attuali se acquistano un'offerta o un piano base diverso per lo stesso abbonamento o se si abbonano di nuovo dopo un annullamento. Le opzioni disponibili sono Addebito immediato, equivalente a CHARGE_FULL_PRICE, e Addebito alla data di fatturazione successiva, equivalente a WITHOUT_PRORATION. Queste sono le uniche modalità di sostituzione pertinenti se si cambia piano base nello stesso abbonamento.

Ad esempio, se implementi un'offerta di riattivazione per lo stesso piano dopo l'annullamento da parte dell'utente, ma prima della fine dell'abbonamento, puoi elaborare il nuovo acquisto come un normale acquisto senza indicare alcun valore in SubscriptionUpdateParams. Il sistema utilizza la modalità di sostituzione predefinita che hai configurato nell'abbonamento e gestisce automaticamente la transizione del piano dall'acquisto precedente a quello nuovo.

Cambia piano tra abbonamenti o sostituisci la modalità di sostituzione predefinita

Se l'utente cambia prodotti di abbonamento, acquista un abbonamento diverso o se vuoi sostituire la modalità di sostituzione predefinita per qualsiasi motivo, devi specificare la tariffa proporzionale in fase di runtime come parte dei parametri del flusso di acquisto.

Per fornire correttamente SubscriptionUpdateParams come parte della configurazione del flusso di acquisto di runtime, tieni presente le seguenti limitazioni:

  • Quando esegui l'upgrade, il downgrade o il passaggio dello stesso abbonamento a un piano prepagato da un piano prepagato o con rinnovo automatico, l'unica modalità proporzionale consentita è CHARGE_FULL_PRICE. Se specifichi qualsiasi altra modalità proporzionale, l'acquisto non va a buon fine e viene mostrato un errore all'utente.
  • Quando passi da un piano all'interno dello stesso abbonamento a un piano con rinnovo automatico da un piano prepagato o con rinnovo automatico, le modalità di proporzionalità valide sono CHARGE_FULL_PRICE e WITHOUT_PRORATION. Se specifichi qualsiasi altra modalità proporzionale, l'acquisto non va a buon fine e viene mostrato un errore all'utente.

Esempi e comportamenti di sostituzione

Per capire come funziona ogni modalità di ripartizione, considera il seguente scenario:

Samwise ha un abbonamento ai contenuti online dall'app Country Gardener. Ha un abbonamento mensile alla versione di Tier 1 dei contenuti, che è di solo testo. Questo abbonamento costa 2$al mese e si rinnova il primo giorno del mese.

Il 15 aprile, Samwise ha scelto di eseguire l'upgrade alla versione annuale dell'abbonamento Tier 2, che include aggiornamenti video e costa 36$all'anno.

Durante l'upgrade dell'abbonamento, lo sviluppatore seleziona una modalità proporzionale. Il seguente elenco descrive in che modo ogni modalità proporzionale influisce sull'abbonamento di Samwise:

WITH_TIME_PRORATION

L'abbonamento Tier 1 di Samwise scade immediatamente. Poiché ha pagato per un mese intero (1-30 aprile), ma ha eseguito l'upgrade a metà del periodo di abbonamento, al nuovo abbonamento viene applicata metà dell'abbonamento di un mese (1 $). Tuttavia, poiché il nuovo abbonamento costa 36 $all'anno, il saldo del credito di 1 $paga solo per 10 giorni (16-25 aprile); quindi il 26 aprile gli vengono addebitati 36 $per un nuovo abbonamento e altri 36 $il 26 aprile di ogni anno successivo.

Devi chiamare PurchasesUpdatedListener dell'app nel momento in cui è andato a buon fine l'acquisto e potrai recuperare il nuovo acquisto nell'ambito di una chiamata a queryPurchasesAsync(). Il tuo backend riceve immediatamente una SUBSCRIPTION_PURCHASEDNotifica in tempo reale per lo sviluppatore.

CHARGE_PRORATED_PRICE

Questa modalità può essere utilizzata perché il prezzo dell'abbonamento Tier 2 per unità di tempo (36 $/anno = 3 $/mese) è superiore al prezzo dell'abbonamento Tier 1 per unità di tempo (2 $/mese). L'abbonamento Tier 1 di Samwise scade immediatamente. Poiché ha pagato per un mese intero, ma ne ha utilizzato solo metà, pertanto al nuovo abbonamento viene applicata metà dell'abbonamento del mese (1 $). Tuttavia, poiché il nuovo abbonamento costa 36 $all'anno, i 15 giorni rimanenti costano 1,50 $; quindi gli viene addebitata la differenza di 0,50 $per il nuovo abbonamento. Il 1° maggio, a Samwise, vengono addebitati 36 $per il nuovo livello di abbonamento e altri 36 $il 1° maggio di ogni anno successivo.

Devi chiamare PurchasesUpdatedListener dell'app nel momento in cui è andato a buon fine l'acquisto e potrai recuperare il nuovo acquisto nell'ambito di una chiamata queryPurchasesAsync(). Il tuo backend riceve immediatamente una SUBSCRIPTION_PURCHASEDNotifica in tempo reale per lo sviluppatore.

WITHOUT_PRORATION

L'abbonamento Tier 1 di Samwise viene immediatamente aggiornato al Tier 2 senza costi aggiuntivi e il 1° maggio gli vengono addebitati 36 $per il nuovo livello di abbonamento e altri 36 $il 1° maggio di ogni anno successivo.

Devi chiamare PurchasesUpdatedListener dell'app nel momento in cui è andato a buon fine l'acquisto e potrai recuperare il nuovo acquisto nell'ambito di una chiamata queryPurchasesAsync(). Il tuo backend riceve immediatamente una SUBSCRIPTION_PURCHASEDNotifica in tempo reale per lo sviluppatore.

DEFERRED

L'abbonamento Tier 1 di Samwise sarà valido fino alla scadenza del 30 aprile. Il 1° maggio entra in vigore l'abbonamento Tier 2 e a Samwise viene addebitato un importo di 36 $per il suo nuovo livello di abbonamento.

Devi chiamare PurchasesUpdatedListener dell'app nel momento in cui è andato a buon fine l'acquisto e potrai recuperare il nuovo acquisto nell'ambito di una chiamata queryPurchasesAsync(). Il tuo backend riceve immediatamente una SUBSCRIPTION_PURCHASEDNotifica in tempo reale per lo sviluppatore. Devi elaborare l'acquisto nello stesso modo in cui procederesti a qualsiasi altro nuovo acquisto. In particolare, assicurati di confermare il nuovo acquisto. Tieni presente che il valore startTime del nuovo abbonamento viene completato nel momento in cui la sostituzione entra in vigore, che si verifica alla scadenza del vecchio abbonamento. A quel punto, riceverai un SUBSCRIPTION_RENEWED RTDN per il nuovo piano di abbonamento. Scopri di più sul comportamento di ReplacementMode.DEFERRED in Gestire la sostituzione differita.

CHARGE_FULL_PRICE

L'abbonamento Tier 1 di Samwise scade immediatamente. Il suo abbonamento Tier 2 inizia oggi e gli vengono addebitati $36. Poiché ha pagato per un mese intero, ma ne ha utilizzato solo metà, al nuovo abbonamento viene applicata metà dell'abbonamento mensile ($1). Poiché il nuovo abbonamento costa 36 $all'anno, riceverebbe 1/36 dell'anno in aggiunta al periodo di abbonamento (circa 10 giorni). Pertanto, il prossimo addebito di Samwise a partire da oggi sarà di 36 $tra 1 anno e 10 giorni. Successivamente, gli verranno addebitati 36 $all'anno successivo.

Quando scegli una modalità proporzionale, assicurati di rivedere i nostri consigli sulla sostituzione.

Attivare le modifiche all'abbonamento in-app

La tua app può offrire agli utenti un upgrade o un downgrade seguendo gli stessi passaggi previsti per l'avvio di un flusso di acquisto. Tuttavia, quando esegui l'upgrade o il downgrade, devi fornire i dettagli dell'abbonamento attuale, dell'abbonamento futuro (con upgrade o downgrade) e la modalità sostitutiva da utilizzare, come mostrato nell'esempio seguente:

Kotlin

val offerToken = productDetails
        .getSubscriptionOfferDetails(selectedOfferIndex)
        .getOfferToken()

val billingParams = BillingFlowParams.newBuilder().setProductDetailsParamsList(
       listOf(
           BillingFlowParams.ProductDetailsParams.newBuilder()
               .setProductDetails(productDetails)
               .setOfferToken(offerToken)
               .build()
       )
       ).setSubscriptionUpdateParams(
           BillingFlowParams.SubscriptionUpdateParams.newBuilder()
               .setOldPurchaseToken("old_purchase_token")
               .setSubscriptionReplacementMode(
                 BillingFlowParams.ReplacementMode.CHARGE_FULL_PRICE
               )
               .build()
       ).build()

billingClient.launchBillingFlow(
    activity,
    billingParams
   )
// ...

Java

String offerToken = productDetails
    .getSubscriptionOfferDetails(selectedOfferIndex)
    .getOfferToken();

BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(
        ImmuableList.of(
            ProductDetailsParams.newBuilder()
                // fetched via queryProductDetailsAsync
                .setProductDetails(productDetails)
                // offerToken can be found in
                // ProductDetails=>SubscriptionOfferDetails
                .setOfferToken(offerToken)
                .build()))
    .setSubscriptionUpdateParams(
        SubscriptionUpdateParams.newBuilder()
            // purchaseToken can be found in Purchase#getPurchaseToken
            .setOldPurchaseToken("old_purchase_token")
            .setSubscriptionReplacementMode(ReplacementMode.CHARGE_FULL_PRICE)
            .build())
    .build();

BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);
// ...

Consigli sulla sostituzione

La tabella seguente mostra diversi scenari di distribuzione proporzionale e mostra cosa consigliamo per ogni scenario:

Scenario Modalità di sostituzione consigliata Risultato
Upgrade a un livello più costoso CHARGE_PRORATED_PRICE L'utente riceve l'accesso immediatamente, mantenendo lo stesso periodo di fatturazione.
Eseguire il downgrade a un livello meno costoso DEFERRED L'utente ha già pagato per il livello più costoso, quindi manterrà l'accesso fino alla data di fatturazione successiva.
Eseguire l'upgrade durante il periodo di prova senza costi e mantenere la prova WITHOUT_PRORATION L'utente mantiene l'accesso alla prova senza costi, ma esegue l'upgrade a un livello superiore per il resto della prova.
Upgrade durante il periodo di prova senza costi: termine dell'accesso alla prova senza costi CHARGE_PRORATED_PRICE L'utente riceve immediatamente l'accesso al nuovo livello, ma non dispone più di una prova senza costi.

Gestire gli acquisti per il cambio di abbonamento

Le modifiche al piano sono nuovi acquisti per tutti i termini e gli scopi e devono essere elaborati e confermati come tali una volta che il flusso di fatturazione è stato completato correttamente. Oltre a elaborare correttamente il nuovo acquisto, devi ritirare l'acquisto sostituito.

Il comportamento in-app è lo stesso di qualsiasi nuovo acquisto. La tua app riceve il risultato del nuovo acquisto in PurchasesUpdatedListener e il nuovo acquisto è disponibile in queryPurchasesAsync.

L'API Google Play Developer restituisce un linkedPurchaseToken nella risorsa abbonamento quando un acquisto sostituisce un acquisto esistente. Assicurati di invalidare il token fornito in linkedPurchaseToken per assicurarti che il token precedente non venga utilizzato per accedere ai tuoi servizi. Per informazioni sulla gestione degli acquisti di upgrade e downgrade, consulta Upgrade, downgrade e nuove registrazioni.

Quando ricevi il nuovo token di acquisto, segui la stessa procedura di verifica della verifica di un nuovo token di acquisto. Assicurati di confermare questi acquisti con BillingClient.acknowledgePurchase() dalla Libreria Fatturazione Google Play o con Purchases.subscriptions:acknowledge dall'API Google Play Developer.

Sostituzione differita del manico

La modalità di sostituzione differita ti consente di consentire a un utente di utilizzare il diritto rimanente nel piano precedente prima di iniziare il nuovo piano.

Quando utilizzi SostituzioneMode.DEFERRED per un nuovo acquisto, queryPurchasesAsync() restituisce un nuovo token di acquisto dopo il flusso di acquisto che rimane associato al vecchio prodotto fino a quando la sostituzione differita non ha luogo alla data di rinnovo successiva, dopodiché il nuovo prodotto viene restituito.

In passato, potevi usufruire di questa esperienza utente con la versione deprecata ProrationMode.DEFERRED, ma ProrationMode.DEFERRED è deprecata con la Libreria Fatturazione Play 6. Consulta la seguente tabella per capire dove è diverso il comportamento:

Ora

ProrationMode.DEFERRED (deprecato)

SostituzioneMode.DEFERRED

Subito dopo la riuscita del flusso di acquisto (app)

PurchasesUpdatedListener viene richiamato dopo l'acquisto e indica se l'upgrade o il downgrade è andato a buon fine.

Il diritto al piano precedente continuerà fino alla data di rinnovo successiva. Per garantire che l'app dia il diritto corretto, queryPurchasesAsync() restituisce un oggetto Purchase con il token di acquisto originale e il diritto originale fino alla sostituzione.

Il nuovo token di acquisto non viene visualizzato, pertanto al momento non può essere elaborato.

PurchasesUpdatedListener viene richiamato dopo l'acquisto e indica se l'upgrade o il downgrade è andato a buon fine.

queryPurchasesAsync() restituisce immediatamente l'acquisto con il nuovo token di acquisto e il diritto originale associato.

Il nuovo token di acquisto viene visualizzato, pertanto a questo punto dovrebbe essere elaborato, in considerazione dei tempi di sostituzione.

Subito dopo la riuscita del flusso di acquisto (backend)

L'RTDN SUBSCRIPTION_PURCHASED non viene inviato dopo il flusso di acquisto. Il backend non è ancora a conoscenza del nuovo acquisto.

L'RTDN SUBSCRIPTION_PURCHASED con il vecchio product_id viene inviato subito dopo il flusso di acquisto per il nuovo token di acquisto.

La chiamata al metodo purchases.subscriptionsv2.get con il nuovo token di acquisto restituisce un acquisto avente un valore "startTime" che indica l'ora di acquisto con due elementi pubblicitari:

  • Uno che rappresenta il diritto vecchio e ha un valore "expiryTime" nel futuro. Il vecchio diritto non verrà rinnovato e avrà un diritto DeferredItemSostituzione contenente il prodotto del nuovo diritto. Indica una sostituzione in attesa del diritto precedente alla sua scadenza.
  • Uno che rappresenta il diritto nuovo acquistato. Non è impostato alcun valore per "expiryTime".

SUBSCRIPTION_EXPIRED inviato per il token di acquisto precedente. Quando chiami il metodo purchases.subscriptionsv2.get con il vecchio token di acquisto, questo risulta scaduto (il diritto del piano precedente viene trasferito al nuovo acquisto per il tempo rimanente).

In caso di sostituzione: primo rinnovo dopo il flusso di acquisto (app)

queryPurchasesAsync() restituisce un nuovo oggetto Purchase con il diritto e il token di acquisto new.

Il nuovo token di acquisto viene ora visualizzato, quindi dovrebbe essere elaborato.

queryPurchasesAsync() restituisce immediatamente l'acquisto con il nuovo token di acquisto e il nuovo diritto associato.

Il nuovo acquisto dovrebbe essere stato già elaborato una volta che il flusso di acquisto è andato a buon fine, quindi l'app non deve intraprendere alcuna azione speciale oltre ad assicurarsi che venga concesso il diritto corretto.

In caso di sostituzione: primo rinnovo dopo il flusso di acquisto (backend)

Ora è possibile elaborare e confermare il nuovo acquisto quando viene inviato il primo RTDN SUBSCRIPTION_RENEWED.

Il linkedPurchaseToken nella risorsa di abbonamento può essere utilizzato per determinare quale utente nel backend dell'abbonamento, se applicabile, deve essere aggiornato con il nuovo diritto.

Il nuovo acquisto è stato elaborato e confermato quando l'RTDN SUBSCRIPTION_PURCHASED è stato inviato per il nuovo token di acquisto e registrato come "startTime".

Con SostituzioneMode.DEFERRED, i primi rinnovi seguono il comportamento standard di qualsiasi altro rinnovo e non è necessario gestire una logica speciale per le sostituzioni quando si verifica questo evento.

Quando chiami il metodo purchases.subscriptionsv2.get con il nuovo token di acquisto, viene restituito un acquisto con due elementi pubblicitari:

  • Uno che rappresenta il diritto vecchio, con un valore "expiryTime" nel passato e nessun valore impostato per DeferredItemSostituzione.
  • Uno che rappresenta il diritto new, con un valore "expiryTime" nel futuro e il flag auto_renewing_enabled attivo.

SostituzioneMode.DEFERRED deve essere utilizzato d'ora in poi anziché il ritiro ProrationMode.DEFERRED, in quanto presenta lo stesso comportamento per quanto riguarda le modifiche dei diritti, ma offre un modo di gestire l'acquisto in modo più coerente con i comportamenti degli altri nuovi acquisti.

Gestione clienti

Grazie alle Notifiche in tempo reale per lo sviluppatore, puoi rilevare in tempo reale quando un utente decide di annullare l'abbonamento. Quando un utente annulla l'abbonamento, ma prima che il suo abbonamento sia scaduto, puoi inviargli notifiche push o messaggi in-app per chiedergli di riabbonarsi.

Dopo che un utente ha annullato l'abbonamento, puoi provare a riconquistarlo nella tua app o tramite il Play Store. La tabella seguente descrive diversi scenari di abbonamento con le azioni di callback associate e i requisiti dell'app.

Prima della scadenza dell'abbonamento Dopo la scadenza dell'abbonamento
In-app Nel Play Store In-app Nel Play Store
Funzionalità di riattivazione Abbonamento in-app Ripristina Abbonamento in-app Riabbonati
L'utente esegue il flusso di pagamento No
L'abbonamento utente rimane associato allo stesso SKU L'utente può registrarsi per uno stesso SKU o per un altro SKU L'utente può registrarsi per uno stesso SKU o per un altro SKU
Crea un nuovo token di acquisto No
Attivata per impostazione predefinita No Sì, è richiesto l'assistenza per tutti gli sviluppatori No

App senza Libreria Fatturazione 2.0 o versioni successive: no

App con Libreria Fatturazione 2.0 o versioni successive: sì. Gli sviluppatori possono disattivare questa opzione nella console.

Quando viene addebitato un importo all'utente

Se utilizzi lo stesso SKU: fine del periodo di fatturazione corrente.

Se utilizzi uno SKU diverso: dipende dalla modalità proporzionale.

Fine del periodo di fatturazione corrente Immediatamente Immediatamente
Implementazione richiesta Fornisci una UI per la nuova registrazione nell'app

Rileva la modifica dello stato dell'abbonamento

Link diretto al Play Store

Fornisci una UI per la nuova registrazione nell'app Gestire gli acquisti fuori app

Prima della scadenza dell'abbonamento - in-app

Per gli abbonamenti annullati, ma non ancora scaduti, puoi consentire agli abbonati di ripristinare il loro abbonamento all'interno della tua app applicando lo stesso flusso di acquisto di prodotti in-app utilizzato per i nuovi abbonati. Assicurati che la UI rifletta che l'utente abbia un abbonamento esistente. Ad esempio, potresti voler visualizzare la data di scadenza attuale e il prezzo ricorrente dell'utente con un pulsante Riattiva.

Nella maggior parte dei casi, vorrai offrire all'utente lo stesso prezzo e SKU a cui era già abbonato, come indicato di seguito:

  • Avvia un nuovo abbonamento con lo stesso SKU.
  • Il nuovo abbonamento sostituisce quello precedente e si rinnova alla stessa data di scadenza. L'abbonamento precedente viene immediatamente contrassegnato come scaduto.
  • Ad esempio, Achille ha un abbonamento all'app Music di esempio e scade il 1° agosto. Il 10 luglio, si abbona di nuovo all'abbonamento di un mese allo stesso prezzo al mese. Il nuovo abbonamento viene ripartito proporzionalmente con il credito residuo, è attivo immediatamente e verrà rinnovato il 1° agosto.

Se vuoi offrire un prezzo diverso, ad esempio una nuova prova senza costi o uno sconto per la riattivazione, puoi offrire uno SKU diverso all'utente:

  • Avvia un upgrade o un downgrade con lo SKU diverso utilizzando la modalità di sostituzione WITHOUT_PRORATION.
  • Il nuovo abbonamento sostituisce quello precedente e si rinnova alla stessa data di scadenza. All'utente viene addebitato all'utente il prezzo del nuovo SKU, inclusi gli eventuali prezzi di lancio, alla data di scadenza originale. Se l'abbonamento precedente è stato creato utilizzando un ID account offuscato, lo stesso ID deve essere trasmesso a BillingFlowParams per gli upgrade e i downgrade.
  • Ad esempio, Achille ha un abbonamento all'app Music di esempio e scade il 1° agosto. Il 10 luglio si abbona di nuovo a un abbonamento annuale a un prezzo di lancio. Il nuovo abbonamento è immediatamente attivo e all'utente viene addebitato il prezzo di lancio il 1° agosto.
  • Se decidi di includere una prova senza costi o un prezzo di lancio nello SKU di callback, assicurati che l'utente sia idoneo deselezionando la casella Consenti una prova senza costi per app in Google Play Console, così l'utente non potrà usufruire di una prova senza costi per app.

Quando ricevi il token di acquisto, elabora l'acquisto come faresti per un nuovo abbonamento. Inoltre, l'API Google Play Developer restituisce un valore linkedPurchaseToken nella risorsa abbonamento. Assicurati di annullare la validità del token fornito in linkedPurchaseToken per assicurarti che il token precedente non venga utilizzato per accedere ai tuoi servizi.

Prima della scadenza dell'abbonamento - nel Play Store

Mentre l'abbonamento è annullato, ma è ancora attivo, gli utenti possono ripristinarlo nel Centro abbonamenti Google Play facendo clic su Riabbonati (in precedenza Ripristina). In questo modo vengono conservati lo stesso abbonamento e lo stesso token di acquisto.

sezione Abbonamenti dell'app Google Play Store che mostra un abbonamento annullato con un pulsante Riabbonati
Figura 8. Account > Abbonamenti nell'app Google Play Store che mostra un abbonamento annullato con un pulsante Riabbonati.

Per ulteriori informazioni sul ripristino degli abbonamenti, consulta la sezione Ripristino.

Dopo la scadenza dell'abbonamento - in-app

Puoi consentire agli abbonati scaduti di riabbonarsi all'interno della tua app applicando lo stesso flusso di acquisto di prodotti in-app utilizzato per i nuovi abbonati. Tieni presente quanto segue:

  • Per offrire agli utenti uno sconto, ti consigliamo di offrire un ID prodotto con prezzi speciali per il tuo abbonamento, chiamato anche SKU di riattivazione. Puoi fornire l'offerta nella tua app o informare l'utente dell'offerta al di fuori dell'app, ad esempio via email.
  • Per avviare un abbonamento di riattivazione, avvia il flusso di acquisto nella tua app Android utilizzando la Libreria Fatturazione Google Play. Si tratta della stessa procedura di un nuovo abbonamento, ma puoi determinare lo SKU disponibile per l'utente.
  • Se decidi di includere una prova senza costi o un prezzo di lancio nello SKU Wi-Fi, assicurati che l'utente sia idoneo deselezionando la casella Consenti una prova senza costi per app in Google Play Console. In questo modo l'utente non potrà usufruire di una prova senza costi per app.
  • Se l'utente si abbona di nuovo allo stesso SKU, non sarà più idoneo per le prove senza costi o il prezzo di lancio. Assicurati che la tua UI rifletta questa condizione.

Quando ricevi il token di acquisto, elabora l'acquisto come faresti per un nuovo abbonamento. Non riceverai un linkedPurchaseToken nella risorsa di abbonamento.

Dopo la scadenza dell'abbonamento - nel Play Store

Se l'opzione è attivata, gli utenti possono riabbonarsi allo stesso SKU fino a un anno dopo la scadenza facendo clic su Riabbonati nel centro abbonamenti Google Play. In questo modo vengono generati un nuovo abbonamento e un nuovo token di acquisto.

sezione degli abbonamenti nell'app Google Play Store che mostra un abbonamento annullato e scaduto con pulsanti Riabbonati e Rimuovi
Figura 9. Account > Abbonamenti nell'app Google Play Store che mostra un abbonamento annullato e scaduto con i pulsanti Riabbonati e Rimuovi.

La riabbonarsi è considerata un acquisto fuori app, quindi segui le best practice per gestire gli acquisti effettuati al di fuori dell'app.

Promuovi il tuo abbonamento

Puoi creare codici promozionali per offrire a utenti selezionati una prova senza costi estesa di un abbonamento esistente. Per scoprire di più, consulta la sezione Codici promozionali.

Per le prove senza costi, Google Play verifica che l'utente disponga di un metodo di pagamento valido prima di iniziare la prova senza costi. Alcuni utenti potrebbero vedere questa verifica come una sospensione o un addebito sul loro metodo di pagamento. Questa trattenuta o questo addebito è temporanea e viene successivamente annullata o rimborsata.

Al termine del periodo di prova, l'intero importo dell'abbonamento viene addebitato sul metodo di pagamento dell'utente.

Se l'utente annulla un abbonamento in qualsiasi momento durante la prova senza costi, l'abbonamento rimane attivo fino al termine della prova e non gli verrà addebitato alcun importo al termine del periodo di prova senza costi.

Annullare, rimborsare o revocare

Puoi utilizzare l'API Google Play Developer per annullare rimborsare o revocare un abbonamento. Questa funzionalità è disponibile anche in Google Play Console.

  • Annulla: gli utenti possono annullare un abbonamento su Google Play. Puoi anche fornire agli utenti un'opzione di annullamento nella tua app o sul tuo sito web. La tua app deve gestire questi annullamenti come descritto nella sezione Annullamenti.
  • Rimborso: se rimborsi, l'utente può continuare a utilizzare l'abbonamento. I rimborsi possono essere utilizzati se, ad esempio, si è verificato un errore tecnico che ha impedito all'utente di accedere al tuo prodotto, ma l'errore è stato risolto. Tieni presente che per rimborsare un importo superiore al pagamento più recente o se vuoi emettere un rimborso parziale, devi utilizzare Google Play Console.
  • Revoca: quando revochi l'abbonamento, l'utente perde immediatamente l'accesso all'abbonamento. Questa opzione può essere utilizzata se, ad esempio, si è verificato un errore tecnico che ha impedito all'utente di accedere al tuo prodotto e l'utente non vuole continuare a utilizzarlo. La tua app dovrebbe gestire queste cancellazioni come descritto in Revoche.

La seguente tabella illustra le differenze tra annullamento, rimborso e revoca.

Interrompe il rinnovo Rimborsa denaro Revocare l'accesso
Annulla No No
Rimborso No No
Revoca

Rimanda la fatturazione per un abbonato

Puoi anticipare la data di fatturazione successiva per un abbonato con rinnovo automatico utilizzando Purchases.subscriptions:defer dall'API Google Play Developer. Durante il periodo di rinvio, l'utente si è abbonato ai tuoi contenuti con accesso completo, ma non gli viene addebitato alcun costo. La data di rinnovo dell'abbonamento viene aggiornata alla nuova data.

Per i piani prepagati, puoi utilizzare l'API Defer billing per posticipare la scadenza.

La fatturazione differita ti consente di:

  • Offri agli utenti l'accesso senza costi sotto forma di offerta speciale, ad esempio una settimana senza costi per l'acquisto di un film.
  • Concedi l'accesso senza costi ai clienti come gesto di riconoscenza.

La fatturazione può essere differita di un solo giorno e di massimo un anno per chiamata API. Per posticipare ulteriormente la fatturazione, puoi chiamare di nuovo l'API prima dell'arrivo della nuova data di fatturazione.

Ad esempio, Darcy ha un abbonamento mensile ai contenuti online per l'app Fishing Quarterly. Generalmente le vengono addebitati 1,25 £ il primo giorno di ogni mese. A marzo, ha partecipato a un sondaggio online per il publisher di app. L'editore la premia con sei settimane senza costi rinviando il pagamento successivo fino al 15 maggio, ossia sei settimane dopo la data di fatturazione precedentemente programmata del 1° aprile. Darcy non riceve alcun addebito per aprile o l'inizio di maggio e ha comunque accesso ai contenuti. Il 15 maggio le viene addebitata la normale tariffa di abbonamento mensile di 1, 25 £. La prossima data di rinnovo è il 15 giugno.

Quando si esegue il differimento, è consigliabile informare l'utente via email o all'interno dell'app per informarlo che la sua data di fatturazione è cambiata.

Gestione dei rifiuti dei pagamenti

In caso di problemi di pagamento con il rinnovo di un abbonamento, Google tenterà periodicamente di rinnovare l'abbonamento per un certo periodo di tempo prima di annullarlo. Questo periodo di recupero può consistere in un periodo di tolleranza, seguito da un periodo di sospensione dell'account. Durante questo periodo, Google invia all'utente email e notifiche con la richiesta di aggiornare il metodo di pagamento.

Quando il pagamento viene rifiutato, l'abbonamento entra in un periodo di tolleranza, se ne è configurato uno. Durante il periodo di tolleranza, devi assicurarti che l'utente abbia ancora accesso ai diritti dell'abbonamento.

Al termine del periodo di tolleranza, l'abbonamento entra in un periodo di sospensione dell'account. Durante la sospensione dell'account, devi assicurarti che l'utente non abbia accesso ai diritti dell'abbonamento.

Puoi specificare la durata del periodo di tolleranza di ogni piano base con rinnovo automatico e la sospensione dell'account in Google Play Console. Specificando lunghezze inferiori ai valori predefiniti, è possibile ridurre il numero di abbonamenti recuperati dai rifiuti di pagamento.

Per massimizzare le probabilità di recupero dell'abbonamento durante un pagamento rifiutato, puoi informare l'utente di un problema di pagamento e chiedergli di risolverlo.

Puoi eseguire questa operazione autonomamente, come descritto nelle sezioni relative al periodo di tolleranza e alla sospensione degli account, oppure puoi implementare l'API di messaggistica in-app, in cui Google mostra un messaggio agli utenti nella tua app.

Messaggistica in-app

Se hai attivato la messaggistica in-app con InAppMessageCategoryId.TRANSACTIONAL, Google Play mostrerà agli utenti lo scambio di messaggi durante il periodo di tolleranza e la sospensione dell'account una volta al giorno e offrirà loro la possibilità di risolvere i problemi di pagamento senza uscire dall'app.

Snackbar che invita l'utente a correggere il pagamento
Figura 20. Snackbar che invita l'utente a completare il pagamento.

Ti consigliamo di chiamare questa API ogni volta che l'utente apre l'app per stabilire se il messaggio deve essere mostrato.

Se l'utente ha recuperato correttamente l'abbonamento, riceverai un codice di risposta SUBSCRIPTION_STATUS_UPDATED insieme a un token di acquisto. Dovresti poi usare il token di acquisto per chiamare l'API Google Play Developer e aggiornare lo stato dell'abbonamento nell'app.

Integra la messaggistica in-app

Per mostrare la messaggistica in-app agli utenti, utilizza BillingClient.showInAppMessages().

Ecco un esempio di attivazione del flusso di messaggi in-app:

Kotlin

val inAppMessageParams = InAppMessageParams.newBuilder()
        .addInAppMessageCategoryToShow(InAppMessageCategoryId.TRANSACTIONAL)
        .build()

billingClient.showInAppMessages(activity,
        inAppMessageParams,
        object : InAppMessageResponseListener() {
            override fun onInAppMessageResponse(inAppMessageResult: InAppMessageResult) {
                if (inAppMessageResult.responseCode == InAppMessageResponseCode.NO_ACTION_NEEDED) {
                    // The flow has finished and there is no action needed from developers.
                } else if (inAppMessageResult.responseCode
                        == InAppMessageResponseCode.SUBSCRIPTION_STATUS_UPDATED) {
                    // The subscription status changed. For example, a subscription
                    // has been recovered from a suspend state. Developers should
                    // expect the purchase token to be returned with this response
                    // code and use the purchase token with the Google Play
                    // Developer API.
                }
            }
        })

Java

InAppMessageParams inAppMessageParams = InAppMessageParams.newBuilder()
        .addInAppMessageCategoryToShow(InAppMessageCategoryId.TRANSACTIONAL)
        .build();

billingClient.showInAppMessages(activity,
        inAppMessageParams,
        new InAppMessageResponseListener() {
            @Override
            public void onInAppMessageResponse(InAppMessageResult inAppMessageResult) {
                if (inAppMessageResult.responseCode
                        == InAppMessageResponseCode.NO_ACTION_NEEDED) {
                    // The flow has finished and there is no action needed from developers.
                } else if (inAppMessageResult.responseCode
                        == InAppMessageResponseCode.SUBSCRIPTION_STATUS_UPDATED) {
                    // The subscription status changed. For example, a subscription
                    // has been recovered from a suspend state. Developers should
                    // expect the purchase token to be returned with this response
                    // code and use the purchase token with the Google Play
                    // Developer API.
                }
            }
        });