Vai al contenuto

Linee guida per la revisione di Android Play Store per gli IAP

GitHub

Per far approvare la tua app Android su Google Play è necessario rispettare le policy di Google, specialmente per le app con acquisti in-app e abbonamenti. Questa guida spiega tutto ciò che serve per superare la revisione con successo.

  1. Crea un Android App Bundle firmato

    Le nuove app su Google Play dovrebbero essere caricate come Android App Bundle (.aab), non come APK di debug caricati manualmente.

    Mantieni il tuo versionCode in aumento a ogni upload e conserva la tua upload key in modo sicuro se utilizzi Play App Signing.

    Flusso Android App Bundle

  2. Crea l'app nella Play Console

    Se non hai ancora un account developer, inizia con la registrazione alla Play Console. Poi, in Home > Crea app, scegli la lingua, il tipo di app/gioco, se è gratuita o a pagamento, l'email di supporto e accetta le dichiarazioni richieste.

    Scegli con cura l'impostazione gratuita/a pagamento. Google ti permette di rendere gratuita un'app a pagamento in seguito, ma una volta che un'app è stata offerta gratuitamente, non può più diventare a pagamento.

    Crea l'app in Play Console

  3. Completa App Content e Store Listing

    Prima della revisione in produzione, completa le dichiarazioni obbligatorie su Play Console:

    • Informativa sulla privacy
    • Annunci
    • Accesso alle app
    • Target audience e contenuti
    • Classificazione dei contenuti
    • Sicurezza dei dati
    • Dichiarazioni di permessi sensibili, se applicabili
  4. Eseguire un test track installato tramite Play

    Inizia con test interno per una QA rapida. Se il tuo account developer è un account personale creato dopo il 13 novembre 2023, devi anche completare un test chiuso con almeno 12 tester che hanno aderito per 14 giorni consecutivi prima dell'accesso alla produzione.

    Test interno in Play Console

  5. Verifica del billing end-to-end

    Installa l'app da Google Play, non da un APK esportato localmente. Quindi conferma che:

    • I prodotti vengano caricati correttamente da Play
    • Il pannello di acquisto mostra un acquisto di prova banner per i tester della licenza
    • Gli Entitlements si sbloccano dopo l'acquisto
    • I flussi di ripristino e gestione degli abbonamenti funzionano

Per i beni e i servizi digitali, devi devi usare il sistema di fatturazione di Google Play:

Beni digitali (Play Billing obbligatorio):

  • Abbonamenti a funzionalità premium
  • Valuta in-app o crediti
  • Contenuti digitali (ebook, musica, video)
  • Upgrade e power-up nei giochi
  • Sblocco app e livelli premium

Beni fisici (non usare Play Billing):

  • Merchandising fisico
  • Servizi nel mondo reale
  • Donazioni una tantum a no-profit

:::note Configurazione Abbonamenti In Play Console, configura gli abbonamenti Android usando il nuovo abbonamento -> piano base -> offerta modello. In native-purchases, passa il Base Plan ID con planIdentifier. :::

import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';
// Ensure billing is available on the device
const { isBillingSupported } = await NativePurchases.isBillingSupported();
if (!isBillingSupported) throw new Error('Google Play Billing not available');
// Fetch subscription products (Store data is required—never hardcode pricing)
const { products } = await NativePurchases.getProducts({
productIdentifiers: ['premium_monthly', 'premium_yearly'],
productType: PURCHASE_TYPE.SUBS,
});
// Plan identifiers are the Base Plan IDs you create in Google Play Console
const transaction = await NativePurchases.purchaseProduct({
productIdentifier: 'premium_monthly',
planIdentifier: 'monthly-plan', // REQUIRED on Android, ignored on iOS
productType: PURCHASE_TYPE.SUBS,
});
console.log('Purchase token for server validation:', transaction.purchaseToken);

Informativa sui prezzi in anticipo

Sezione intitolata “Informativa sui prezzi”

Google Play richiede una chiara informativa su tutti i costi prima dell'acquisto:

Elementi richiesti:

  • Prezzo esatto nella valuta locale dell'utente
  • Frequenza di fatturazione (mensile, annuale, ecc.)
  • Cosa include l'abbonamento
  • Costo totale per le offerte di lancio
  • Quando avverranno gli addebiti

