RevenueCat

Build With RevenueCat

Build a customized mobile subscription business with RevenueCat. We do the heavy lifting of normalizing subscribers from any source and maintain a single source of truth for subscription status, so you can get back to building your app.

RevenueCat is a powerful, secure, reliable, and free to use in-app purchase server with global support. All you need to get started is an API key.

Get Started    API Reference

Error Handling

Handling errors in Purchases SDK

👍

This section assumes you've followed our Quickstart section of our Getting Started guide to install and configure our SDK.

If the completion callbacks or listeners on asynchronous methods receive an error argument that is not nil, an error has occurred.

With the exception of NetworkError, PurchaseCancelledError or StoreProblemError, retrying a failed operation with the same arguments won't succeed. For failed purchases, assume the user wasn't charged, unless a StoreProblemError occurred - in which case the user may or may not have been charged.

iOS Errors

On iOS, when an error has occurred the completion callback will receive an NSError object.

When investigating or logging errors, review the userInfo dictionary, paying attention to the following keys:

  • RCReadableErrorCodeKey contains a cross-platform error name string that can be used for identifying the error.
  • NSLocalizedDescriptionKey contains a description of the error. This description is meant for the developer.
  • NSUnderlyingErrorKey contains the underlying error that caused the error in question, if an underlying error is present.

Examples:

if let err = error as NSError? {
                
    // log error details
    print("Error: \(err.userInfo[ReadableErrorCodeKey])")
    print("Message: \(err.localizedDescription)")
    print("Underlying Error: \(err.userInfo[NSUnderlyingErrorKey])")

    // handle specific errors
    switch Purchases.ErrorCode(_nsError: err).code {
    case .purchaseNotAllowedError:
        showAlert("Purchases not allowed on this device.")
    case .purchaseInvalidError:
        showAlert("Purchase invalid, check payment source.")
    default:
        break
    }
}
if (error) {

    // log error details
    NSLog(@"RCError: %@", [error.userInfo objectForKey:RCReadableErrorCodeKey]);
    NSLog(@"Message: %@", error.localizedDescription);
    NSLog(@"Underlying Error: %@", [error.userInfo objectForKey:NSUnderlyingErrorKey]);

    switch ([error code]) {
        case RCNetworkError:
            showError(@"Network error, check your connection and try again.");
        case RCPurchaseNotAllowedError:
            showError(@"Purchases not allowed on this device.");
        case RCPurchaseInvalidError:
            showError(@"Purchase invalid, check payment source.");
        default:
            break;
    }

}

Android Errors

On Android, when an error has occurred the onError listener will receive a PurchasesError object.

When investigating or logging errors, reveiw the properties of PurchasesError:

  • code contains the PurchasesErrorCode that can be used for identifying the error.
  • message contains a description of the error. This description is meant for the developer.
  • underlyingErrorMessage contains a description of the underlying error that caused the error in question, if an underlying error is present.

Examples:

with(error) {
    // log error details
    print("Error: $code")
    print("Message: $message")
    print("Underlying Error: $underlyingErrorMessage")
    when (code) {
        PurchasesErrorCode.PurchaseNotAllowedError -> {
            showAlert("Purchases not allowed on this device.")
        }
        PurchasesErrorCode.PurchaseInvalidError -> {
            showAlert("Purchase invalid, check payment source.")
        }
        else -> {}
    }
}

Legend

When debugging errors, it's important to consider whether the error was thrown by RevenueCat, Apple, or Google. This can help you pinpoint where to look for a resolution.

Icon

Description

😿

Error generated from RevenueCat

🍎

Error generated from Apple

🤖

Error generated from Google

Error codes common to all methods

😿 INVALID_APP_USER_ID

Problem:
Indicates the App User Id is set to an invalid value.

Resolution:
Make sure you're not sending a string over 100 characters or a blocked app user Id.


😿 🍎 🤖 INVALID_CREDENTIALS

Problem:
Indicates the application has been configured with an invalid credentials.

Resolution:
If this error occurs before a purchase, ensure you're using the correct API Key from the RevenueCat dashboard.
If this error happens during the purchase flow, make sure your Play Store Credentials and/lor App Store Shared Secret are configured correctly in the RevenueCat dashboard.


😿 NETWORK_ERROR

Problem:
Indicates a network error occurred during the operation.

Resolution:
Make sure the device has an internet connection and try again. If you are testing in sandbox, make sure your outgoing connections is turned on. You can find this in XCode under signing & capabilities > App Sandbox > Outgoing connections (Client).


😿 OPERATION_ALREADY_IN_PROGRESS

Problem:
Indicates an identical operation is already in progress. For example, making two identical purchase attempts at the same time.

