What does Play Billing ITEM_ALREADY_OWNED (7) mean?
Play Billing ITEM_ALREADY_OWNED (7) means the user already owns the subscription or one-time product they tried to buy.
Quick facts#
| Error | BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED (7) |
| Where | Google Play Billing Library (BillingResult.responseCode) |
| What the vendor says | The purchase failed because the item is already owned. |
Cause#
- Google says the Google Play user already owns the product. In most cases this is not transient, except when stale purchase data cached by Play causes it.
- A stale cache is refreshed when you receive the error, so a retry after the refresh can succeed.
- Your app offered a product the user owns because it did not check what the user already has.
Fix#
- Call
queryPurchasesAsync()after the error to see what the user owns, and process those purchases (grant access, acknowledge or consume). - If the user does not own the product after that, retry the purchase once; the cache has been updated.
- Prevent it: check the user's entitlements when you list products, and do not offer products the user already owns.
- Tell the person "You already have this" instead of showing a failure.
Example#
Kotlin
import com.android.billingclient.api.BillingClient
import com.android.billingclient.api.BillingResult
import com.android.billingclient.api.QueryPurchasesParams
// Treat ITEM_ALREADY_OWNED as good news: fetch what the user owns and grant it (Google's recommended fix).
fun onPurchaseResult(client: BillingClient, result: BillingResult) {
if (result.responseCode == BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED) {
val params = QueryPurchasesParams.newBuilder().setProductType(BillingClient.ProductType.SUBS).build()
client.queryPurchasesAsync(params) { queryResult, purchases ->
if (queryResult.responseCode == BillingClient.BillingResponseCode.OK) {
purchases.forEach { println("Already owned: ${it.products}") }
}
}
}
}Not compiled: this Kotlin snippet was not built here because the docs repo has no Kotlin or Android toolchain. Check it against your Play Billing Library or SDK version before you ship it.
How the RevenueDot SDK reports it#
The RevenueDot purchases-android fork maps ITEM_ALREADY_OWNED to PurchasesErrorCode.ProductAlreadyPurchasedError (code 6). Call restorePurchases() or getCustomerInfo() to give the customer the entitlement they already paid for. See what productAlreadyPurchasedError means.
Related#
- What does Play Billing ITEM_NOT_OWNED (8) mean?
- What does productAlreadyPurchasedError (code 6) mean in the purchases SDK?
- What does Play Billing BILLING_UNAVAILABLE (3) mean?
Source#
- Google: BillingResponseCode.ITEM_ALREADY_OWNED
- Google: Handle BillingResult response codes
- RevenueDot purchases-android: google/errors.kt (how the SDK maps response codes)
Checked: 2026-10-03