aisplice

Integralo nella tua app

Abbonamenti Google Play

Per le app Android che vendono abbonamenti tramite Google Play e non hanno un backend proprio. La tua app invia il token di acquisto al gateway con una chiave API; il gateway interroga Google con il tuo account di servizio e risponde se l'abbonamento è attivo. La verifica è gratuita.

#Prima di iniziare

  • Un accesso a Play Console come proprietario dell'account o amministratore, così da poter invitare utenti.
  • Un account Google che possa creare un progetto nella console Google Cloud (va bene qualsiasi account Google).
  • Il nome del pacchetto della tua app (applicationId), per esempio com.example.app, e almeno un prodotto in abbonamento creato in Play Console.
  • Circa 15 minuti di clic, poi fino a un giorno perché Google attivi l'autorizzazione.

#1. Ottieni il JSON dell'account di servizio

Il file JSON è la chiave dell'account di servizio. Permette al gateway di chiedere a Google informazioni sugli acquisti della tua app e nient'altro. Google la chiama service account key; non è il file del client OAuth (client_secret_….json).

  1. 1

    Apri la console Google Cloud e scegli un progetto

    console.cloud.google.com

    Usa il selettore dei progetti in alto. Va bene qualsiasi progetto; crearne uno nuovo solo per le verifiche Play aiuta a tenere tutto in ordine.

  2. 2

    Attiva la Play API

    APIs & Services → Library → Google Play Android Developer API → Enable

    Cerca il nome esatto. Se il pulsante dice Manage, è già attiva.

  3. 3

    Crea l'account di servizio

    IAM & Admin → Service accounts → Create service account

    Dagli un nome qualsiasi, per esempio play-verify. Salta i passaggi facoltativi che concedono ruoli di progetto o accesso utente: non gli serve alcun ruolo Cloud. Fai clic su Done.

  4. 4

    Scarica la sua chiave JSON

    Apri l'account di servizio → Keys → Add key → Create new key → JSON → Create

    Il browser scarica un file .json. Conservalo al sicuro: Google non lo mostra mai più e chiunque lo possieda può leggere gli acquisti della tua app.

  5. 5

    Copia l'email dell'account di servizio

    Ha un formato tipo play-verify@your-project.iam.gserviceaccount.com ed è mostrata nella pagina dell'account di servizio e nel file come client_email. Ti serve nel passaggio successivo.

Create new key è disattivato o viene rifiutato?

La tua organizzazione Google Cloud blocca il download delle chiavi con la policy iam.disableServiceAccountKeyCreation (attiva per impostazione predefinita nelle nuove organizzazioni). Un amministratore dell'organizzazione può disattivarla per questo progetto in IAM & Admin → Organization policies, oppure puoi usare un progetto esterno all'organizzazione.

#2. Concedigli l'accesso in Play Console

  1. 1

    Invita l'account di servizio

    play.google.com/console → Users and permissions → Invite new users

    Incolla l'email dell'account di servizio come indirizzo email. Un account di servizio non deve accettare l'invito.

  2. 2

    Concedi queste due autorizzazioni

    App permissions → Add app → scegli la tua app

    Seleziona View financial data, orders, and cancellation survey responses e Manage orders and subscriptions. Lascia disattivato tutto il resto. Selezionando le stesse due voci in Account permissions copri invece tutte le tue app.

  3. 3

    Invia l'invito

    Apply → Invite user

    Ora l'account di servizio compare in Users and permissions come Active.

Perché queste autorizzazioni

Il gateway legge solo un abbonamento con purchases.subscriptionsv2.get di Google. Per questa lettura Google richiede le autorizzazioni sui dati finanziari e sugli ordini. Il gateway non conferma, rimborsa né annulla mai nulla.

Google può impiegare fino a un giorno per attivarla

Fino ad allora le verifiche rispondono google_play_permission_denied. Modificare un qualsiasi prodotto in abbonamento in Play Console (cambia la descrizione, salva, poi ripristinala) spesso fa applicare prima la nuova autorizzazione.

#3. Impostalo su una chiave API

  1. 1

    Apri la chiave usata dalla tua app

    Console → Chiavi API → Modifica

    Usa una chiave solo per l'app (vedi sotto).

  2. 2

    Compila Verifica abbonamenti Google Play

    Configura la verifica Google Play

    Inserisci il nome del pacchetto esattamente come nel build.gradle della tua app (applicationId), scegli il file JSON del passaggio 1 e salva.

  3. 3

    Leggi il messaggio dopo il salvataggio

    Il gateway prova il file con Google prima di salvarlo. Se Google lo rifiuta ancora, la finestra indica cosa manca, di solito l'API del passaggio 1 o l'autorizzazione del passaggio 2. Il file viene salvato cifrato e non viene mai più mostrato; caricalo di nuovo per sostituirlo.

Usa una chiave solo per l'app

Le impostazioni Google Play appartengono a una sola chiave. Crea una chiave separata per l'app, limitala ai modelli che l'app usa e assegnale un tetto di quota.

#4. Verifica dall'app

