Report: State of in-app subscriptions in the US 2023 Get a report

Tutorial: como implementar compras em um aplicativo com Flutter

Alexey Goncharov

Updated: March 20, 2023

Content

62fdf15a5a9626b86649d085 jp android tutorial 1 configuration 6

Flutter é um framework relativamente novo desenvolvido pelo Google que permite criar rapidamente aplicativos (apps) multiplataforma. O outro framework é o React Native do Facebook. Os aplicativos Flutter são desenvolvidos para o iOS e Android simultaneamente. Portanto, uma biblioteca de compras deve ser compatível com o StoreKit e com a Biblioteca de Faturamento (Billing Library). 

Em termos de arquitetura, qualquer plugin de pagamento – incluindo nosso Adapty Flutter SDK – é um wrapper que envolve as bibliotecas nativas, StoreKit e Biblioteca de Faturamento. No nosso caso, é um wrapper que envolve nossas próprias bibliotecas Adapty iOS e Android SDK

Bibliotecas de código aberto para compras no aplicativo (in-app purchases) baseadas no Flutter

Soluções populares para compras em aplicativos Flutter são os plugins de código aberto in_app_purchase (desenvolvidos pela equipe responsável pelo Flutter) e flutter_inapp_purchase (um plugin não-oficia). 

Estes plugins foram feitos para implementar as compras do lado do cliente. Eles não apresentam o recurso de validação de recibo (receipt validation) do lado do servidor (server-side) Você deve configurar sua própria infraestrutura do lado do servidor (server-side) para validar recibos e coletar dados de analytics de pagamento referentes a renovações, reembolsos, períodos de avaliação, cancelamentos e muito mais. 

Além disso, essas bibliotecas geralmente são lentas para suportar novos recursos de loja. Só para citar alguns, neste momento, elas não oferecem ofertas promocionais, recursos de pagamento à vista e de pagamento antecipado para o iOS.

Como a nossa biblioteca fala com o nosso servidor, ela apresenta todos os recursos abaixo:

  • Validação do servidor de compra; 
  • Suporte completo aos recursos de pagamento nativos; 
  • sintaxe DRY;
  • Analytics de assinaturas e compras e algumas outras coletas de dados;
  • Testes A/B, bem como experiências rápidas com compras, preços e períodos promocionais;
  • Paywalls e ofertas promocionais.

Para manter este artigo sucinto e fácil de ler, vamos linkar alguns artigos que escrevemos anteriormente sobre algumas etapas que você deve seguir antes de começar a trabalhar com compras no seu aplicativo Flutter.

Como criar compras no iOS e Android

Primeiro, você precisa criar uma conta de desenvolvedor, caso não tenha uma. Em seguida, você deve criar uma compra semanal no iOS e também no Android. Já explicamos como fazer isso em nossos artigos anteriores:

Como criar comprar no iOS

Como criar comprar no Android

Assim que terminar, você pode começar a criar e configurar seu projeto.

Como criar e configurar o projeto

Para que suas compras funcionem na sua implementação e em nosso sistema, você deve atender aos seguintes detalhes técnicos.

61dbfcadde3e1409fe5f8314 iy6l5yif4wtrzqfjzaek9s70lntdy9bul 7h6homozvwghjkvrzry8ohu9pva

Para o sistema iOS, você precisa fazer o seguinte:

  • Especificar o ID do pacote para linkar seu projeto Adapty ao seu aplicativo;
  • Configurar as notificações do App Store Serve, para que você possa receber notificações sobre eventos de assinatura;
  • Especificar o segredo compartilhado da App Store., que o servidor da Adapty vai utilizar para estabelecer uma conexão com os servidores da Apple e validar recibos.

Para o sistema Android, tanto o nome do pacote como o arquivo da chave da conta de serviço devem ser especificados. O nome do pacote é o ID do pacote iOS para Android. Você precisa usar o mesmo que é usado no código. Ele pode ser encontrado no arquivo /android/app/build.gradle, que está localizado no diretório android.defaultConfig.applicationId .

Como configurar produtos e paywalls

Um produto da Adapty reúne os de várias lojas. Por enquanto é apenas a App Store e o Google Play, mas introduziremos outras lojas no futuro. A ideia implícita nesta abordagem é facilitar a coleta de estatísticas entre plataformas, bem como permitir que você trabalhe com entidades de alto nível, ao invés de identificadores.

Paywall é uma entidade abstrata que contém uma matriz de produtos e um arquivo de configuração remota (que é um arquivo JSON contendo os metadados que você especificou no seu dashboard). Você codifica em código duro a ID do paywall no seu aplicativo, que deve ser usada para recuperar o arquivo de configuração e os dados do produto. É possível editar ambos sem ter que atualizar o aplicativo. Em um cenário típico, você projeta o paywall e o preenche com os dados que recebe de nós.

