SDK error · code 6

productAlreadyPurchasedError (error code 6): Product already purchased

What it means

productAlreadyPurchasedError (code 6) means the customer already owns this product, so the store refused to sell it again. Restore purchases or refresh customer info to give them the entitlement they already paid for. On Google Play it is ITEM_ALREADY_OWNED, which can also be a stale cache or an unacknowledged purchase.

Code

6

iOS (Swift)

ErrorCode.productAlreadyPurchasedError

Android (Kotlin)

PurchasesErrorCode.ProductAlreadyPurchasedError

Causes

Why the SDK returns productAlreadyPurchasedError

  • StoreKit 1: an unknown SKError whose underlying ASD error is 3532 (currently subscribed), which the SDK maps to productAlreadyPurchasedError (source).
  • Android: Play Billing ITEM_ALREADY_OWNED. Google says it is usually permanent but can be a cache issue, and recommends querying purchases with queryPurchasesAsync() (Google docs).
  • Android: the backend answered 7852 (a web purchase that belongs to another user), which the Android SDK maps here (errors.kt). iOS maps 7852 to purchaseBelongsToOtherUser.
  • Amazon Appstore: Amazon answered ALREADY_PURCHASED for the purchase request.
Backend codeMeaning
7852Purchase belongs to another user. Android maps it to productAlreadyPurchasedError; iOS maps it to purchaseBelongsToOtherUser.

Fix

How to fix productAlreadyPurchasedError

  1. 01

    Refresh customer info

    Call getCustomerInfo and check the entitlement. If it is active, the customer already has access, so close the paywall.

  2. 02

    Restore purchases

    If the entitlement is not active, call restorePurchases() so the SDK posts the owned purchase. See how to restore purchases.

  3. 03

    Acknowledge or consume on Android

    A non-consumable that was never acknowledged, or a consumable that was never consumed, stays owned and blocks a second purchase. Let the SDK post the purchase, or finish it with Play.

  4. 04

    Hide the buy button for owners

    Check the entitlement before you show a paywall, so owners never see a purchase button for a product they have.

In your app

How to handle it in code

  • Do not retry the purchase. It will fail again.
  • Treat it as good news: tell the customer "You already have this" and refresh their access with restore or customer info.
  • Grant access only after customer info shows the entitlement active, not because of this error.
Match the errorSwift · Kotlin
// Swift
do {
  let result = try await Purchases.shared.purchase(package: package)
} catch let error as ErrorCode where error == .productAlreadyPurchasedError {
  // handle product already purchased
}

// Kotlin
if (error.code == PurchasesErrorCode.ProductAlreadyPurchasedError) { /* ... */ }

On RevenueDot: When a web purchase has already been redeemed by another app user, RevenueDot answers 7852. The iOS SDK reports that as purchaseBelongsToOtherUser (code 40) and the Android SDK as this error.

FAQ

productAlreadyPurchasedError: questions people ask

What does ITEM_ALREADY_OWNED mean?

Google Play says the customer already owns the product. It is usually permanent, but a stale purchase cache can cause it too, so query purchases again before you decide (Google docs).

How do I fix productAlreadyPurchasedError?

Refresh customer info and call restorePurchases. The customer already owns the product, so the fix is to give them the access they paid for, not to sell it again.

How do I check for productAlreadyPurchasedError in React Native and Flutter?

In React Native, compare error.code with PURCHASES_ERROR_CODE.PRODUCT_ALREADY_PURCHASED_ERROR. In Flutter, convert the PlatformException with PurchasesErrorHelper.getErrorCode(e) and compare the result with PurchasesErrorCode.productAlreadyPurchasedError.

Get started

Keep the RevenueCat SDK. Change the backend.

RevenueDot answers the same SDK calls with the same error codes. Start free on RevenueDot Cloud, free up to $10,000 a month in tracked revenue.

Already have an account? Sign in · Prefer your own servers? Self-host free