Best practice per il design della UI

Esempio di UI conforme:

function SubscriptionCard({ product }) {
return (
<div className="subscription-card">
<h3>{product.title}</h3>
{/* Show intro offer if available */}
{product.introductoryPrice && (
<div className="intro-offer">
<p className="intro-price">{product.introductoryPriceString}</p>
<p className="intro-period">
for {product.introductoryPricePeriod}
</p>
</div>
)}
{/* Regular price */}
<div className="regular-price">
<p className="price">{product.priceString}</p>
<p className="period">per {product.subscriptionPeriod}</p>
</div>
{/* Clear description */}
<p>{product.description}</p>
{/* Renewal terms */}
<p className="terms">
Renews automatically. Cancel anytime in Google Play.
</p>
<button onClick={() => handlePurchase(product)}>
Subscribe Now
</button>
</div>
);
}

Prima del rinnovo automatico, Google richiede:

  • Notifica chiara dell'avvenuto rinnovo
  • Promemoria del prezzo
  • Accesso facile alla cancellazione

Chiarezza dei prezzi cross-platform

Sezione: “Chiarezza dei prezzi cross-platform”

Se vendi lo stesso entitlement su più piattaforme, mantieni allineati nomi dei prodotti, periodi di fatturazione, benefit inclusi e clausole di rinnovo per non sorprendere gli utenti.

I prezzi possono variare legittimamente per tasse, valuta locale o dinamiche dello store, ma la UI di acquisto non deve mai nascondere tali differenze o implicare costi di rinnovo diversi da quelli di Google Play.

Requisiti per la Privacy Policy

Sezione: “Requisiti della Privacy Policy”

Se la tua app include acquisti in-app, devi:

  1. Inserire il link nella scheda del Play Store

    • Aggiungere l'URL della privacy policy nella Play Console
    • Deve essere accessibile pubblicamente
    • Deve essere nella stessa lingua della tua app
  2. Inserire il link all'interno dell'app

    • Mostrare la privacy policy nelle impostazioni dell'app
    • Visualizzarla prima di raccogliere dati utente
    • Renderla facilmente reperibile

Esempio di implementazione:

function SettingsScreen() {
const openPrivacyPolicy = () => {
window.open('https://yourapp.com/privacy', '_blank');
};
const openTerms = () => {
window.open('https://yourapp.com/terms', '_blank');
};
return (
<div>
<h2>Settings</h2>
<button onClick={openPrivacyPolicy}>
Privacy Policy
</button>
<button onClick={openTerms}>
Terms of Service
</button>
<button onClick={() => NativePurchases.manageSubscriptions()}>
Manage Subscriptions
</button>
</div>
);
}

Google Play richiede una dichiarazione dettagliata nella sezione Sicurezza dei dati:

Per le app con IAP, dichiara:

  • Raccolta della cronologia acquisti
  • Indirizzi email (per le ricevute)
  • ID dispositivo (per la prevenzione delle frodi)
  • Gestione delle informazioni di pagamento
  • Raccolta dati analitici

La sezione Sicurezza dei dati è legalmente vincolante. Dichiarazioni errate possono causare la rimozione dell'app.

Dichiarazioni sui contenuti dell'app

Sezione "Dichiarazioni sui contenuti dell'app"

La revisione di Google Play non riguarda solo il binario. Prima del rilascio in produzione, completa le dichiarazioni su Policy e programmi > Contenuti dell'app.

Il set minimo da revisionare con cura:

  • Informativa sulla privacy: URL pubblico in Play Console e un punto di accesso nell'app se richiesto
  • Annunci: Dichiarare se l'app contiene annunci
  • Accesso alle app: Fornire credenziali di test o un percorso chiaro se alcune schermate sono protette
  • Pubblico e contenuti target: Corrispondere al pubblico reale dell'app
  • Classificazione dei contenuti: Completare il questionario IARC per evitare che l'app risulti senza classificazione
  • Sicurezza dei dati: Dichiarare con precisione pratiche di raccolta, condivisione e sicurezza

1. Implementazione della fatturazione mancante o errata

Sezione intitolata “1. Implementazione dei pagamenti mancante o errata”