Resolution:
Wait for the original operation to complete.


🍎 🤖 STORE_PROBLEM

Problem:
This error is forwarded from Apple/Google and indicates there was a problem connecting to the App Store or Play Store.

The problems that will trigger this on iOS:

The problems that will trigger this on Android:

Resolution:
If everything was working while testing, you shouldn't have to do anything to handle this error in production. RevenueCat will automatically retry any purchase failures so no data is lost.

If this occurs while testing in sandbox you can try:

  • Repeating the operation later.
  • Create a new sandbox user on iOS.

😿 UNEXPECTED_BACKEND_RESPONSE_ERROR

Problem:
Indicates the SDK received an unexpected response from the server.

Resolution:
Report the error with the full error object.


😿 UNKNOWN_BACKEND_ERROR

Problem:
Indicates there was an unknown server error.

Resolution:
Report the error with the full error object.


🤷 UNKNOWN

Problem:
Indicates an unknown error occurred.

Resolution:
Help us fix it.


Purchasing Errors

😿 RECEIPT_ALREADY_IN_USE

Problem:
Indicates there is an identical receipt already in use by another subscriber.

Resolution:
The user will either need to log in as the App User Id that already owns the receipt or restore purchases to re-sync the receipt with their current account.


🍎 🤖 INVALID_RECEIPT

Problem:
Indicates the receipt is malformed or invalid.

Resolution:
Receipt validation failed, no action required.


🍎 MISSING_RECEIPT_FILE

Problem:
Indicates there is no receipt file available on the device. This is more common in sandbox testing.

Resolution:
Make sure you're signed into the device with a valid Apple account. In Sandbox, you may have to make a purchase to generate a receipt before attempting the operation. This error can occur fairly often in the sandbox environment. In sandbox a receipt is generated when a user makes a purchase and is saved against the sandbox account. While in production a receipt is generated when a user downloads the app and is saved against the Apple account.


🍎 🤖 INSUFFICIENT_PERMISSIONS_ERROR

Problem:
Indicates the device does not have sufficient permissions to make in-app purchases.

Resolution:
Make sure you're signed into a physical device with a valid Apple or Google account that has permissions to make purchases.


🍎 🤖 PAYMENT_PENDING

Problem:
Additional action is required by the user before granting entitlement. For example, a user might choose to purchase your in-app product at a physical store using cash, or a parental control on a child's device may require approval before purchasing.

Resolution:
Confirm to the user that they've started the pending purchase, and to complete it, they should follow instructions that are given to them from Apple or Google.


🍎 🤖 PRODUCT_NOT_AVAILABLE_FOR_PURCHASE

Problem:
Indicates the product is not available for purchase by the device or user.

Resolution:
Ensure you're attempting to purchase a product that's available for the device / user.


🍎 🤖 PURCHASE_CANCELLED

Problem:
Indicates the user cancelled their purchase and was not charged.

On iOS, this can also mean the Apple account already owns the product. The user can restore purchases to re-sync any transactions with their current App User Id.

Resolution:
No action required. The user decided not to proceed with their in-app purchase.


🍎 🤖 PURCHASE_INVALID

Problem:
Indicates one of the provided arguments for the purchase was invalid, including the payment method.

The problems that will trigger this on Android:

The problems that will trigger this on iOS:

Resolution:
Ensure the device payment method is valid and all arguments passed in are correct.


🍎 🤖 PURCHASE_NOT_ALLOWED

Problem:
Indicates the device or user is not allowed to make the purchase.

The problems that will trigger this on Android:

The problems that will trigger this on iOS:

Resolution:
Make sure the device and user are allowed to make in-app purchases. Try the following troubleshooting steps:

  • Make sure your device/emulator is completely updated.
  • Try running on device. Sometimes the emulator glitches out and it must be restarted. Overall, testing on device is more reliable.
  • Restart your device/emulator.
  • Make sure you're logged in with a Google account.
  • If you're running on an emulator, make sure it has Google Play installed.

Restoring Errors

🍎 🤖 INVALID_RECEIPT

Problem:
Indicates the receipt is malformed or invalid.

Resolution:
Receipt validation failed, no action required.


🍎 MISSING_RECEIPT_FILE

Problem:
Indicates there is no receipt file available on the device. This is more common in sandbox testing.

Resolution:
Make sure you're signed into the device with a valid Apple account. For Sandbox testing, you may have to make a purchase to generate a receipt before attempting the operation. In Sandbox a receipt is generated when a user makes a purchase and is saved against the sandbox account. While in production a receipt is generated when a user downloads the app and is saved against the Apple account.

Next Steps

Updated 5 days ago


Error Handling


Handling errors in Purchases SDK

Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.