Intégralo en tu app
Suscripciones de Google Play
Para apps Android que venden suscripciones a través de Google Play y no tienen backend propio. Tu app envía el token de compra al gateway con una clave de API; el gateway consulta a Google con tu cuenta de servicio y responde si la suscripción está activa. La verificación es gratuita.
#Antes de empezar
- Un inicio de sesión de Play Console que sea propietario de la cuenta o administrador, para poder invitar usuarios.
- Una cuenta de Google que pueda crear un proyecto en la consola de Google Cloud (cualquier cuenta de Google puede).
- El nombre del paquete de tu app (applicationId), por ejemplo com.example.app, y al menos un producto de suscripción creado en Play Console.
- Unos 15 minutos de clics y, después, hasta un día para que Google active el permiso.
#1. Obtén el JSON de la cuenta de servicio
El archivo JSON es la clave de la cuenta de servicio. Permite al gateway consultar a Google sobre las compras de tu app y nada más. Google lo llama clave de cuenta de servicio; no es el archivo del cliente OAuth (client_secret_….json).
- 1
Abre la consola de Google Cloud y elige un proyecto
console.cloud.google.comUsa el selector de proyectos de la parte superior. Sirve cualquier proyecto; crear uno nuevo solo para las verificaciones de Play mantiene todo ordenado.
- 2
Activa la API de Play
APIs y servicios (APIs & Services) → Biblioteca (Library) → Google Play Android Developer API → Habilitar (Enable)Busca el nombre exacto. Si el botón dice Administrar (Manage), ya está activada.
- 3
Crea la cuenta de servicio
IAM y administración (IAM & Admin) → Cuentas de servicio (Service accounts) → Crear cuenta de servicio (Create service account)Ponle cualquier nombre, como play-verify. Omite los pasos opcionales que otorgan roles del proyecto o acceso de usuarios: no necesita ningún rol de Cloud. Haz clic en Listo (Done).
- 4
Descarga su clave JSON
Abre la cuenta de servicio → Claves (Keys) → Agregar clave (Add key) → Crear clave nueva (Create new key) → JSON → Crear (Create)El navegador descarga un archivo .json. Guárdalo bien: Google no vuelve a mostrarlo, y cualquiera que lo tenga puede leer las compras de tu app.
- 5
Copia el correo de la cuenta de servicio
Tiene el formato play-verify@your-project.iam.gserviceaccount.com y aparece en la página de la cuenta de servicio y dentro del archivo como client_email. Lo necesitas en el paso siguiente.
¿Crear clave nueva (Create new key) aparece en gris o se rechaza?
#2. Dale acceso en Play Console
- 1
Invita a la cuenta de servicio
play.google.com/console → Usuarios y permisos (Users and permissions) → Invitar a usuarios nuevos (Invite new users)Pega el correo de la cuenta de servicio como dirección de correo. Una cuenta de servicio no necesita aceptar la invitación.
- 2
Concede estos dos permisos
Permisos de la aplicación (App permissions) → Añadir aplicación (Add app) → elige tu appMarca Ver datos financieros, pedidos y respuestas a encuestas de cancelación (View financial data, orders, and cancellation survey responses) y Gestionar pedidos y suscripciones (Manage orders and subscriptions). Deja todo lo demás desmarcado. Si marcas esos dos en Permisos de la cuenta (Account permissions), se aplican a todas tus apps.
- 3
Envía la invitación
Aplicar (Apply) → Invitar a usuario (Invite user)La cuenta de servicio aparece ahora en Usuarios y permisos con el estado Activo (Active).
Por qué estos permisos
Google puede tardar hasta un día en activarlo
#3. Configúralo en una clave de API
- 1
Abre la clave que usa tu app
Consola → Claves de API → EditarUsa una clave solo para la app (ver más abajo).
- 2
Completa Verificación de suscripciones de Google Play
Configurar la verificación de Google PlayEscribe el nombre del paquete exactamente como en el build.gradle de tu app (applicationId), elige el archivo JSON del paso 1 y guarda.
- 3
Lee el mensaje al guardar
El gateway prueba el archivo con Google antes de almacenarlo. Si Google sigue rechazándolo, el diálogo indica qué falta, normalmente la API del paso 1 o el permiso del paso 2. El archivo se almacena cifrado y no vuelve a mostrarse; súbelo de nuevo para reemplazarlo.
Usa una clave solo para la app
#4. Verifica desde la app
Verifica justo después de una compra, y de nuevo cuando la app se abra con el token guardado. No bloquees el inicio de la app esperando la respuesta: muestra el último resultado guardado y actualízalo cuando vuelva la verificación. El mismo token se responde desde una caché de un minuto. Cada clave puede verificar 120 veces por minuto de forma predeterminada; la configuración de Google Play de la clave muestra su límite actual, y soporte puede aumentarlo para una clave. Las llamadas por encima del límite responden 429 y no se registran, así que conserva la última respuesta guardada.
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. Decide qué desbloquear
| Respuesta de la verificación | Qué hace la app | Causa habitual |
|---|---|---|
| active: true, in_trial: true | Desbloquea. Muestra “La prueba termina” con expiry_time. | Prueba gratuita |
| active: true | Desbloquea hasta expiry_time. | Pagada, incluidas las suscripciones canceladas que aún no han vencido |
| subscribed: true, active: false | Bloquea y muestra una pantalla de renovación. | Caducada, en pausa, en espera |
| subscribed: false | Bloquea y muestra la pantalla de suscripción. | Token desconocido, pago pendiente |
| HTTP 502 / 503 | Conserva la última respuesta guardada y reintenta más tarde. | Google o la cuenta de servicio no responden |
Guarda expiry_time con la respuesta. Entre verificaciones, trata la suscripción como utilizable hasta esa hora, para que un teléfono sin conexión siga funcionando.
#6. Confirma cada compra
Las compras no confirmadas se reembolsan a los 3 días
#7. Protege la clave en la app
Una clave dentro de una app se puede leer del tráfico capturado. Activa la firma de solicitudes en esa clave para que una clave copiada no pueda usarse por sí sola, ofusca la compilación y mantén un tope de cuota en la clave.
La firma cubre todas las llamadas hechas con la clave
#8. Revisa qué pasó
Cada verificación, incluidas las respuestas en caché y los fallos, aparece en Consola → Registro de solicitudes como una “Verificación de Google Play” gratuita en la clave. Busca por el token de compra completo, sus últimos caracteres o el ID de pedido (GPA.…) que un usuario te envíe desde el correo de recibo de Google.
- google_play_api_disabled: la API de Play del paso 1 no está habilitada en el proyecto al que pertenece el archivo JSON.
- google_play_permission_denied: falta la invitación del paso 2, no tiene los dos permisos, es para otra app o aún no está activa.
- google_play_credentials_invalid: la clave JSON se eliminó o desactivó en Google Cloud. Crea una clave nueva y súbela en la clave de API.
- Al guardar se indica que el archivo no es una clave de cuenta de servicio: elegiste el archivo del cliente OAuth. Descarga la clave desde la pestaña Claves (Keys) de la cuenta de servicio.
- Todas las verificaciones dicen que no se encontró la compra: el nombre del paquete de la clave no coincide con el applicationId de la app, o el token es de otra app.
- Las compras de prueba de los testers con licencia responden test_purchase: true.
¿Sigues con el problema?
Envíanos el ID de solicitud o el mensaje de error y lo revisaremos.