Tutorial: como implementar compras em um aplicativo com Flutter
Updated: March 20, 2023
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:
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.
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.
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.
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:
Info.plist:
<dict>
...
<key>AdaptyPublicSdkKey</key>
AndroidManifest.xml:
<application ...>
...
<meta-data
android:name="AdaptyPublicSdkKey"
android:value="PUBLIC_SDK_KEY" />
</application>
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<bool> 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<void> 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<AdaptyPaywall> 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
}
});
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.