⟵ Back to blog

iOS in-app purchases, part 5: list of SKError codes and how to handle them

6 min read

Share

In our series of articles, my team and I are talking about in-app purchases implementation for iOS. And this is the fifth article in a series. Follow the links to read previous articles:

  1. iOS in-app purchases, part 1: configuration and adding to the project.
  2. iOS in-app purchases, part 2: initialization and purchases processing.
  3. iOS in-app purchases, part 3: testing purchases in XCode.
  4. iOS in-app purchases, part 4: server-side receipt validation.
  5. iOS in-app purchases: the list of SKError codes and how to handle them.

In this post, I will address the SKErrors: what problems they imply and what to do about them. For each error, we will work out three aspects: why it occurs, how to handle them, and what message to display in the error notification.

SKError.Code.unknown, code 0

What it means. An error occurred for an unknown reason.

How to fix it. No action is needed from the developers' side. This error also comes on a request when trying to get products when using the iOS 14 and above simulator. In this case, to get a product, use the StoreKit local testing or a real device/emulator with the iOS version below iOS 14.

What message to display. Sorry, the purchase is unavailable for an unknown reason. Please try again later.

SKError.Code.clientInvalid, code 1

What it means. The user cannot make a purchase. For example, a child tries to buy something when the parental control function on the device is on.

How to fix it. No action is needed from the developers' side.

What message to display. The purchase cannot be completed. Please, change your account or device.

SKError.Code.paymentCancelled, code 2

What it means. The user got to the payment screen, but changed his mind about making a purchase and clicked "cancel".

How to fix it. From a technical point of view, no error occurred and, in this case, nothing needs to be done. From a marketing point of view, you can continue working with such a user, for example, offer him a discount.

What message to display. You have two options here. The easiest one is not to show anything. However, you can also try winning a user back with a message like this: “You have canceled your purchase. Are you interested in trying a subscription at a discounted price?”

SKError.Code.paymentInvalid, code 3

What it means. For some reason, the payment failed: the card had expired or there were not enough funds for this purchase.

How to fix it. No action is needed from the developers' side.

What message to display. Your purchase was declined. Please, check the payment details and make sure there are enough funds in your account.

SKError.Code.paymentNotAllowed, code 4

What it means. Probably, this card has some purchase restrictions available: limits are set or the online shopping function is unavailable.

How to fix it. No action is needed from the developers' side.

What message to display. The purchase is not available for the selected payment method. Please, make sure your payment method allows you to make online purchases.

SKError.Code.storeProductNotAvailable, code 5

What it means. The user is trying to buy a product that is not available for the region in which this store is used.

How to fix it. The developer needs to check products for their availability in the user's store and region. For this, you can use SKStorefront.

What message to display. This product is not available in your region. Please, change the store and try again.

SKError.Code.cloudServicePermissionDenied, code 6

What it means. The user didn’t give access to the information of his Cloud service.

How to fix it. No action is needed from the developers' side.

What message to display. To be honest, I have never met such an error. Actually, you can just write that the purchase was declined.

SKError.Code.cloudServiceNetworkConnectionFailed, code 7

What it means. The device was not connected to the Internet when making a purchase.

How to fix it. No action is needed from the developers' side.

What message to display. The purchase cannot be completed because your device is not connected to the Internet. Please, try again later with a stable internet connection.

SKError.Code.cloudServiceRevoked, code 8

What it means. This device doesn’t have access to the StoreKit payment service. Commonly, this error occurs in Sandbox.

How to fix it. Create a new Sandbox user or just try repeating the operation.

What message to display. Sorry, an error has occurred.

SKError.Code.privacyAcknowledgementRequired, code 9

What it means. The user didn’t accept the terms of use in the AppStore. As it's said in the documentation, "the user has not yet acknowledged Apple’s privacy policy for Apple Music". But it looks like an error, because there is no reason to mention Apple Music here.

How to fix it. No action is needed from the developers' side.

What message to display. The purchase cannot be completed because you have not accepted the terms of use of the AppStore. Please, confirm your consent in the settings and then return to the purchase.

SKError.Code.unauthorizedRequestData, code 10

What it means. Your app ID doesn't contain the required entitlement for using StoreKit.

How to fix it. You need to finish the setup process of in-app purchases for your app.

What message to display. An error has occurred. Please, try again later.

SKError.Code.invalidOfferIdentifier, code 11

What it means. The user is trying to buy a product with an incorrect promotional offer.

How to fix it. No action is needed from the developers' side.

What message to display. The promotional offer is invalid or expired.

SKError.Code.invalidSignature, code 12

What it means. The signature for the promotional offer for the StoreKit request was generated incorrectly.

How to fix it. Check how the signature is generated and fix the errors. If you use Adapty, download the Subscription Key.

What message to display. Sorry, an error has occurred when applying the promo code. Please, try again later.

SKError.Code.missingOfferParams, code 13

What it means. Parameters of the promotional offer are formed incorrectly.

How to fix it. Check and correct the parameters of your promotional offer.

What message to display. Sorry, an error has occurred when applying the promo offer. Please, try again later.

SKError.Code.invalidOfferPrice, code 14

What it means. The user is trying to buy a product with an irrelevant price. Probably, the price displayed in the AppStore is no longer valid.

How to fix it. Set the updated price for this offer in the AppStore.

What message to display. Sorry, your purchase cannot be completed. Please, try again later.

Conclusion

Correct error handling improves user experience and can return at least some of those users who could not pay for the subscription immediately for some reason. These are the most common mistakes when implementing purchases in an iOS app:

  • SKError.Code.unknown, an unknown error; 
  • SKError.Code.paymentCancelled, when the user cancels the purchase; 
  • SKError.Code.paymentInvalid, when the payment can’t be processed.

Actually, error handling and purchase implementation are cumbersome processes. So I would recommend trying Adapty SDK for iOS, which makes implementing in-app purchases easier and provides other benefits, such as subscription analytics, cohort analysis, a/b tests for paywalls, and server-side receipt validation.


Andrey Kyashkin
August 30, 2021