Perché viene rifiutato:

  • Non si usa Google Play Billing per i beni digitali
  • Utilizzo di API di fatturazione deprecate
  • Implementazione di soluzioni di pagamento custom per gli abbonamenti

Prevenzione:

// ✅ Correct: Use native-purchases (uses Google Play Billing)
await NativePurchases.purchaseProduct({
productIdentifier: 'premium_monthly',
planIdentifier: 'monthly-plan',
productType: PURCHASE_TYPE.SUBS,
});
// ❌ Wrong: Custom payment processor for subscriptions
// await CustomPayment.charge(user, 9.99);

Perché viene rifiutato:

  • Prezzo visualizzato solo dopo il click su acquista
  • Costi aggiuntivi non dichiarati preventivamente
  • Termini di abbonamento poco chiari

Prevenzione:

function PurchaseScreen({ product }) {
return (
<div>
{/* Show ALL costs upfront */}
<h2>Premium Subscription</h2>
<div className="pricing">
<p className="price">{product.priceString}/month</p>
<p className="taxes">Taxes may apply based on location</p>
</div>
<div className="features">
<h3>Includes:</h3>
<ul>
<li>Ad-free experience</li>
<li>Unlimited cloud storage</li>
<li>Priority support</li>
</ul>
</div>
<div className="terms">
<p>
Subscription renews automatically unless cancelled at least
24 hours before the end of the current period.
</p>
<p>
Manage or cancel in Google Play Subscriptions.
</p>
</div>
<button onClick={handlePurchase}>
Start Subscription
</button>
</div>
);
}

Perché viene rifiutato:

  • Pre-selezione delle opzioni premium
  • Nascondere le alternative più economiche
  • Rendere difficile la cancellazione
  • Falsa urgenza (“Solo 3 posti rimasti!”)

Best Practice per la descrizione

Linee guida di marketing

Prevenzione:

  • Mostra tutti i piani di abbonamento allo stesso modo
  • Rendi la cancellazione chiara e accessibile
  • Evita countdown o falsa scarsità
  • Non usare dark pattern per spingere opzioni costose

Perché viene rifiutato:

  • L'app crasha durante l'acquisto
  • I prodotti non vengono caricati
  • La conferma d'acquisto non appare
  • Le funzioni premium non si sbloccano dopo l'acquisto
  • Test effettuati solo su build sideloaded invece di un testing track di Play

Prevenzione:

import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';
// Comprehensive testing before submission
async function testPurchaseFlow() {
try {
// 1. Test product loading
const { products } = await NativePurchases.getProducts({
productIdentifiers: ['premium_monthly', 'premium_yearly'],
productType: PURCHASE_TYPE.SUBS,
});
console.log('✓ Products loaded:', products.length);
// 2. Test purchase flow
const transaction = await NativePurchases.purchaseProduct({
productIdentifier: 'premium_monthly',
planIdentifier: 'monthly-plan',
productType: PURCHASE_TYPE.SUBS,
});
console.log('✓ Purchase completed', transaction.transactionId);
// 3. Verify entitlements
const { purchases } = await NativePurchases.getPurchases({
productType: PURCHASE_TYPE.SUBS,
});
if (
purchases.some(
(purchase) =>
purchase.productIdentifier === 'premium_monthly' &&
['PURCHASED', '1'].includes(purchase.purchaseState ?? '') &&
purchase.isAcknowledged,
)
) {
console.log('✓ Premium features unlocked');
}
// 4. Test restore
await NativePurchases.restorePurchases();
console.log('✓ Restore works');
} catch (error) {
console.error('✗ Test failed:', error);
}
}

5. Violazioni della privacy policy

Sezione: “5. Violazioni della Privacy Policy”

Perché viene rifiutato:

  • Link alla privacy policy assente nell'app
  • Privacy policy non accessibile
  • Raccolta dati non dichiarata
  • Sezione Data Safety inaccurata

Prevenzione:

  • Aggiungi la privacy policy alla scheda del Play Store
  • Includi il link nelle impostazioni dell'app
  • Compila correttamente la sezione Data Safety
  • Aggiornare la policy aggiungendo nuovi dati raccolti