Verifica subito dopo un acquisto, e di nuovo all'apertura dell'app con il token salvato. Non bloccare l'avvio dell'app in attesa della risposta: mostra l'ultimo risultato salvato e aggiornalo quando arriva la verifica. Allo stesso token si risponde da una cache di un minuto. Ogni chiave può effettuare 120 verifiche al minuto per impostazione predefinita; le impostazioni Google Play della chiave mostrano il limite attuale e l'assistenza può aumentarlo per una singola chiave. Le chiamate oltre il limite rispondono 429 e non vengono registrate, quindi conserva l'ultima risposta salvata.

google_play.dart
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:in_app_purchase/in_app_purchase.dart';

const apiKey = 'sk-YOUR_KEY';

Future<Map<String, dynamic>?> checkSubscription(String purchaseToken) async {
  final res = await http.post(
    Uri.parse('https://www.aisplice.store/v1/google-play/verify'),
    headers: {
      'Authorization': 'Bearer $apiKey',
      'Content-Type': 'application/json',
      // Request signing on for this key? Then this call must be signed too:
      // ...signedHeaders('POST', '/v1/google-play/verify'),
    },
    body: jsonEncode({'purchase_token': purchaseToken}),
  );
  if (res.statusCode != 200) return null; // keep the last saved answer
  return jsonDecode(res.body) as Map<String, dynamic>;
}

// In your purchaseStream listener:
Future<void> onPurchase(PurchaseDetails purchase) async {
  if (purchase.status != PurchaseStatus.purchased &&
      purchase.status != PurchaseStatus.restored) return;
  final token = purchase.verificationData.serverVerificationData;
  final status = await checkSubscription(token);
  if (status != null && status['active'] == true) {
    await saveEntitlement(token, status); // your local storage
    unlockPaidFeatures();
  }
  if (purchase.pendingCompletePurchase) {
    await InAppPurchase.instance.completePurchase(purchase); // acknowledges on Android
  }
}

#5. Decidi cosa sbloccare

Risposta della verificaCosa fa l'appCausa tipica
active: true, in_trial: trueSblocca. Mostra “La prova termina il” con expiry_time.Prova gratuita
active: trueSblocca fino a expiry_time.Pagato, compresi gli abbonamenti annullati non ancora scaduti
subscribed: true, active: falseBlocca e mostra una schermata di rinnovo.Scaduto, in pausa, sospeso
subscribed: falseBlocca e mostra la schermata di abbonamento.Token sconosciuto, pagamento in sospeso
HTTP 502 / 503Mantieni l'ultima risposta salvata e riprova più tardi.Google o l'account di servizio non risponde

Salva expiry_time insieme alla risposta. Tra una verifica e l'altra, considera l'abbonamento utilizzabile fino a quel momento, così un telefono offline continua a funzionare.

#6. Conferma ogni acquisto

Gli acquisti non confermati vengono rimborsati dopo 3 giorni

Il gateway legge soltanto l'abbonamento; non lo conferma mai. La tua app deve chiamare completePurchase (Flutter) o acknowledgePurchase (Play Billing). Se la verifica restituisce acknowledged: false per un acquisto più vecchio di qualche minuto, l'app non l'ha ancora fatto.

#7. Proteggi la chiave nell'app

Una chiave dentro un'app può essere letta dal traffico intercettato. Attiva la firma delle richieste per quella chiave, così una chiave copiata non può essere usata da sola, offusca la build e mantieni un tetto di quota sulla chiave.

La firma vale per ogni chiamata fatta con la chiave

Una volta attivata la firma, /v1/google-play/verify richiede X-Timestamp, X-Nonce e X-Signature come ogni altra richiesta con quella chiave, altrimenti risponde 401 signature_required. Firmala con il suo percorso: signedHeaders('POST', '/v1/google-play/verify'). Attiva la firma solo dopo aver pubblicato la versione dell'app che firma.

Firma delle richieste per le app →

#8. Controlla cosa è successo

Ogni verifica, comprese le risposte in cache e gli errori, è elencata in Console → Registro delle richieste come “Verifica Google Play” gratuita sulla chiave. Cerca per token di acquisto completo, per i suoi ultimi caratteri o per l'ID ordine (GPA.…) che un utente ti invia dall'email di ricevuta di Google.

  • google_play_api_disabled: la Play API del passaggio 1 non è attiva nel progetto a cui appartiene il file JSON.
  • google_play_permission_denied: l'invito del passaggio 2 manca, non include le due autorizzazioni, riguarda un'altra app o non è ancora attivo.
  • google_play_credentials_invalid: la chiave JSON è stata eliminata o disattivata in Google Cloud. Crea una nuova chiave e caricala sulla chiave API.
  • Il salvataggio dice che il file non è una chiave di account di servizio: hai scelto il file del client OAuth. Scarica invece la chiave dalla scheda Keys dell'account di servizio.
  • Ogni verifica dice che l'acquisto non è stato trovato: il nome del pacchetto sulla chiave è diverso dall'applicationId dell'app, oppure il token proviene da un'altra app.
  • Gli acquisti di prova dei tester delle licenze restituiscono test_purchase: true.

Tutti i campi e i codici di errore →

Non hai ancora risolto?

Inviaci l'ID richiesta o il messaggio di errore e verificheremo.