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

Tutorial: cómo implementar las compras dentro de la aplicación en una aplicación Flutter

Alexey Goncharov

Updated: diciembre 9, 2023

14 min read

Content

62fdf15a5a9626b86649d085 jp android tutorial 1 configuration 6

Flutter es un framework relativamente nuevo desarrollado por Google que te permite crear rápidamente aplicaciones (app) multiplataforma. El otro framework popular es React Native de Facebook. Las aplicaciones Flutter se compilan para iOS y Android a la vez. Por tanto, una biblioteca de compras debe ser compatible tanto con StoreKit como con la Biblioteca de Facturación. 

Desde el punto de vista de la arquitectura, cualquier plugin de pago -incluido nuestro SDK de Adapty Flutter- es una envoltura alrededor de las bibliotecas nativas, StoreKit y Biblioteca de Facturación. En nuestro caso, es una envoltura alrededor de nuestras propias bibliotecas Adapty iOS y Android SDK

Bibliotecas de código abierto para compras dentro de la aplicación (in-app purchases) en aplicaciones basadas en Flutter

Las soluciones más populares para las compras en las aplicaciones de Flutter son los plugins de código abierto in_app_purchase (desarrollado por el equipo detrás de Flutter) y flutter_inapp_purchase (plugin no oficial). 

Estos plugins se crearon para implementar las compras del lado del cliente. No cuentan con la Verificación del recibo (receipt validation) del lado del servidor (server side). Tendrás que configurar tu propia infraestructura del lado del servidor para validar los recibos y recopilar los análisis de pago relativos a renovaciones, reembolsos, pruebas, cancelaciones, etc. 

Además, estas librerías suelen ser lentas a la hora de admitir nuevas funciones de la tienda. Por nombrar algunas, ahora mismo carecen de ofertas promocionales, de funciones de pago por uso y de la función de pago por adelantado (pay upfront) para iOS.

Ya que nuestra biblioteca se comunica con nuestro servidor, cuenta con todo esto:

  • Validación de compra del servidor; 
  • Soporte completo de funciones de pago nativas; 
  • Sintaxis DRY;
  • Análisis de suscripciones y compras y alguna otra recopilación de datos;
  • Pruebas A/B (A/B tests), así como la experimentación rápida con las compras, los precios y periodos de promoción;
  • Muros de pago (paywall) y ofertas promocionales (promo offer).

Para que este artículo sea breve y fácil de leer, vamos a vincular algunos artículos que hemos escrito anteriormente sobre algunos pasos que deberías dar antes de empezar a trabajar en las compras para tu aplicación Flutter.

Crear compras en iOS y Android

En primer lugar, tendrás que crear una cuenta de desarrollador si no tienes una. A continuación, tendrás que crear una compra semanal tanto para iOS como para Android. Hemos explicado cómo hacerlo en nuestros artículos anteriores:

Crear compras para iOS

Crear compras para Android

Una vez que hayas terminado, puedes empezar a crear y configurar tu proyecto.

Crear y configurar el proyecto

Para que tus compras funcionen tanto en tu aplicación como en nuestro sistema, tendrás que rellenar estos datos técnicos.

61dbfcadde3e1409fe5f8314 iy6l5yif4wtrzqfjzaek9s70lntdy9bul 7h6homozvwghjkvrzry8ohu9pva

Para iOS, necesitarás:

  • Especifica el ID del paquete para vincular tu proyecto Adapty a tu aplicación;
  • Configura las notificaciones del servidor del App Store en App Store Connect, para que puedas recibir notificaciones sobre los eventos de suscripción;
  • Especifica el secreto compartido de App Store, que el servidor de Adapty utilizará para establecer una conexión con los servidores de Apple y validar los recibos.

Para Android, hay que especificar tanto el Nombre del Paquete como el Archivo de Clave de la Cuenta de Servicio. El nombre del paquete es el ID del paquete de iOS para Android. Debes utilizar el mismo que se usa en el código. Se encuentra en el archivo /android/app/build.gradle, situado en el directorio android.defaultConfig.applicationId.

Configurar los productos y muros de pago

Un producto de Adapty encapsula los de varias tiendas. Por ahora sólo se trata de App Store y Google Play, pero en el futuro introduciremos otras tiendas. La idea de este enfoque es facilitar la recopilación de estadísticas entre plataformas, así como permitirte trabajar con entidades de nivel superior, en vez de con identificadores.

El Muro de pago (Paywall) es una entidad abstracta que contiene una matriz de productos y un archivo de configuración remoto (que es un archivo JSON que contiene los metadatos que has especificado en tu dashboard). Debes codificar de forma rígida el ID del muro de pago en tu aplicación: este ID se utiliza para recuperar el archivo de configuración y los datos del producto. Puedes editar ambos sin tener que actualizar la aplicación. En el escenario habitual, diseñas el muro de pago y lo rellenas con los datos que recibes de nosotros.

Crear un producto

Utilicemos Google Play Console y App Store Connect para crear un producto que corresponda a una suscripción semanal. Rellena el ID de los productos correspondientes, que puedes recuperar de los sistemas de pago. Es importante tener en cuenta que, como App Store Connect no tiene API, tendrás que hacerlo manualmente. Eso sí, sólo una vez. 

61dbfcadc56e16884ceeda5a 34mxwyuolr8iv5x2uec0mz6

Crear un muro de pago

Al crear un muro de pago, lo fundamental es especificar su ID en el formato conveniente. Este identificador será utilizado posteriormente por el SDK para solicitar los datos del muro de pago. Creemos que este es un buen enfoque: Con esta arquitectura, no hay necesidad de codificar de forma rígida tus productos en el lado del cliente. Puedes ser flexible con la gestión de tus productos, el versionado, las pruebas, etc. La opción alternativa sería Firebase JSON con un conjunto de productos incorporados. Sin embargo, esto no proporciona validación de errores y no es tan fácil de usar.