Como criar um produto

Vamos usar o Google Play Console e a App Store Connect para criar um produto que corresponda a uma assinatura semanal. Digite a identificação dos produtos correspondentes, que você pode recuperar dos sistemas de pagamento. É importante lembrar que, como a App Store Connect não tem API, é preciso fazer isso manualmente. Mas só uma vez. 

61dbfcadc56e16884ceeda5a 34mxwyuolr8iv5x2uec0mz6

Como criar um paywall

Ao criar um paywall, o segredo é especificar sua identificação em um formato apropriado. Este identificador será posteriormente utilizado pelo SDK para solicitar os dados do paywall. Acreditamos que este seja um bom método: Com esta arquitetura, não há necessidade de codificar seus produtos de forma dura do lado do cliente. Pode-se ser flexível com o gerenciamento dos produtos, versionamento, testes, etc. Uma outra opção seria o Firebase que armazena dados JSON com um conjunto de produtos integrados. No entanto, tal opção não permite a validação de erros e não é tão fácil de usar.

61dbfcae9d2b62d615559378 zn55mgmaz86h7qtmlow pxcwlspih63ifgswsurxtydhjlqyj3gm jqtzo vk8bvb3txn29f7g2oe6o2voyadhruy1lhyyvqvuo6ms5ytfq

Voilá! Após criar um produto e um paywall, agora está tudo pronto para sua primeira compra. Vamos prosseguir com a instalação do SDK.

Como usar o SDK

Vejamos as principais funções que precisamos para configurar e utilizar as assinaturas.

Instalação da biblioteca

Primeiro, você precisará acrescentar a biblioteca adapty_flutter ao seu projeto. Para isso, adicione a seguinte dependência ao seu arquivo pubspec.yaml:

dependencies:
  adapty_flutter: ^1.0.4

Depois disso, execute:

flutter pub get

A partir deste ponto, é possível importar o Adapty SDK em seu aplicativo desta forma:

import 'package:adapty_flutter/adapty_flutter.dart';

Configuração

É preciso configurar seu aplicativo para trabalhar com o Adapty. Para isso, adicione a bandeira AdaptyPublicSdkKey com sua chave pública SDK no Info.plist (para iOS) ou no AndroidManifest.xml (para Android).

A chave SDK pode ser encontrada nas configurações do Adapty:

61dbfcaef59c49d11e233082 lsazt3ucjsc79arcgsxqdhss6j5t7gzc1ozj9kcwzet3 ouvcwuj

Info.plist:

&ltdict&gt
	...     
		&ltkey&gtAdaptyPublicSdkKey&lt/key&gt

AndroidManifest.xml:

&ltapplication ...&gt
        ...
        &ltmeta-data
               android:name="AdaptyPublicSdkKey"
               android:value="PUBLIC_SDK_KEY" /&gt
 &lt/application&gt

Em seguida, ative o SDK usando este código no lado Flutter – por exemplo, no método principal() do seu projeto:

void main() {
   runZoned(() async {
     Adapty.activate();
     final installId = await Service.getOrCreateInstallId();
     await Adapty.identify(***customer-user-id***);
     await Adapty.setLogLevel(AdaptyLogLevel.verbose);
     runApp(MyApp());
  });
 }

A função Adapty.activate() vazia ativa a biblioteca Adapty_Flutter:

Future&ltbool&gt Adapty.identify(String customerUserId)

O Adapty.identify permite que você recupere a identificação do usuário. O Adapty a envia para os sistemas de assinatura e de analytics para atribuir eventos a este perfil. Você também poderá encontrar seus clientes pelo customerUserId em Perfis.

O Adapty registra mensagens de erro e outros dados importantes para ajudá-lo a entender o que está acontecendo.

Future&ltvoid&gt Adapty.identify(AdaptyLogLevel value)

A função permite que você escolha um dos três valores possíveis:

  • AdaptyLogLevel.none (a configuração padrão): nada será registrado.
  • AdaptyLogLevel.errors: somente as mensagens de erro serão registradas. 
  • AdaptyLogLevel.verbose: chamadas de método, solicitações de API e respostas, e também mensagens de erro serão registradas. 

Como recuperar os paywalls

Para recuperar a lista de paywall, execute o seguinte código:

try {
  final GetPaywallsResult getPaywallsResult = await Adapty.getPaywalls(forceUpdate: Bool);
  final List&ltAdaptyPaywall&gt paywalls = getPaywallsResult.paywalls;
 } on AdaptyError(adaptyError) {}
  catch(e) {}