I programmi di fatturazione alternativa di Google variano in base alla regione. Se desideri utilizzare soluzioni diverse dal Google Play Billing standard, verifica immediatamente l'idoneità del mercato, le API richieste e il linguaggio di disclosure nella Play Console prima dell'implementazione.

Gli utenti devono poter:

  • Visualizza facilmente gli abbonamenti attivi
  • Annulla senza contattare il supporto
  • Capisci quando l'annullamento diventa effettivo

Implementazione:

import { NativePurchases } from '@capgo/native-purchases';
function ManageSubscriptionButton() {
const openManagement = async () => {
try {
// Opens Google Play subscription management
await NativePurchases.manageSubscriptions();
} catch (error) {
// Fallback to direct URL
const playStoreUrl = 'https://play.google.com/store/account/subscriptions';
window.open(playStoreUrl, '_blank');
}
};
return (
<button onClick={openManagement}>
Manage Subscription in Google Play
</button>
);
}

Informativa obbligatoria:

  • Quando diventa effettivo l'annullamento?
  • L'accesso rimane attivo fino alla fine del periodo?
  • Sono disponibili rimborsi parziali?
function CancellationInfo() {
return (
<div className="cancellation-info">
<h3>Cancellation Policy</h3>
<ul>
<li>Cancel anytime in Google Play</li>
<li>Access continues until end of billing period</li>
<li>No refunds for partial periods</li>
<li>Resubscribe anytime to regain access</li>
</ul>
<button onClick={() => NativePurchases.manageSubscriptions()}>
Manage in Google Play
</button>
</div>
);
}

Checklist pre-invio

  1. Verifica l'implementazione del billing

    • Utilizzo di Google Play Billing (tramite native-purchases)
    • Tutti i prodotti in abbonamento creati in Play Console
    • Base plan e offerte configurati correttamente
    • Prodotti attivati e pubblicati
    • Prezzi impostati per tutti i paesi target
  2. Test dei flussi di acquisto

    • Crea un account di licenza per i test
    • Installa la build da un canale di test di Play
    • Testa ogni livello di abbonamento
    • Verifica il caricamento dei prodotti
    • Testa il completamento dell'acquisto
    • Conferma che il acquisto di prova banner appaia
    • Verifica lo sblocco delle funzioni premium
    • Testa il ripristino dell'abbonamento
    • Testa su più dispositivi
  3. Revisione di tutti i testi

    • Prezzi chiari prima dell'acquisto
    • Tutte le commissioni sono esplicite
    • Termini di abbonamento chiari
    • Procedura di cancellazione spiegata
    • Nessuna dichiarazione fuorviante
  4. Contenuti e privacy dell'app

    • Informativa sulla privacy collegata in Play Console
    • Informativa sulla privacy accessibile nell'app
    • Dichiarazione sulla pubblicità completata
    • Istruzioni di accesso aggiunte se l'app è protetta
    • Sezione Data Safety compilata correttamente
    • Permessi giustificati e documentati
  5. Classificazione dei contenuti e pubblico

    • Completa il questionario sulla classificazione
    • Completa la sezione Pubblico di destinazione e contenuti
    • Assicura valutazione coerente con i contenuti
    • Dichiara gli acquisti in-app nel questionario
  6. Prepara la scheda del Play Store

    • Descrizione dell'app corretta
    • La descrizione breve non supera gli 80 caratteri
    • La descrizione completa non supera i 4000 caratteri
    • Almeno 2 screenshot del telefono caricati
    • Feature graphic 1024x500 caricata
    • Gli screenshot mostrano la versione corrente
    • Tutti gli asset richiesti caricati

Accesso alla produzione per nuovi account personali: Solitamente 7 giorni o meno dall'invio Prima revisione in produzione: Spesso diversi giorni, a volte di più se sorgono problemi di fatturazione o policy Aggiornamenti: Spesso più veloci della prima release, ma soggetti a revisione Ricorsi: Prevedi diversi giorni e fornisci fix precisi e istruzioni per i revisori

:::tip Revisioni continue A differenza di Apple, Google revisiona le app continuamente. La tua app può andare online in qualsiasi momento durante il periodo di revisione, non a un orario fisso. :::

  1. Aggiungi account di test:

    • Vai su Play Console
    • Impostazioni > License testing
    • Aggiungi l'account Gmail per i test
  2. Test in Sandbox:

import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';
// Test purchases with license test account
async function testInSandbox() {
const { isBillingSupported } = await NativePurchases.isBillingSupported();
if (!isBillingSupported) {
console.error('Billing not supported in this environment');
return;
}
// Fetch products (returns test pricing when using a license tester)
const { products } = await NativePurchases.getProducts({
productIdentifiers: ['premium_monthly'],
productType: PURCHASE_TYPE.SUBS,
});
console.log('Test products:', products);
// Make test purchase (no charge)
const transaction = await NativePurchases.purchaseProduct({
productIdentifier: 'premium_monthly',
planIdentifier: 'monthly-plan',
productType: PURCHASE_TYPE.SUBS,
});
console.log('Test purchase complete:', transaction.transactionId);
}
  1. Verifica il banner di test:
    • Effettuando un acquisto con l'account di test
    • Dovresti vedere la notifica “Test purchase”
    • Non vengono addebitati costi reali

Prima del rilascio in produzione:

  1. Crea una track di test interni per un QA rapido o una track di test chiusi monitora per test più ampi
  2. Carica un rilascio firmato .aab e pubblica la release di test
  3. Aggiungi le email dei tester e condividi il link di opt-in
  4. Fai installare la build ai tester tramite Google Play
  5. Verifica i flussi di acquisto end-to-end sulla build installata da Play Store
  6. Se il tuo account developer personale è stato creato dopo il 13 novembre 2023, mantieni almeno 12 tester iscritti a un test chiuso per 14 giorni consecutivi prima di richiedere l'accesso alla produzione

Una build di debug sideloadata non sostituisce una build di test installata tramite Play per la validazione di Google Play Billing.

import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';
async function handlePurchase(productId: string, planIdentifier?: string) {
try {
setLoading(true);
const transaction = await NativePurchases.purchaseProduct({
productIdentifier: productId,
planIdentifier,
productType: planIdentifier ? PURCHASE_TYPE.SUBS : PURCHASE_TYPE.INAPP,
});
console.log('Purchase token:', transaction.purchaseToken ?? transaction.receipt);
// Success - check entitlements from the store
const { purchases } = await NativePurchases.getPurchases({
productType: planIdentifier ? PURCHASE_TYPE.SUBS : PURCHASE_TYPE.INAPP,
});
const isOwned = purchases.some(
(purchase) =>
purchase.productIdentifier === productId &&
(purchase.purchaseState === 'PURCHASED' || purchase.purchaseState === '1') &&
purchase.isAcknowledged,
);
if (isOwned) {
unlockPremiumFeatures();
showSuccess('Premium activated!');
}
} catch (error: any) {
// Handle specific error cases
switch (error.code) {
case 'USER_CANCELLED':
// User backed out - no error needed
console.log('Purchase cancelled');
break;
case 'ITEM_ALREADY_OWNED':
// They already own it - restore instead
showInfo('You already own this! Restoring...');
await NativePurchases.restorePurchases();
break;
case 'ITEM_UNAVAILABLE':
showError('This subscription is currently unavailable. Please try again later.');
break;
case 'NETWORK_ERROR':
showError('Network error. Please check your connection and try again.');
break;
default:
showError('Purchase failed. Please try again.');
console.error('Purchase error:', error);
}
} finally {
setLoading(false);
}
}
import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';
function RestorePurchasesButton() {
const [loading, setLoading] = useState(false);
const handleRestore = async () => {
setLoading(true);
try {
await NativePurchases.restorePurchases();
const { purchases } = await NativePurchases.getPurchases({
productType: PURCHASE_TYPE.SUBS,
});
const hasSubscription = purchases.some(
(purchase) => purchase.productType === 'subs' && purchase.isAcknowledged,
);
if (hasSubscription) {
unlockPremiumFeatures();
showSuccess('Subscriptions restored!');
return;
}
// Check one-time unlocks if needed
const { purchases: iaps } = await NativePurchases.getPurchases({
productType: PURCHASE_TYPE.INAPP,
});
const hasInApp = iaps.some((purchase) => purchase.productIdentifier === 'premium_unlock');
if (hasInApp) {
unlockPremiumFeatures();
showSuccess('Previous purchases restored!');
return;
}
showInfo('No previous purchases found.');
} catch (error) {
showError('Failed to restore purchases. Please try again.');
} finally {
setLoading(false);
}
};
return (
<button onClick={handleRestore} disabled={loading}>
{loading ? 'Restoring...' : 'Restore Purchases'}
</button>
);
}

