As your app grows in popularity, it will probably attract malicious users that will try to abuse your app. We won't describe how they can do that here, but we'll give you some advices on how to avoid it.
Move logic to you backend
As much as you can, always delegate sensitive data and logic to your backend. It will be a lot harder for your users to abuse from your system and in case of bugs or security issues, it will be a lot easier for you to fix them.
Here are some examples of bad practices:
- if you bundle the unlocked content in your app, malicious users will be able to get it without paying;
- if you validate a subscription/one-time-purchase directly in your app, some users will be able to simulate a purchase and you'll give free access to unlocked content.
Protect your unlocked content
To prevent malicious users from accessing and/or redistributing your unlocked content, do not bundle it in your app. Instead, retrieve it from your server or any other real-time service.
Then you'll be able to store in on the user's device... but be sure to encrypt the content and use a device-specific encryption key!
How to properly validate a purchase?
After a user has made a purchase in your app, you should do the following:
- Send the corresponding
receipt data(Apple App Store) /
purchase token(Google Play Store, Huawei AppGallery) /
receipt id(Amazon Appstore) to you server;
- verify this data hasn't been used by anyone else before (and if it's the case, refuse the purchase OR transfer the purchase to the user);
- verify the receipt by calling the stores servers from your backend.
- if the receipt is legitimate (and not expired), you can safely grant entitlement to the user;
- in some cases, the subscription will replace an old one (in case of a plan upgrade for example) and you should revoke the entitlement associated to the old subscription. To detect them, you should look for:
Avoid void purchases
Voided purchases are purchases that have been canceled, revoked, or charged back.
The best way to detect them quickly is to subscribe to the "server-to-server notifications" services offered by the different stores. They will send Webhooks to your servers on real time when the status of a purchase is changed.
- for Apple App Store
- for Google Play Store
- for Huawei AppGallery
- it doesn't exist for Amazon Appstore, and as explained in their documentation, you should verify your receipts at least 1 time every 72 hours
What you should do when you detect a void purchase
Revoke entitlements in case of subscription, perform clawbacks for one-time-purchases. For example, if you sell virtual coins in your app, and the reimbursed users have already used them, apply a negative balance to their account.
Stay moderate with newly-reimbursed users. If they reiterate, apply more drastic measures (like disabling purchases or forbid access to your app for the user until your investigation is finished).
💡 If you're interested on how to detect void purchases, you can check our article on How to detect an expired subscription.
Help stores track malicious users
Some types of fraud are related to malicious users who create multiple Apple/Google and in-app accounts to hide their activity. You can give more anonymised information on your users to help detect this kind of behaviour:
- for Apple App Store, use
- for Google Play Store, use
setObfuscatedProfileIdmethods in the builder for
- there is no equivalent for Huawei and Amazon.
Nothing is easier than Purchasely to avoid fraud: our solution will do all the work for you!
4 lines of code in your app to integrate Purchasely and you're ready to go, free from malicious users :)