61dbfcae9d2b62d615559378 zn55mgmaz86h7qtmlow pxcwlspih63ifgswsurxtydhjlqyj3gm jqtzo vk8bvb3txn29f7g2oe6o2voyadhruy1lhyyvqvuo6ms5ytfq

¡Listo! Después de haber creado un producto y un muro de pago, ya estás listo para tu primera compra. Procedamos a instalar el SDK.

¿Cómo utilizar el SDK?

Veamos las principales funciones que necesitaremos para configurar y utilizar las suscripciones.

Instalar la biblioteca

En primer lugar, tendrás que añadir la biblioteca adapty_flutter a tu proyecto. Para ello, añade la siguiente dependencia a tu archivo pubspec.yaml:

dependencies:
  adapty_flutter: ^1.0.4

Después, ejecuta:

flutter pub get

Desde aquí, puedes importar el SDK de Adapty a tu aplicación así:

import 'package:adapty_flutter/adapty_flutter.dart';

Configuración

Tendrás que configurar tu aplicación para que funcione con Adapty. Para ello, añade la marca AdaptyPublicSdkKey con tu clave pública del SDK en Info.plist (para iOS) o en AndroidManifest.xml (para Android).

Puedes encontrar tu clave de SDK en Adapty settings:

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

A continuación, activa el SDK invocando este código en el lado de Flutter, por ejemplo, en el método main() de tu proyecto:

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

La función vacía Adapty.activate() activa la biblioteca Adapty_Flutter:

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

Adapty.identify te permite recuperar el identificador del usuario. Adapty lo envía a los sistemas de suscripción y análisis para asignar los eventos a este perfil. También podrás encontrar a tus clientes por customerUserId enProfiles.

Adapty registra los mensajes de error y otros datos importantes para ayudarte a entender lo que está pasando.

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

La función te permite elegir uno de los tres valores posibles:

  • AdaptyLogLevel.none (la configuración por defecto): no se registrará nada.
  • AdaptyLogLevel.errors: sólo se registrarán los mensajes de error. 
  • AdaptyLogLevel.verbose: se registrarán las llamadas al método, las peticiones y respuestas de la API y los mensajes de error. 

Subscribe to Adapty newsletter

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

Recuperar los muros de pago

Para recuperar la lista de los muros de pago, ejecuta este código:

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

La función Adapty.getPaywalls() devuelve el objeto GetPaywallsResult que contiene:

  • Muros de pago: Un conjunto de muros de pago ( AdaptyPaywall ). El modelo contiene la lista de productos, el ID del muro de pago, la carga útil personalizada y algunos otros valores.

Hacer compras 

En el paso anterior, has recuperado la matriz de pago. Ahora, buscaremos el que necesitas para mostrar esos productos en tu interfaz de usuario. Supongamos que este muro de pago se denomina your_paywall_id:

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

A continuación, utilizando la matriz de productos del campo productos, muestra todos sus elementos. Digamos que el usuario quiere comprar el primer producto. Para simplificar, supondremos que es el primer elemento de la matriz de productos. 

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

Una vez ejecutada la función con éxito, la variable makePurchaseResult adoptará el resultado como valor. A continuación te explicamos cómo comprobar el nivel de acceso una vez finalizada la compra: 

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

Para iniciar la compra, invoca la función makePurchaseResult. (Recuerda envolver esto en un bloque try-catch para seguir recibiendo todos los mensajes de error del SDK).

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

Ten en cuenta que AdaptyErrorCode.paymentCancelled significa que el usuario ha cancelado la compra él mismo, lo que significa que no es un mensaje de error real. 

Para restaurar las compras, utiliza el 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) {}

Ten en cuenta que tanto los objetos MakePurchaseResult como RestorePurchasesResult incluyen purchaserInfo. Este objeto contiene datos sobre los niveles de acceso, las suscripciones y compras. Normalmente, puedes saber si el usuario puede acceder a las funciones premium de tu aplicación simplemente comprobando su nivel de acceso.

Estado de la suscripción

Para evitar tener que comprobar toda la cadena de transacciones anterior, vamos a introducir el término «nivel de acceso». El nivel de acceso es una marca que explica a qué parte de la funcionalidad de la aplicación puede acceder el usuario. Si aún no ha realizado ninguna compra, su nivel de acceso será nulo. De lo contrario, será el que hayas especificado para tu producto.

Por ejemplo, puedes tener dos niveles de acceso, a saber, silver y golden. Diferentes compras desbloquearán diferentes niveles de acceso y funciones. La mayoría de las aplicaciones sólo tienen un nivel de acceso.

Para ver si la suscripción está activa, es suficiente comprobar si el usuario tiene un nivel de acceso activo. Para ello puedes utilizar el método. the.getPurchaserInfo():

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) {}

También puedes suscribirte al stream .purchaserInfoUpdateStream para enterarte puntualmente de cualquier cambio en el nivel de acceso del suscriptor. Aquí te explicamos cómo: 

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

Conclusión

Hemos diseñado nuestro SDK de forma que te ayude a integrar rápidamente los pagos en tu aplicación.  Además, hemos intentado simplificar todos los demás pasos que puedas necesitar, como las pruebas AB, los análisis y otras integraciones.

Te proporcionaremos la funcionalidad de compra completa de forma gratuita si tus ingresos ascienden a menos de 10.000 $ al mes. Ahórrate meses de trabajo y céntrate en lo más importante: tu producto.

Socio informativo: Todascasasdeapuestas.com