Controlla lo stato dell'abbonamento

Sezione: “Verifica lo stato dell'abbonamento”
import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';
async function checkSubscriptionStatus() {
try {
const { purchases } = await NativePurchases.getPurchases({
productType: PURCHASE_TYPE.SUBS,
});
const subscription = purchases.find(
(purchase) =>
purchase.productIdentifier === 'premium_monthly' &&
(purchase.purchaseState === 'PURCHASED' || purchase.purchaseState === '1') &&
purchase.isAcknowledged,
);
if (!subscription) {
showPaywall();
return;
}
console.log('Subscription active:', {
productId: subscription.productIdentifier,
expiresAt: subscription.expirationDate,
willRenew: subscription.willCancel === false,
purchaseToken: subscription.purchaseToken,
});
unlockPremiumFeatures();
} catch (error) {
console.error('Failed to check subscription:', error);
}
}

Cosa fare se l'app viene rifiutata

Sezione: “Se la tua app viene rifiutata”

Violazioni comuni delle policy

Sezione: “Violazioni comuni delle policy”

Policy sui pagamenti:

  • Non utilizzo di Google Play Billing
  • Termini di abbonamento fuorvianti
  • Costi nascosti

Policy sui dati utente:

  • Privacy policy mancante
  • Dichiarazioni sulla sicurezza dei dati imprecise
  • Permessi eccessivi
  1. Esamina la notifica di violazione

    • Leggi la policy specifica citata
    • Capisci cosa ha segnalato Google
    • Controlla gli esempi forniti
  2. Risolvi il problema

    • Agisci sulla causa radice, non solo sui sintomi
    • Testa accuratamente dopo la correzione
    • Documenta tutte le modifiche apportate
  3. Invia ricorso (se applicabile)

    Processo di chiarimento e ricorso

    Subject: Policy Violation Appeal - [App Name]
    Dear Google Play Review Team,
    I have received notification that my app violates [Policy X.Y].
    I have made the following changes to comply:
    1. [Specific change made]
    2. [Specific change made]
    3. [Specific change made]
    The updated version [version number] addresses all concerns raised.
    Test account for verification:
    Email: test@example.com
    Password: TestPass123
    Thank you for your consideration.

    Richiedi esempio di documentazione

  4. Invia nuovamente o aggiorna

    • Upload della versione corretta
    • Invia nuovamente per la revisione
    • Monitora lo stato in Play Console

Navigare la revisione del Play Store può essere complesso, specialmente quando devi gestire conformità dei pagamenti, dichiarazioni sui contenuti dell'app e configurazione dei test track. Se hai bisogno di assistenza personalizzata:

Prenota una call di consulenza con il nostro team per supporto su:

  • Preparazione completa alla revisione del Play Store
  • Configurazione test track e reclutamento tester
  • Revisione dell'implementazione IAP
  • Sicurezza dei dati e conformità alla privacy
  • Risoluzione rifiuti e ricorsi
  • Processo completo di invio dell'app

I nostri esperti hanno guidato centinaia di app verso il successo sul Play Store e possono aiutarti a rispettare i requisiti attuali.

Serve aiuto con l'implementazione?

Continua con le Linee guida per la revisione di Android Play Store per gli IAP

Sezione intitolata “Approfondimenti sulle linee guida di Google Play Store per gli acquisti in-app”

Se stai usando Linee guida per la revisione di Android Play Store per gli IAP per pianificare sicurezza e compliance, collegalo a Utilizzo di @capgo/native-purchases per la funzionalità nativa in Utilizzo di @capgo/native-purchases, Crittografia per i dettagli di implementazione della crittografia, Conformità per i dettagli di implementazione in Compliance, Security Scanner di Capgo per il workflow di prodotto in Capgo Security Scanner, e Sicurezza Capgo per il workflow di prodotto in Capgo Security.