Validating In-App Purchases On-Device

Stackoverflow is flooded with questions related to in-app purchase validation on-device or through servers. A receipt of purchase confirmation is always preferred because it lets the users know what was purchased, when purchased, for which app/service, and by whom? It’s almost been 10 years since Apple introduced in-app purchases, which made it possible for developers to sell digital products from their apps itself.

During the initial days of the feature introduction, this was enabled only for paid apps. But soon, Apple made it available for free apps as well. And today, every single Apple user can purchase digital products and services using their Apple IDs. However, these in-app purchases have to be validated. It is advisable to use your own server for validating the purchases. The reason being, any app recognizes its own server and puts it before any other. This further gives you complete control over the transaction.

But as this feature has to handle the transfer of real-money, security and resource provision are the main things that you need to ensure first; Security of the personal credentials and confirmation of the transfer of a digital resource.

Server-to-server purchase validation is one way to go, but the other way is on-device validation. You can use both the methods to unleash in-app features and content without server connection.

This article will guide you through both the options, and you can select any one of the two depending on your app structure and features.

The validation process highlight:

The device receives a transaction request. Further, for server validation, it sends to the server, and for on-device validation, it carries out the process of validating receipt. Both the methods start updating the state and allow you to unlock the content, and there you go, the transaction is finished.

Validating in-app purchases in iOS and Android

Server-to-server purchase validation:

For iOS in-app purchase server validation, all the requests are handled by Apple’s HTTP validation service. This server is secured and manages business logic for data comparison and date validation.

You just need to pass this receipt to the server for validation, and it further passes the receipt to the application. You will need a password for receipt having an auto-renewable subscription. Once the Apple server has processed the receipt, it will send a response in a JSON format.

This response contains the receipt for the transaction containing every single detail of the purchase. However, it is advisable not to send the receipt directly to the app from the AppStore to ensure security concerns.

So how is this method beneficial for validating in-app purchases?

There is no need for any cryptography;

There is no chance of any data tampering or date changes on the device;

The users get updated information about the purchases across all the device;

If you subscribe to the feature, you get additional information.

The above features indicate that the server can keep the latest version of a receipt and check it regularly for the status update. This makes it possible for you to display updated information about subscriptions to users. There is no need for the user to go to the app and check for updates.

Is it sufficient enough for you to know that the subscription is no more active? Or is there something more to it?

Well, it is difficult to get the answers to the questions like why the user unsubscribed the service? Are there any chances of them renewing it? Why does AppleCare return money back to the user? Have the users agreed to a price hike?

We suppose without having the subscription churn number, it would be to gauge the exact number of users who have stopped the service subscription. Unsubscription to the service many times happens voluntarily or involuntarily. For instance, a user’s credit card expiration date is not something in the user’s control. And hence server notification will help you keep track of the same.

For receiving user notifications, you need to submit your server address to iTunes Connect, and you will start receiving notifications for the initial subscription purchases, subscription cancellation by AppleCare, Subscription downgrades, and renewal or expired subscriptions.

Validating in-app purchases in iOS and Android

On-device purchase validation:


Many of our esteemed clients have asked us this question, “how to validate in-app purchases on device?”. We tell them the whole process and make them understand how it works. If you have questions, you can ask our team of the app development company, we would be happy to help you.

This method is suitable only if all the purchases are processed locally on one single iOS device. However, purchase validations performed on an iOS device will not be accessible on-site or on an Android app. Hence, you should pick up this approach only if you are planning to process purchases only on iOS devices.

Apple provides a StoreKit framework in the iOS SDK, which creates a SKPayment object and adds it to the SKPaymentQueue. This process pops up a dialog on the screen which describes the payment request. This request is sent to the Apple server, and once the request is processed, it sends a response carrying all the transaction details.

The app now carries out the following tasks:

It insects the receipt to verify if it is an authenticated purchase (updatedTransactions);

Ensures that the user gets the resources they have paid for;

Tells the server that the transaction has been finished (finishTransaction function)

Your job for performing receipt validation is to ensure that the receipt is authentic (that is received from Apple only) and to check its integrity (that it is not tampered). The receipt will be stored on-device as a single file that will contain, Apple digital signature, an app certificate, and detailed information about packages.

If you wish to refer to the receipt validation guide, you can click here.

Steps to receipt validation are:

Use bundle API to locate the receipt.

guard let appStoreReceiptURL = Bundle.main.appStoreReceiptURL, FileManager.default.fileExists(atPath: appStoreReceiptURL.path) else {
return
}
let rawReceiptData = try Data(contentsOf: appStoreReceiptURL) let receiptData = rawReceiptData.base64EncodedString(options: ...)

If you haven’t received the receipt, then request for it using the below lines of commands.

let request = SKReceiptRefreshRequest()
request.delegate = self
request.start()

Now you are ready to validate the receipt. You can use OpenSSL, ASN.1 Compiler, or any other analogous solution.

1. Ensure that the receipt has an authenticated Apple certificate signature. Check the date of the certificate against the current date on the device. You can also check the expiry date against the date of the transaction.

2. Confirm the product identifier and bundle identifier given in the receipt with the values you expect. This step will mitigate the attack by the intruder.

3. This way, you compare the identifierForVendor property from UIDevice and complete the transaction.

So how will you restore the purchases?

Auto-renewable, non-renewable, consumable, and non-consumable are the types of purchases users usually make.

Auto-renewable subscription means users can access the services and the data after renewing the plan on a regular basis, say weekly, monthly, yearly, etc.

Non-renewable subscription means users can access the services for a definite period of time. These kinds of subscriptions do not get renewed automatically.

Consumable subscription means a purchase of resources like lives & coins in a game. These resources can be purchased multiple times and used only once.

Non-consumable subscription means the purchase of in-app features and functionalities like various editors and filters in an app.

The ones who have opted for non-consumable or auto-renewable subscriptions will have access to the purchases using the same AppleID. When implementing the on-device receipt validation, you need to remember the following things.

Perform validity and integrity checks in order to confirm that the product is received by the user;

If you do not find an authentic transaction, refresh the receipt;

Store a list of redeemed receipt identifiers;

Understand the whole process of receipt validation and ensure that a secured receipt validation is carried out each time.

In-app purchases have become another way of generating revenues. If you wish to carry out validation of in-app purchases in iOS and Android, you can talk to our experts who will make you understand various monetization strategies.

Conclusion:


In this blog, we have provided the basic procedure of performing in-app purchase receipt validation, keeping iOS in focus. The process of validation for Android apps and Windows apps might be different, but, the general principles remain the same.

Do not overlook the process of receipt validation because it may cause you security concerns in the later stages. A receipt doesn’t always exist in the app always, but if the app is downloaded from the App Store, then yes, they will get the receipt. But, if the app is installed via Xcode or Testflight in the sandbox, then there will not be any inbuilt receipt unless you make a purchase.

In-app purchase validation ensures that there is no room for intruders, and the user doesn’t suffer any monetary losses. If you wish to validate your in-app purchases, you can reach us out.


ABOUT THE AUTHOR
blog Author - kodytechnolab

Sagar Bagsariya

Principle Mobile App Developer


RELATED POSTS