I have an app I'm developing which relies heavily on users being able to purchase content which will be downloaded from a server. As the app nears completion I'm becoming more concerned about my current distribution model, which is simply that when the user purchases an item the app then generates the correct URL and downloads the data (e.g., from www.website.com/content/music.mp3).
I have some simple web development experience, but I'm not aware of any authenticating process to ensure that only my iphone app has access to this content. In other words, as soon as somebody detects the outgoing URL request, they could get my content for free. Is there anything I can do to prevent, deter or even strongly discourage this?
Send the receipt to your server, verify the receipt and create a one-time-url for the file.
Related
My app uses in-app purchase, and I verify the transaction receipts with Apple. This has shown me that many users are trying to pirate the in-app purchase mechanism by submitting fake transaction receipts, which come up with a product ID of com.zeptolab.ctrbonus.superpower1 (from "Cut the Rope"). Of course I don't let them use the in-app purchase items with a fake receipt. What are some strategies for battling iOS piracy and trying to get these people either to pay or to suffer?
The only way to truly prevent this is to control everything through your own server(s). Even the infamous "com.zeptolab.ctrbonus.superpower1" receipt is an actual valid receipt that Apple's own validation endpoint will tell you is OK. Once a transaction is completed, the app should send the transaction data to a server you control and:
Validate the receipt with Apple from your own server.
If Apple says it's OK, parse the product_id field from Apple's response and make sure it's a product ID from your app.
If the first two items pass, return data to tell your app where to download your content (if it's hosted content).
Even this has a flaw, especially if your IAP content is simply on the device but "locked". There are ways to redirect the validation call from your server to make your app think your server said "everything is OK!". This is much more difficult if your IAP content is hosted remotely as they can't as easily spoof the response with the location of the content if they don't know where the content is in the first place.
The problem in all of this for most people is that controlling your own servers and remote content can get costly, not to mention the need to write your own validation logic. The more difficult you make it for these hacks to be successful, the more it can cost you, so you have to weigh just how much you want to make them "suffer" with how much time, effort and money you're willing to spend vs how much you're making and/or losing. Remember, one "pirated" IAP is not necessarily equal to one lost sale, so it can be hard to gauge just how much you might be losing from this.
The idea is whether rain or shine, wet or fine, user must get that he paid for all out.
From Apple:
Store Kit provides built-in functionality to restore transactions for non-consumable products, auto-renewable subscriptions and free subscriptions
For these transactions Apple Store Kit has good build-in tools. I want to focus on other types (consumable in particular).
One and only transaction information is an identifier and a receipt data which we receiving by Store Kit after successful purchase.
Our application uses server-side model to deliver products to it. But there still much cases of losing purchase data, such as if the server lay down while user is making purchase via App Store so its not possible to send receipt to server to complete verification process.
Current workaround is:
Server returns a list of product identifiers
User selects one; app saves its identifier on device (via SQLite or Core Data). Standart Apple Store transaction process goes right after that.
In case of success application saves receipt data in conjunction with its identifier on device and send it to server. If there were failure or cancelation the identifier is immediatelly removed from device.
If server's response is OK then app removes identifier with receipt data from device. Otherwise it will send requests to server periodically until successful response behaves.
But this approach still has leaks. For example, user can remove application from device not waiting for transaction delivering to server, so there will not any proof about his purchase at all.
Your suggestions?
The fundamental rule is that you not call finishTransaction: on the payment queue until you have successfully delivered content. That means that you make the request to your verification and content servers and they come back with valid responses. Only after those proper responses do you call finishTransaction:. Note that bad purchase receipt is valid just not good. You will get people trying to ripoff goods - don't lose sleep over it but do put in proper receipt checking.
As I understand it (from my non-consumable items), as long as you do not call finishTransaction, the store will continue to retry it on your app installation. For that reason, I do not think you need your application to save the receipt on the device. However, for consumables, the server has to store the data if you want to be able to restore it later. A non-trivial problem is what key to store it under.
BTW, your first line is absolutely correct and worth losing sleep over.
So all the documentation and posts I see about auto-renew subscription are using the server side model to deliver products. Is there a particular reason why one couldn't use the Built-in model.
I am creating a audio player app that will provide new original music every month. With service side verification I understand that it checks to see if the receipt is valid before allowing the user to download the audios from my server.
However, couldn't I just program my app to ping the app store to see if their subscription is active. If their subscription isn't active have the app sit on the home screen saying "Please renew your subscription before regaining access to the audio player"
It's my understanding that the server side model is there to prevent pirates from gaining access to my servers resources. Is there any other reason I should use it?
It depends on whether you want your application to be hacked or not.
Main reason for all the validation routine is that once application is available to user, he can modify it in any way he likes which can be seen on all the hacked iPhone apps out there.
So in your case they would delete all checks from your code and set "active" to true.
I am working on a application which has a more peculiar requirement. Basically it is something which is not targeted at end users but at a system integrator who will embed an iPad into a larger system and sell it to an end user as a whole.
However, the problem I'm facing is that the system integrators could simply purchase the app once and then keep cloning thousands of iPads from a single iTunes account, my company would not get any revenue from this.
Is there any way around this. I've looked at in app purchases but according to the guidelines I'm supposed to give in app purchase restore functionality so I guess if I don't the app won't get approved.
I could use external authentication servers I guess, but that may be viewed as circumventing the app store.
I've loked at the volume B2B stuff but I'm not quite clear on how that works or if it would help me in this case.
Any ideas?
Thanks
Last time I checked an application can only be installed on five devices, and then the other ones simply refuse to install the application.
If this system integrator managed to circumvent this, it's he who is breaking the App Store rules.
You can't use the App Store mechanisms as you described (you can't change iTunes). In-App purchases of non-consumable items must include a restore option so the user can restore it on all his devices even if it's thousands (this also for subscriptions etc). If you won't enable that you would be rejected.
You can think you can send the Device-ID for each device that purchase the item and have control over that(or any information) but apple would simply reject your app because it's forbidden to send device-ID.
If your service is online you can simply use some kind of tokens created on your servers which would be given to each client (from some kind of private key), This way you must be connected to each purchased item (only those would contact your servers and you would grant access).
Security wise you must consider leaving some of the functionality on your server side. This is not illegal same as you can't access Facebook without username& password.
And now for the easy way, Define your service as consumable item for in-App purchase(if you can). What does it mean? Lets say you are selling a special feature like "Ad-Free" you can sell credits that would be consumed with each app open or any other process you have in mind, You can even set this credit to 1 million for 0.99$ (so the user never gets to that) but still the consumer would have to buy it again and again for each device and it would be absolutely legal by Apple. Pay attention that the problem would be on the consumer side such as that if user have deleted his app you should find a way to help him or refund him on next buy. Also, If you can and would use this method pay attention to save those credits on the restored folder on the device, so if the user would upgrade or restore the device he would still have the credits he bought.
Pay attention that if you are going to use in-App there are lots of methods to steal this content on jailbroken devices and you must use your own server to check the buying process (according to Apple).
Another important thing is that the app without the in-App purchase must have some value to the user.
I am considering using In App Purchase for our iPhone app. But since we will offer a larger quantity of content items (>10 video items each day added), I would like to automate the new product registration in iTunes Connect.
Is this possible ?
If not: how long does it typically take before Apple approves a new registred product in iTunes Connect ? Since the content looses quickly it's 'freshness' (news broadcasts...), it is crucial to be able to have new content available ASAP.
Would you recommend using In App Purchase for this scenario or would you recommend developing our own payment & account system ?
As far as I know, it is not possible to automate it, unless you develop your own script (in AppleScript, for example, to operate safari and I am not sure if it will work as expected.
A new app will be reviewed and approved typically in 7 days. In-app purchases will go live when the app is approved.
In-app purchases can operate in two ways:
you include the content inside the app
you put the content on your severs and include the mechanisms to make the magic work. When the user buy the app, Apple server will communicate with yours and vice-versa, and a signal must be sent to Apple servers, during the process, so they will know the content was delivered. You will have to read the docs, as this is too complex to explain here.
I automated the input of a large number of in-app purchases using the Firefox extension iMacros. The free version is absolutely sufficient for this.
You have to create a CSV file containing all the data, then record the workflow in iTunes Connect and press start!