A função Adapty.getPaywalls() retorna o objeto GetPaywallsResult que contém:

  • Paywalls: Uma matriz de paywall ( AdaptyPaywall ). O modelo contém a lista de produtos, a ID do paywall, a carga útil personalizada, entre outros valores.

Como comprar 

Na etapa anterior, você recuperou a matriz de paywall. Agora, vamos buscar exatamente o paywall necessário para exibir esses produtos em sua interface de usuário. Vamos supor que este paywall se chama your_paywall_id:

final List<AdaptyPaywall>? paywalls = getPaywallsResult.paywalls;
    myPaywall = paywalls?.firstWhere((paywall) => paywall.developerId == "your_paywall_id", orElse: null);

Em seguida, utilizando a matriz de produtos do campo de produtos, vamos exibir todos os itens. Digamos que o usuário queira comprar o primeiro produto. Por uma questão de simplicidade, vamos supor que ele seja o primeiro item da matriz de produtos. 

final AdaptyProduct? product = myPaywall?.products?.first;

Para iniciar a compra, use a função makePurchaseResult. (Lembre-se de colocar tudo em um bloco de tentativa de captura para ainda receber todas as mensagens de erro do SDK).

final MakePurchaseResult makePurchaseResult = await Adapty.makePurchase(product);

Assim que a função tiver sido executada com sucesso, a variável makePurchaseResult assumirá o resultado como seu valor. Veja como verificar o nível de acesso após a compra ter sido concluída:

final isPremium = makePurchaseResult?.purchaserInfo?.accessLevels['premium']?.isActive ?? false;

Convém observar que o AdaptyErrorCode.paymentCancelled significa que o próprio usuário cancelou a compra, portanto, não se trata, na verdade, de uma mensagem de erro. 

Para restaurar compras, use o método .restorePurchases():

try {
	final RestorePurchasesResult restorePurchasesResult = await Adapty.restorePurchases();
// "premium" is an identifier of default access level
  if (restorePurchasesResult?.purchaserInfo?.accessLevels['premium']?.isActive ?? false) {
  	// grant access to premium features
  }
} on AdaptyError catch (adaptyError) {}
catch (e) {}

Tenha em mente que os objetos MakePurchaseResult e RestorePurchasesResult incluem o objeto  purchaserInfo. Este objeto contém dados sobre níveis de acesso, assinaturas e compras. Normalmente, é possível saber se o usuário pode acessar os recursos premium do seu aplicativo apenas verificando seu nível de acesso.

Status da assinatura

Para evitar verificar toda a cadeia de transação anterior, vamos introduzir o termo “nível de acesso”. O nível de acesso é uma bandeira que explica o quanto da funcionalidade do aplicativo o usuário pode acessar. Caso o usuário não tenha realizado nenhuma compra, seu nível de acesso será nulo. Caso contrário, o nível de acesso será aquele que você especificou para o produto.

Por exemplo, você pode ter dois níveis de acesso, ou seja, prata e ouro. Compras diferentes irão desbloquear diferentes níveis de acesso e recursos. A maioria dos aplicativos tem apenas um nível de acesso.

Para saber se a assinatura está ativa, basta verificar se o usuário tem um nível de acesso ativo. Pode-se usar o método the.getPurchaserInfo() para fazer exatamente isso:

try {
	AdaptyPurchaserInfo purchaserInfo = await Adapty.getPurchaserInfo();
   // "premium" is an identifier of default access level
  if (purchaserInfo.accessLevels['premium']?.isActive ?? false) {
  	// grant access to premium features
  }
} on AdaptyError catch (adaptyError) {}
catch (e) {}

Você também pode assinar o fluxo .purchaserInfoUpdateStream para saber rapidamente qualquer mudança no nível de acesso do assinante. Veja como:

Adapty.purchaserInfoUpdateStream.listen((purchaserInfo) {
  print('#Adapty# Purchaser Info Updated');
	if (purchaserInfo.accessLevels['premium'].isActive) {
  	// grant access to premium features
  }
});

Subscribe to Adapty newsletter

Get fresh paywall ideas, subscription insights, and mobile app news every month!

Conclusão

Projetamos nosso SDK de forma a ajudá-lo a integrar rapidamente os pagamentos ao seu aplicativo.  Além disso, também tentamos simplificar todas as outras etapas que você possa precisar executar, como testes AB, analytics e outras integrações.

Forneceremos gratuitamente a funcionalidade completa de compra caso sua receita seja inferior a US$ 10.000 por mês. Economize meses de trabalho e concentre-se no que é mais importante: o seu produto.