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. 1

    Abra o console do Google Cloud e escolha um projeto

    console.cloud.google.com

    Use o seletor de projetos no topo. Qualquer projeto serve; criar um novo só para as verificações do Play mantém tudo organizado.

  2. 2

    Ative a API do Play

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

    Busque exatamente por esse nome. Se o botão disser Manage, ela já está ativada.

  3. 3

    Crie a conta de serviço

    IAM & Admin → Service accounts → Create service account

    Dê 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. 4

    Baixe a chave JSON dela

    Abra a conta de serviço → Keys → Add key → Create new key → JSON → Create

    O 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. 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?

A sua organização no Google Cloud bloqueia o download de chaves com a política iam.disableServiceAccountKeyCreation (ativada por padrão em organizações novas). Um administrador da organização pode desativá-la para este projeto em IAM & Admin → Organization policies, ou você pode usar um projeto fora da organização.

#2. Dê acesso a ela no Play Console

  1. 1

    Convide a conta de serviço

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

    Cole 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. 2

    Conceda estas duas permissões

    App permissions → Add app → escolha o seu app

    Marque “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. 3

    Envie o convite

    Apply → Invite user

    A conta de serviço agora aparece em Users and permissions como Active.

Por que essas permissões

O gateway apenas lê uma assinatura com o purchases.subscriptionsv2.get do Google. O Google exige as permissões de dados financeiros e de pedidos para essa leitura. O gateway nunca confirma, reembolsa ou cancela nada.

O Google pode levar até um dia para ativá-la

Até lá, as verificações respondem google_play_permission_denied. Editar qualquer produto de assinatura no Play Console (alterar a descrição, salvar, voltar ao original) muitas vezes faz a nova permissão valer mais cedo.

#3. Coloque-a em uma chave de API

  1. 1

    Abra a chave que o seu app usa

    Console → Chaves de API → Editar

    Use uma chave só para o app (veja abaixo).

  2. 2

    Preencha “Verificação de assinatura do Google Play”

    Configurar a verificação do Google Play

    Informe o nome do pacote exatamente como no build.gradle do seu app (applicationId), escolha o arquivo JSON da etapa 1 e salve.

  3. 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

As configurações do Google Play pertencem a uma chave. Crie uma chave separada para o app, limite-a aos modelos que o app usa e defina um teto de cota.

#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.

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. Decida o que liberar

Resposta da verificaçãoO que o app fazCausa comum
active: true, in_trial: trueLiberar. Mostrar “Teste termina em” com expiry_time.Teste gratuito
active: trueLiberar até expiry_time.Pago, incluindo assinaturas canceladas que ainda não venceram
subscribed: true, active: falseBloquear e mostrar uma tela de renovação.Expirada, pausada, suspensa
subscribed: falseBloquear e mostrar a tela de assinatura.Token desconhecido, pagamento pendente
HTTP 502 / 503Manter 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

O gateway apenas lê a assinatura; nunca a confirma. O seu app precisa chamar completePurchase (Flutter) ou acknowledgePurchase (Play Billing). Se a verificação retornar acknowledged: false para uma compra feita há mais de alguns minutos, o app ainda não fez isso.

#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

Com a assinatura ativada, /v1/google-play/verify precisa de X-Timestamp, X-Nonce e X-Signature como qualquer outra requisição com essa chave, ou responde 401 signature_required. Assine-o com o próprio caminho: signedHeaders('POST', '/v1/google-play/verify'). Só ative a assinatura depois que a versão do app que assina estiver publicada.

Assinatura de requisições para apps →

#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.

Todos os campos e códigos de erro →

Ainda com problemas?

Envie para nós o ID da requisição ou a mensagem de erro e vamos investigar.