Subscriptions 101: learn how to get +23% app revenue Read more

Las compras dentro de la aplicación de Android, parte 4: facturación de los Códigos de Error de la Biblioteca y cómo no fallar en las pruebas.

Vlad Guriev

September 6, 2022

14 min read

Table of Contents

62fdf1acd9ba1f688246e39e jp android tutorial 1 configuration 3

Hoy hablaremos de los códigos de error que podemos obtener de la Biblioteca de Facturación en el método getResponseCode().

Puedes encontrar un ejemplo de cómo pasamos los errores en nuestras devoluciones de llamada en este artículo. Ya hemos considerado uno de los errores en artículos anteriores: se trata de USER_CANCELED cuando un usuario cierra el diálogo de compra sin comprar nada. Conozcamos a los demás.

ERROR y DEVELOPER_ERROR

Empecemos con los errores llamados ERROR (responseCode 6) y DEVELOPER_ERROR (responseCode 5). Para el primer caso, Google escribe en la documentación “Error fatal durante la acción de la API”, para el segundo – “Argumentos no válidos proporcionados a la API”. Por ejemplo, pude obtener un DEVELOPER_ERROR cuando pasé una cadena vacía al constructor en setType() para la solicitud querySkuDetailsAsync().

Pero no es tan simple. Fui más allá y en el método launchBillingFlow() utilicé el SkuDetails modificado (extraje el json de SkuDetails del producto real, cambié el productID en él y lo pasé al nuevo constructor SkuDetails). De hecho, es un argumento no válido, y esperaba obtener un DEVELOPER_ERROR, pero … Tengo un ERROR.

Esto, por supuesto, era un ejemplo artificial. El caso en el que Google rechazó el pago es mucho más cercano a la realidad. Si seleccionas “tarjeta de prueba, siempre rechazada” en el diálogo de compra al probar las compras con una tarjeta de prueba, de lo que te hablaremos al final del artículo, también volverá el ERROR, pero con un texto adecuado.

En el tercer artículo, donde se describía el cambio de suscripción, aumentamos el precio de una suscripción anual casi 3 veces para uno de los modos de prorrateo, pero no dijimos qué error debería haber habido si no hubiéramos hecho eso. Estamos reparando los daños.

Como resulta que allí se especifica un modo de prorrateo erróneo, lógicamente deberíamos obtener el mismo DEVELOPER_ERROR. En su lugar, obtenemos SERVICE_UNAVAILABLE (responseCode 2). También lo conseguimos si introducimos cualquier número inadecuado como modo de prorrateo (esto es int, no enum, nadie nos lo impedirá), y si especificamos un PurchaseToken incorrecto. Consultamos la documentación sobre SERVICE_UNAVAILABLE y … espera, ¿qué? Vemos que la “Conexión de red está inactiva”.

Al mismo tiempo, también vemos un extraño diálogo:

615371cbae3a194fdd67617c 5n7uqaw9bx5dejwxgqh9sluv3r38yqwegbzbnzj5db9bullr12o2uraffoyko2jn4pjwhsy04xwdwrwxt37pkvgt3q1zgtblivzbagg 91v1ogagpaptqj

Otra cosa interesante en el caso del ERROR es que al cerrar el diálogo NO a través del botón “OK” (es decir, por medios que se interpretan como “navegar de vuelta”), el ERROR llega a onPurchasesUpdated(), y en el caso de SERVICE_UNAVAILABLE en una situación similar llega USER_CANCELED (pero si se hace clic en “OK” en el diálogo, recibiremos SERVICE_UNAVAILABLE, como se esperaba).

Y en el caso de pérdida de conexión a Internet, de hecho, viene SERVICIO_DISPONIBLE.

Códigos de error

