IPHONE in-app purchase: is it possible to verify a receipt without using an external server? - iphone

I have a receipt of a recorded transaction stored by the application when the transaction was done and I would like to ask apple's servers if this receipt is valid.
Is there a way to do this without using an external server?

I would like to ask Apple's servers if this receipt is valid.
Is there a way to do this without using an external server?
Perhaps it's just me, but it seems like you are asking to contact a server without contacting a server, which is quite impossible I'm afraid.

As far as I know, there are few json service provided by Apple:
One for the In App sandbox (before the submission):
https://sandbox.itunes.apple.com/verifyReceipt
One for the App Store version:
https://buy.itunes.apple.com/verifyReceipt
You can call them sending your receipt:
{
"receipt-data" : "(actual receipt bytes here)"
}
And it returns the answer:
{
"status" : 0,
"receipt" : { ... }
}
I assume you can make a direct call to the service within your iPhone app OR you can call your own server script that work as a proxy to the Apple service. It depends on your app logic. If you need to check the receipt on your server (IE. to authorize a download) you should call your server script otherwise you can verify the receipt directly from the app.
Doc reference:
http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/StoreKitGuide/VerifyingStoreReceipts/VerifyingStoreReceipts.html

this case is solved. It is possible to do that using just the iphone.

To clarify:
Only the Apple Server can give information about the validity of a
transaction receipt. Indeed you have to contact this server even just
to find out if a product is still active (or if the user has
cancelled the subscription).
On the web, you get the impression that
it is not at all, or at least not in any safe way, possible to
contact this Apple Server simply via HTTP-POST out of your app.
Everybody seems to be convinced you need to have a web server which
is contacted from your app, and that you should only contact Apple's
server from your web server.
Apple, however, even provides implementation code (I wish I had found that earlier) on how to contact the verification server safely without another web server in between:
http://developer.apple.com/library/ios/#releasenotes/StoreKit/IAP_ReceiptValidation/_index.html
This implementation is similar to what lomanf mentioned, just in more detail and with all the security needed to make it work even with iOS 5.x.
So the answer is most definitely: Yes.

Related

Verify in app purchase receipt without external server?

I would like to verify an in-app purchase receipt by sending a JSON to buy.itunes.apple.com/verifyReceipt, but im not sure how. I can find lots of tutorials on how to do it with a php server, but I dont use an external server for my purchase. Help?
There are cases where validating receipts is an essential thing, but your case does not sound like one of those cases. In your case, you are getting receipts directly from StoreKit and using them within the app.
The main reason someone would have to have validation of receipts is if they are 'delivering' content to an application from an external source. In those cases, validating a receipt is essential because the receipt is coming from an untrusted source (the application could send any receipt it wanted to).
That being said, there is no reason you can't follow the exact process to validate local receipts as well (if desired).

How to develop a payment verification for in-app purchase?

I have developed an iPhone application that was rejected. With this application I offer an SMS transmission service. On my website each user has an account and he can buy credits on the website to be able to send SMS.
The reason for rejections was that my app uses an external service, my website. They say I have to use in-app purchase for the credits.
So now I am about to extend my api. So if purchase takes place in-app the web server needs to know that there was a purchase and what type of purchase. This is done using HTTP-POST.
I could build a simple url and register the purchase in the user-account, since I can verify that an purchase was performed correctly in the app store. But to prevent hacking and just for security reason I think there has to be some kind of encryption.
E.g. if the payment process in the app was successful I send a HTTP-POST to my webserver. It contains some encrypted key that can be encrypted by the webserver.
What do you think about all this? How can I make my api safe regarding in-app purchase and what security algorithm could I use?
Any other suggestions or ideas?
You should probably look into the Server Product Model, rather than trying to invent some way for your app on the device to tell the server that credit was purchased after the fact. The section on Verifying Store Receipts will come in handy; in short, your app transmits the contents of transactionReceipt to your server (ideally via HTTPS). Your server base64-encodes it, embeds it in a simple JSON object, and posts it to Apple to get the status and verified purchase information.
I have a complete implementation of storekit including the server code.
http://blog.mugunthkumar.com/coding/mkstorekit-4-0-supporting-auto-renewable-subscriptions/
Try this
You should check out this wiki article on public key encryption. This is what you'll probably what to be using.
CommonCrypto is a module available for iOS that deals with this type of encryption. Here is a sample project in the iOS developer library that uses this module.
Yes You are correct. That is the best way. When user purchase credit using In-App purchase(IAP) You will have delegate method for purchase succeed. So you can call your Server API in this delegate method and put some flag with credit number in the user table of your server database. You can send this info encrypted and your server would decrypt it and insert in your database.

