Doesn't it necessary to write verification code for in-app-billing? - in-app-billing

I am writing code for in-app-billing for my app.
I saw sample code here https://medium.com/#patpatchpatrick/adding-the-google-play-billing-library-to-your-application-fbeb9ec03151
There is no code for purchase verification.
I mean it does not use BASE_64_ENCODED_PUBLIC_KEY at all.
But TrivialDrive_v2 has code for purchase verification in verifyValidSignature method.
My question is that "Is verification required or just recommendation?"

Related

How to perform the verification off the In-App purchase?

I have just implemented the In-App purchase on my Flutter App.
I saw on various documentations that we should always verify the purchase prior to provide the benefits, but I can't figure out what that is really means.
The PurchaseDetails object provide the followings properties:
purchaseID
productID
verificationData
transactionDate
status
How are we supposed to use them for the verification ?
Thank you for your help,
Benjamin
but I can't figure out what that is really means.
It simply means that as a service provider, we should be double-checking a successful transaction with the payment processing authority (which is Google/Apple for Android/iOS IAP respectively) to prevent any form of fraud.
How are we supposed to use them for the verification ?
https://pub.dev/documentation/in_app_purchase_platform_interface/latest/in_app_purchase_platform_interface/PurchaseVerificationData-class.html
PurchaseDetails.verificationData exposes two kinds of data (they are used the way they are named):
localVerificationData
serverVerificationData
Purchase receipt verification can be done either locally (i.e. on the client app) or on (your) server side. Server-side implementation is recommended for security reasons.
Now, this is where verificationData behaviour for iOS and Android changes.
iOS verificationData
How iOS IAP verification works
Android verificationData
How Android IAP verification works
Ref 1
Ref 2
Without going too much into the references (I think they are quite self-explanatory):
In case of iOS, localVerificationData=serverVerificationData, and the purchase can be verified either by hitting the verifyReceipt endpoint (can be done either on server-side or client-side), or decrypyting the data on the client/server-side and parse the decrypted data manually.
In case of Android, localVerificationData carries the ProductPurchase data, that is otherwise returned by using the token provided by serverVerificationData to request the aforementioned REST endpoint. A purchase is considered 'verified' if purchase status is PURCHASED.
You may also have take care of other situations, depending on your use case.
Hope that the references linked above are useful.

iTunes in-app purchase receipt verification - obscure-JSON

This question related to AppStore in-App Purchase Receipt Verification Issues
In short - receipt data from iTunes is encoded in strange kinda-JSON format without any specifications for it. The accepted answer states that there is no need to decode it, it must be just sent to iTunes.
In my case I want decode that data to ensure that bundle_id parameter is equal to my apps bundle_id.
https://buy.itunes.apple.com/verifyReceipt method treats receipt as valid even if it was not generated for my application - so if hacker will send valid receipt from other app to my server - he well succeed.
The question is in how to do such verification properly, that additional step was certainly not intended by iTunes developers (otherwise they would not used pseudo-JSON), but nevertheless I think that it is necessary for protection from such attacks.
Any thoughts on this?
Gill, you should consider the receipt data that you are validating opaque and not try to interpret it. Send it to Apple's verifyReceipt service and examine the response. It will be a non-strange JSON object. If the "status" field is 0 then Apple considers it to be a valid receipt but it is up to your server app to determine if it is being used in a valid context. To do that you can examine the "receipt" object where you'll find the bundle and product IDs among a lot of other things.
If you're determined to some pre-validation of the receipt data before sending to Apple you can do that as well with some extra effort. It is a base64 encoded JSON object that contains two other base64 encoded objects one of which is receipt data as described above. The problem with this approach is the data is not intended to be examined by Apple service users so would be subject to change without notice. It can be a useful technique for debugging however.
If you are using iOS7, you can do receipt validation including bundle_id verification using on-device methods. Take a look at-- iOS InApp Purchase Receipt Validation iOS 7 and A complete solution to LOCALLY validate an in-app receipts and bundle receipts on iOS 7. I'm assuming you are talking about on-device validation and not using your own server to handle validation.

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.

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 ;)