Integre ao seu app
Assinaturas do Google Play
Para apps Android que vendem assinaturas pelo Google Play e não têm backend próprio. O seu app envia o token de compra ao gateway com uma chave de API; o gateway consulta o Google com a sua conta de serviço e responde se a assinatura está ativa. A verificação é grátis.
#Antes de começar
- Um login no Play Console que seja o proprietário da conta ou um administrador, para poder convidar usuários.
- Uma conta Google que possa criar um projeto no console do Google Cloud (qualquer conta Google pode).
- O nome do pacote do seu app (applicationId), por exemplo com.example.app, e pelo menos um produto de assinatura criado no Play Console.
- Cerca de 15 minutos de cliques e depois até um dia para o Google ativar a permissão.
#1. Obtenha o JSON da conta de serviço
O arquivo JSON é a chave da conta de serviço. Ele permite que o gateway consulte o Google sobre as compras do seu app e nada mais. O Google o chama de chave da conta de serviço; não é o arquivo de cliente OAuth (client_secret_….json).
- 1
Abra o console do Google Cloud e escolha um projeto
console.cloud.google.comUse o seletor de projetos no topo. Qualquer projeto serve; criar um novo só para as verificações do Play mantém tudo organizado.
- 2
Ative a API do Play
APIs & Services → Library → Google Play Android Developer API → EnableBusque exatamente por esse nome. Se o botão disser Manage, ela já está ativada.
- 3
Crie a conta de serviço
IAM & Admin → Service accounts → Create service accountDê qualquer nome, como play-verify. Pule as etapas opcionais que concedem papéis no projeto ou acesso de usuários: ela não precisa de nenhum papel do Cloud. Clique em Done.
- 4
Baixe a chave JSON dela
Abra a conta de serviço → Keys → Add key → Create new key → JSON → CreateO navegador baixa um arquivo .json. Guarde-o com segurança: o Google nunca o mostra de novo, e qualquer pessoa com ele pode ler as compras do seu app.
- 5
Copie o e-mail da conta de serviço
Ele tem o formato play-verify@your-project.iam.gserviceaccount.com e aparece na página da conta de serviço e dentro do arquivo como client_email. Você vai precisar dele na próxima etapa.
Create new key está desativado ou é recusado?
#2. Dê acesso a ela no Play Console
- 1
Convide a conta de serviço
play.google.com/console → Users and permissions → Invite new usersCole o e-mail da conta de serviço como endereço de e-mail. Uma conta de serviço não precisa aceitar o convite.
- 2
Conceda estas duas permissões
App permissions → Add app → escolha o seu appMarque “View financial data, orders, and cancellation survey responses” e “Manage orders and subscriptions”. Deixe todo o resto desmarcado. Marcar as mesmas duas em Account permissions cobre todos os seus apps.
- 3
Envie o convite
Apply → Invite userA conta de serviço agora aparece em Users and permissions como Active.
Por que essas permissões
O Google pode levar até um dia para ativá-la
#3. Coloque-a em uma chave de API
- 1
Abra a chave que o seu app usa
Console → Chaves de API → EditarUse uma chave só para o app (veja abaixo).
- 2
Preencha “Verificação de assinatura do Google Play”
Configurar a verificação do Google PlayInforme o nome do pacote exatamente como no build.gradle do seu app (applicationId), escolha o arquivo JSON da etapa 1 e salve.
- 3
Leia o que o salvamento informa
O gateway testa o arquivo com o Google antes de armazená-lo. Se o Google ainda recusar, a caixa de diálogo diz o que falta, geralmente a API da etapa 1 ou a permissão da etapa 2. O arquivo é armazenado criptografado e nunca é mostrado de novo; envie-o novamente para substituí-lo.
Use uma chave só para o app
#4. Verifique a partir do app
Verifique logo após uma compra e de novo quando o app abrir, com o token que você salvou. Não bloqueie a abertura do app esperando a resposta: mostre o último resultado salvo e atualize-o quando a verificação retornar. O mesmo token é respondido a partir de um cache de um minuto. Cada chave pode verificar 120 vezes por minuto por padrão; as configurações do Google Play da chave mostram o limite atual, e o suporte pode aumentá-lo para uma chave. Chamadas acima do limite respondem 429 e não são registradas, então mantenha a última resposta salva.
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. Decida o que liberar
| Resposta da verificação | O que o app faz | Causa comum |
|---|---|---|
| active: true, in_trial: true | Liberar. Mostrar “Teste termina em” com expiry_time. | Teste gratuito |
| active: true | Liberar até expiry_time. | Pago, incluindo assinaturas canceladas que ainda não venceram |
| subscribed: true, active: false | Bloquear e mostrar uma tela de renovação. | Expirada, pausada, suspensa |
| subscribed: false | Bloquear e mostrar a tela de assinatura. | Token desconhecido, pagamento pendente |
| HTTP 502 / 503 | Manter a última resposta salva e tentar novamente mais tarde. | O Google ou a conta de serviço não responde |
Salve expiry_time junto com a resposta. Entre uma verificação e outra, trate a assinatura como utilizável até esse horário, para que um celular offline continue funcionando.
#6. Confirme todas as compras
Compras não confirmadas são reembolsadas após 3 dias
#7. Proteja a chave no app
Uma chave dentro de um app pode ser lida a partir do tráfego capturado. Ative a assinatura de requisições nessa chave para que uma chave copiada não possa ser usada sozinha, ofusque o build e mantenha um teto de cota na chave.
A assinatura cobre todas as chamadas feitas com a chave
#8. Veja o que aconteceu
Toda verificação, incluindo respostas em cache e falhas, aparece em Console → Log de requisições como uma “Verificação do Google Play” gratuita na chave. Busque pelo token de compra completo, pelos últimos caracteres dele ou pelo ID do pedido (GPA.…) que um usuário enviar a você a partir do e-mail de recibo do Google.
- google_play_api_disabled: a API do Play da etapa 1 não está ativada no projeto ao qual o arquivo JSON pertence.
- google_play_permission_denied: o convite da etapa 2 está faltando, não tem as duas permissões, é de outro app ou ainda não está ativo.
- google_play_credentials_invalid: a chave JSON foi excluída ou desativada no Google Cloud. Crie uma nova chave e envie-a na chave de API.
- O salvamento diz que o arquivo não é uma chave de conta de serviço: você escolheu o arquivo de cliente OAuth. Baixe a chave pela aba Keys da conta de serviço.
- Toda verificação diz que a compra não foi encontrada: o nome do pacote na chave é diferente do applicationId do app, ou o token vem de outro app.
- Compras de teste feitas por testadores de licença respondem test_purchase: true.
Ainda com problemas?
Envie para nós o ID da requisição ou a mensagem de erro e vamos investigar.