Possible security measures for in-app purchases downloaded from a server

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.

Which URL should be used to verify in-App purchase receipts

I have completed an iPhone application which sells its subscription using IAP and, for that, I have took all the necessary steps and it's working fine.
I just need to know which URL I should used to verify receipts on the server side?
When I was developing the application and testing IAP I was using:
"https://sandbox.itunes.apple.com/verifyReceipt"
Now I have submitted my application and IAP for review, on which environment will Apple test my IAP? Do I need to change the URL to:
"https://buy.itunes.apple.com/verifyReceipt"
Look at Apple's technotes, go to "FAQ" and scroll down to number 15.
it says:
Use the sandbox url
https://sandbox.itunes.apple.com/verifyReceipt
while testing your application in the
sandbox and while your application is
in review.
Use the production url
https://buy.itunes.apple.com/verifyReceipt
once your application is live in the
App Store.
The way Mugunth Kumar did it in his MKStoreKit was:
#ifndef NDEBUG
#define kReceiptValidationURL #"https://sandbox.itunes.apple.com/verifyReceipt"
#else
#define kReceiptValidationURL #"https://buy.itunes.apple.com/verifyReceipt"
#endif
and that's always worked for me. I do that on my app side.
UPDATE:
But here is the actual correct answer from that same Tech Note TN2259 found here:
How do I verify my receipt (iOS)?
Always verify your receipt first with the production URL; proceed to verify
with the sandbox URL if you receive a 21007 status code. Following this
approach ensures that you do not have to switch between URLs while your
application is being tested or reviewed in the sandbox or is live in the
App Store.
Note: The 21007 status code indicates that this receipt is a sandbox receipt,
but it was sent to the production service for verification.
So the right way to do it is to always check the receipt at the live URL first, if you get back a status code of 21007, check it again against the sandbox url. Then you'll know if it was verified or not and if it was verified in the live server or in the sandbox. We send the receipt to our server and this check is done from there, which keeps the user from using a redirection exploit. Then our server sends a secret back to the app if it checks out and records the transaction in a database. Also from here we can track how many hack attempts are happening each day.
Please note that, as #Mark mentioned above, the documentation is incorrect or outdated - I filed a bug report to Apple.
The production URL is with https.
https://buy.itunes.apple.com/verifyReceipt.
You may verify the URL by just requesting it, it should return a JSON string like
{"status":21000}
Cost me two expedited reviews ;)

iPhone in app purchase subscription to web server data. How should I auth?

I'm working on an app that will provide data from a web server to users but only if they've bought an in app purchase subscription. I understand the basics of IAPs but how do I securely make sure the data from the server is only accessible to the app, and only if the subscription has been purchased? I don't want to make the user set up an account, I just want to auth the app/purchase securely.
Thanks in advance :)
I'm going to use subscription model too with IAP.
AFAIK, you SHOULD NOT use a unique phone identifier like the IMEI of the phone to identify the user on your server. According to the Apple documentation, you MUST provide a way so that an user can restore his subscriptions on several devices!
Besides, a call to restoreCompletedTransactions of the SKPaymentQueue will restore ONLY nonconsumable products! Subscriptions are not supported by this method.
See these links :
http://developer.apple.com/library/ios/#technotes/tn2009/tn2259.html (section « Frequently Asked Questions », point 10)
iPhone - How to recognize the iTunes user of my app
The only way I know is to use a login/password to identify the user on the web server but this could be quite ugly...
However, if someone know another way, could he describe his solution ?
You should upload store receipts to your server, to be able to check them on Apple's site. And, with request you should upload phone identifier. And, of course, store somewhere in the database. After all, you will have information about which phone id has access to subscription.
And, when you will request subscription-related info from your server, you'll be able to check who has acces (via phone id) and who hasn't.