ITEM_ALREADY_OWNED de la Facturación de Google Play corresponde al código de respuesta 7. Significa que Google Play considera que la suscripción o el producto de compra única enviado a launchBillingFlow() ya pertenece al usuario. La información de compra obsoleta del dispositivo también puede provocar esta respuesta de forma inesperada. En aplicaciones Android que usan la Biblioteca de Facturación de Google Play, la primera medida más segura es llamar a queryPurchasesAsync() para el tipo de producto correspondiente. No concedas derechos de acceso ni reintentes basándote únicamente en el código 7.
Qué significa el código de respuesta 7 ITEM_ALREADY_OWNED
BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED tiene el valor numérico 7, como confirma la referencia de la API BillingResponseCode. Puede devolverse mediante BillingResult cuando se llama a launchBillingFlow() para una suscripción o un producto de compra única que ya pertenece a la cuenta de Google Play.
Hay dos ramas principales de diagnóstico:
- Propiedad real: Play informa de una compra activa que la aplicación debe reconocer y cuya entrega no debe realizar dos veces.
- Estado de compra obsoleto en Play: la información de compra del dispositivo no refleja el estado más reciente del backend, por lo que aparece el código 7 aunque una consulta actualizada no devuelva el producto como propiedad del usuario.
La aplicación también puede estar ofreciendo un producto que el usuario ya posee, y unos parámetros incorrectos de launchBillingFlow() pueden provocar este error. La respuesta por sí sola no demuestra que exista un estado PURCHASED actual. Usa el resultado de la consulta de compras y los registros de derechos de la aplicación para tomar esa decisión.
Consultar las compras para distinguir la propiedad de un estado obsoleto de Play
Cuándo corresponde: aplica primero este procedimiento después de recibir ITEM_ALREADY_OWNED en el flujo de compra de una suscripción o un producto de compra única.
Requisitos previos: BillingClient debe estar conectado y la aplicación debe saber si consulta una suscripción o un producto de compra única. Con la versión 8.x de la Biblioteca de Facturación, usa la forma actual queryPurchasesAsync(QueryPurchaseParams, ...); se eliminó la sobrecarga anterior basada en cadenas.
- Llama a
queryPurchasesAsync()después de recibir el código 7. La referencia de la API BillingClient documenta la API actual del cliente. - Examina las compras actualizadas para localizar el producto relacionado con el flujo fallido.
- Si el producto aparece como propiedad del usuario, verifica el estado de la compra y concílialo con el derecho existente. Deja de ofrecer el producto para su compra.
- Si el resultado actualizado no muestra el producto como propiedad del usuario, sigue la rama de caché obsoleta descrita más adelante y permite como máximo un reintento.
Resultado esperado: la aplicación identifica una compra cuya propiedad está verificada o un estado actualizado en el que el producto no aparece como propiedad del usuario.
Riesgo y reversión: el riesgo es bajo porque se trata de una operación de lectura y conciliación. No requiere eliminar registros locales ni borrar los datos de Google Play Store. Si se confirma la propiedad, detén el flujo de compra y cualquier reintento pendiente.
Conciliar la propiedad en Play con los derechos de la aplicación
Cuándo corresponde: usa este procedimiento cuando la consulta actualizada de compras confirme la propiedad o cuando la interfaz de compra y los registros de derechos del cliente o del backend no coincidan.
Requisitos previos: la aplicación debe disponer del resultado actualizado de la compra en Play y tener acceso a los datos de derechos del cliente o del backend que use habitualmente. Los detalles de implementación del backend dependen de cada aplicación y deben verificarse de acuerdo con su propio diseño de procesamiento seguro.
- Compara la compra actualizada de Play con los registros actuales de derechos del cliente y del backend de la aplicación.
- Concede o conserva el acceso solo después de verificar el estado de compra correspondiente. Haz que la entrega sea idempotente para que una misma compra detectada por el cliente y por el procesamiento del backend no se conceda dos veces.
- Oculta o desactiva las opciones de compra de las suscripciones y los productos de compra única no consumibles que ya pertenecen al usuario.
- En el caso de los consumibles, mantén desactivada la opción de compra hasta que se confirme el consumo.
- Mantén sincronizado el estado de propiedad mostrado con Play y con el estado de derechos que la aplicación considere autoritativo.
Resultado esperado: un producto que realmente pertenece al usuario tiene el derecho correcto y no vuelve a ofrecerse, mientras que un producto que no le pertenece no se trata incorrectamente como comprado.
Riesgo y reversión: el riesgo es bajo si no se concede ningún derecho basándose únicamente en el código 7. Vuelve a habilitar un producto solo cuando el derecho correspondiente deje de estar activo o, si es consumible, después de confirmar su consumo. No elimines registros locales de derechos como sustituto de la conciliación.
Cuándo corresponde reintentar una vez después de ITEM_ALREADY_OWNED
Cuándo corresponde: reintenta únicamente cuando queryPurchasesAsync() haya actualizado el estado de compra y el resultado siga sin mostrar el producto como propiedad del usuario.
Requisitos previos: la consulta de compras debe haber finalizado, la propiedad debe seguir sin confirmarse y la aplicación no debe haber concedido derechos a partir de la respuesta de error.
- Trata la respuesta inicial con el código 7 como una posible señal para actualizar la caché únicamente en esta rama sin propiedad confirmada.
- Confirma que el resultado actualizado de la compra no incluya el producto como propiedad del usuario.
- Vuelve a ejecutar
launchBillingFlow()una sola vez mediante una lógica de reintento sencilla. - Detén el proceso si se confirma la propiedad o si ese único reintento no recupera el flujo.
Resultado esperado: una compra bloqueada únicamente por información obsoleta del dispositivo puede continuar después de la actualización. La mayoría de las respuestas con código 7 no deben tratarse como transitorias.
Riesgo y reversión: el riesgo es bajo cuando el reintento se limita a la condición documentada. No hay ninguna reversión destructiva. Detén el proceso de inmediato si se confirma la propiedad y no crees un bucle de reintentos inmediato, repetido, exponencial ni indefinido. Esta secuencia sigue las indicaciones de Google para recuperarse de ITEM_ALREADY_OWNED.
Confirmar o consumir la compra según el tipo de producto
La confirmación y el consumo no son intercambiables. La operación correcta depende de si el producto es una suscripción, un producto de compra única no consumible o un producto de compra única consumible.
Confirmar suscripciones y productos no consumibles
Cuándo corresponde: usa la confirmación para las suscripciones y los productos no consumibles que deben seguir perteneciendo al usuario.
Requisitos previos: el estado de compra es PURCHASED, se ha concedido el derecho correspondiente y la compra aún no se ha confirmado.
- Verifica el estado
PURCHASED. - Concede el derecho sin duplicar ninguna entrega que ya se haya realizado.
- Confirma la compra lo antes posible después de conceder el derecho.
- Usa
acknowledgePurchase()para el procesamiento exclusivo en el cliente o la API de Google Play Developer en un backend seguro.
Resultado esperado: la suscripción o el producto no consumible verificado sigue perteneciendo al usuario y deja de ofrecerse para su compra.
Riesgo y reversión: el riesgo es bajo. Si la compra ya está confirmada, no realices ninguna otra acción de confirmación. Nunca consumas una suscripción ni un producto no consumible para eliminar el código 7.
Consumir los productos consumibles antes de permitir otra compra
Cuándo corresponde: usa el consumo únicamente para un producto diseñado expresamente para comprarse varias veces.
Requisitos previos: el artículo del catálogo debe ser consumible y ya debe haberse concedido el derecho correspondiente a la compra actual.
- Verifica la compra y concede el beneficio consumible.
- Consume la compra con
consumeAsync()para el procesamiento exclusivo en el cliente o conPurchases.products:consumeen un backend seguro. - Confirma el consumo antes de mostrar el producto como disponible para volver a comprarlo.
- Evita duplicar la entrega si la misma compra se detecta más de una vez.
Resultado esperado: el usuario recibe el beneficio consumible actual y el producto solo puede volver a comprarse después del consumo.
Riesgo y reversión: el riesgo es bajo cuando la clasificación del catálogo es correcta. El consumo no debe realizarse antes de la entrega. Si la compra ya se consumió, no repitas la entrega únicamente porque vuelva a detectarse un resultado de propiedad.
Validar la recuperación sin conceder acceso dos veces
Cuándo corresponde: usa este procedimiento en un entorno de pruebas de Google Play después de implementar las consultas de propiedad, la conciliación de derechos, el filtrado de productos, el reintento condicional y la ruta correcta de confirmación o consumo.
Requisitos previos: debe haber una cuenta de verificador de licencias en el dispositivo Android, la aplicación debe instalarse con esa cuenta y el verificador debe poder observar los cuadros de diálogo de compra de Play y el estado de derechos de la aplicación.
- Realiza una compra de prueba con la cuenta de verificador de licencias.
- Comprueba que la consulta actualizada de compras, los derechos de la aplicación, el registro del backend y la interfaz de compra coincidan.
- Para una suscripción o un producto no consumible, confirma la compra dentro del plazo de tres minutos para verificadores de licencias; de lo contrario, se reembolsará la compra de prueba.
- Para un consumible, confirma que la entrega se realice antes del consumo y que el artículo solo vuelva a aparecer para su compra después del consumo.
- Usa Play Billing Lab cuando necesites acelerar la renovación de suscripciones o los cambios de estado.
- Repite la actualización normal del estado de compra de la aplicación y confirma que las devoluciones de llamada duplicadas o el procesamiento del backend no concedan el derecho dos veces.
- Confirma que una suscripción o un producto no consumible que ya pertenece al usuario no tenga una opción de compra activa y que la lógica de reintento se detenga después del único intento documentado.
Resultado esperado: la propiedad, los derechos, la confirmación o el consumo y el estado de la interfaz de compra permanecen sincronizados sin duplicar la entrega.
Riesgo y reversión: el riesgo es bajo en el entorno de pruebas designado. Cancela la compra de prueba o permite que caduque o se reembolse conforme a las reglas de prueba aplicables. No uses compras de clientes en producción para realizar pruebas destructivas.
No uses el borrado de datos de Play Store, la eliminación de derechos locales, los reintentos repetidos ni el consumo sin verificación como reparaciones principales. Estas acciones no demuestran de forma segura la propiedad y pueden ocultar un defecto en la conciliación de derechos.
Límite de versión e implementación: esta guía usa la versión 8.x de la Biblioteca de Facturación y la terminología actual de las API compatibles. El momento exacto en que se actualiza una caché obsoleta varía según el dispositivo y la versión de Play Store, mientras que la clasificación de productos y la conciliación con el backend dependen de cada aplicación y requieren verificación en la implementación.