Aquí hay más códigos de error con pequeños comentarios, por así decirlo, menciones honoríficas.

  • BILLING_UNAVAILABLE (responseCode 3). Google explica que “La versión de la API de facturación no es compatible con el tipo solicitado”. He podido reproducir este error al cerrar la sesión de mi cuenta de Google, así como al utilizar un dispositivo Huawei sin los servicios de Google Play. También puede reproducirse en teléfonos antiguos en los que no se ha actualizado Google Play.
  • SERVICE_DISCONNECTED (responseCode -1). La aplicación se desconecta a veces del servicio de Google Play. Esto puede ocurrir si Play Store se actualiza inesperadamente. Por lo tanto, te aconsejo que vayas a lo seguro y te conectes antes de cada llamada de los métodos de la Biblioteca de Facturación, como en los artículos anteriores. Además, tanto Google como nosotros te aconsejamos que añadas alguna política de reintentos si este error sigue apareciendo en la respuesta.
  • SERVICE_TIMEOUT (responseCode -3). El nombre habla por sí mismo: llevamos demasiado tiempo esperando una respuesta de Google Play.
  • FEATURE NOT SUPPORTED. Hay cinco constantes FeatureType en la clase BillingClient. Su disponibilidad en este dispositivo puede comprobarse utilizando el método  BillingClient.isFeatureSupported(BillingClient.FeatureType.A_NECESSARY_FEATURE). En mi teléfono (Xiaomi Mi A2 Lite), FEATURE_NOT_SUPPORTED ha vuelto sólo para SUBSCRIPTIONS_ON_VR. Al mismo tiempo, para IN_APP_ITEMS_ON_VR, así como para todas las demás funciones, ha vuelto el OK.
  • ITEM_NOT_OWNED (responseCode 8). Se produce al intentar consumir una compra que no tenemos. Posiblemente, incluso repetidamente después de un consumo exitoso.
  • ITEM_ALREADY_OWNED (responseCode 7). Y aquí, por el contrario, el error se produce al intentar comprar un producto que ya tenemos. En ese caso, sólo tienes que actualizar la interfaz de usuario y hacer que el botón de compra no sea clicable.

ITEM_UNAVAILABLE

El último error, y probablemente el más popular, al principio de la ruta de implementación de las compras dentro de la aplicación es ITEM_UNAVAILABLE (responseCode 4). Indica que el producto no está disponible para su compra, pero no explica por qué. Las razones pueden ser muy diferentes: desde probarlo en una cuenta o dispositivo equivocado hasta comprar un producto inactivo.

Aquí tienes una lista de comprobación de lo que tienes que hacer para evitar este error durante las pruebas:

1. Envía una aplicación con la Biblioteca de Facturación a tu pista de pruebas. Esta es una condición obligatoria; al mismo tiempo, también puedes probar en compilaciones de depuración con el mismo applicationId, pero es importante que la aplicación con la Biblioteca de Facturación se cargue en la Play Console al menos una vez.

2. Añade las cuentas de Google de los probadores a esta pista de pruebas, lo que es especialmente importante para las pruebas internas o las alfa/beta cerradas. También habrá un enlace en la sección Cómo se unen los probadores a tu prueba, donde los probadores deben aceptar la invitación.

3. Sólo puedes comprar un producto activado. Después de crear un producto, hay un botón de activación en Play Console. En el primer artículo describimos más detalladamente el proceso de creación de un producto.

4. Asegúrate de que las pruebas en el dispositivo se realizan desde la cuenta de Google de un probador (lo que significa que debe estar inscrito como probador en esta pista de pruebas y debe tener todos los accesos técnicos necesarios). Este punto parece obvio, pero las cosas suceden, y también tienes que comprobarlo si has recibido un error de este tipo.

5. El applicationId de la compilación que se utiliza para las pruebas de compra debe coincidir completamente con el applicationId de Play Console. Esto es especialmente importante para aquellos que tienen un sufijo añadido en sus compilaciones de depuración.

6. Añade las direcciones de correo electrónico de los probadores a la sección Setup → License Testing en el menú izquierdo de la cuenta (no de la aplicación), a fin de que compren productos gratis desde una tarjeta de prueba, y no desde una real. Otra ventaja es que las suscripciones en este caso tendrán una duración de prueba. No está relacionado con este error, pero también es un conocimiento útil.

Conclusión

Los errores pueden complicar mucho el trabajo, por lo que siempre es importante entender cómo pueden producirse. Teniendo en cuenta la cantidad de pasos que hay que dar para acceder a los productos, lo más fácil es detectar el ITEM_UNAVAILABLE. Por tanto, espero que mi lista de comprobación te ayude.

El SDK de Adapty facilitará el manejo de errores y proporcionará muchas otras ventajas: análisis básico de suscripciones, análisis de cohortes  (cohort analysis), pruebas sencillas de los muros de pago (paywall), integración con servicios de análisis, validación de errores del servidor. ¡Pruébalo ahora!