I'm going to try a few options when I'm closer to being done: 1) Full APK with content locks 2) Separate download after unlocking 3) asynchronously download #2 while the player plays the demo (oh god...) 4) finding another profession
I'm going to try a few options when I'm closer to being done: 1) Full APK with content locks 2) Separate download after unlocking 3) asynchronously download #2 while the player plays the demo (oh god...) 4) finding another profession
All possible options (including #4). You have also conveniently ranked them from easiest to hardest.
Whichever way you go, store a flag on the local device as to whether the user has purchased the game or not (to allow quick progression into the game on launch), but also confirm this flag on each launch by calling OuyaFacade.requestReceipts() and check they have a receipt for the purchase.
I don't think it's a good idea to host content on a server without some kind of OUYA-run server product model similar to Apple's. Everything in the current documentation points to local verification of entitlements and consumables only without a server-side protocol for developers to implement and verify transactions.
Assume that piracy will be a given, I for one would not want to pay for the bandwidth cost to distribute IAP content to anyone whose apk has been hacked to skip the validation process and go to a "secret" url to download additional content. I would rather just ship the full game in demo mode locked behind an entitlement. You'll only get money from paying customers either way, it's just a question of whether you want to pay for bandwidth for pirates or not. :)
Presumably we're going to be able upgrade apps after we deploy them (re-push an APK to a device)
If the IAP could hook into triggering a special one-way version "upgrade", then we'd get that capability for free. (i.e. a purchased item triggers a version upgrade to get the "complete" version)
Yeah, but once you have the receipts you'd need to send it to the server and the server would need to validate them, not running the ODK, but via a web call.
Yeah, but once you have the receipts you'd need to send it to the server and the server would need to validate them, not running the ODK, but via a web call.
AFAIK this is already done under the hood right? The client makes a request to the server to obtain a list of receipts? That was my understanding.
You didn't remember the plot of the Doctor Who movie because there was none; Just a bunch of plot holes strung together.
Exactly. requestReceipts() is getting the receipts from OUYA's servers. The receipts will be encrypted with your application key and your code will have to decrypt them (code will be supplied by OUYA, but for now the OuyaEncryptionHelper class will help you). You decrypt the receipts and then compare them to your app's own record of what has been purchased.
Yes, but when writing a game with an authoritative server like an MMO, the server needs to know if the transaction was successful. I couldn't find the exact Apple documentation on their purchasing, but the web code here (https://github.com/chrismaddern/validate-in-app-purchase-iphone-ios-receipts) is exactly what I'm referring to, but for Apple's App Store.
It is essential for an authoritative server to have access to this because you can't trust anything the client gives you. It needs to come from a trusted server.
Ahh, right. Now it's clear what you mean. Windows 8 IAP has the same feature. Client retrieves receipts from Store, passes receipts to your web service, web service verifies receipts with Store.
There does not appear to be anything publicly available for this third-party receipt verification at this time. Perhaps if we ask for it, it will be considered.
Yes, but when writing a game with an authoritative server like an MMO, the server needs to know if the transaction was successful. I couldn't find the exact Apple documentation on their purchasing, but the web code here (https://github.com/chrismaddern/validate-in-app-purchase-iphone-ios-receipts) is exactly what I'm referring to, but for Apple's App Store.
It is essential for an authoritative server to have access to this because you can't trust anything the client gives you. It needs to come from a trusted server.
Yeah this will be crucial for a lot of games. I'm running an Asynch game with micros so server validation would be nice to have.
Aggro Tactics - A tactical strategy virtual board game built with Unity3D 4.0, designed around the concept of Threat/Aggro inspired by the mechanics of chess and a customizable party like in table top games.
Ahh, right. Now it's clear what you mean. Windows 8 IAP has the same feature. Client retrieves receipts from Store, passes receipts to your web service, web service verifies receipts with Store.
There does not appear to be anything publicly available for this third-party receipt verification at this time. Perhaps if we ask for it, it will be considered.
Do we know if the ODK in this area has dependencies on the console in some way?
If there is nothing from stopping you from running the ODK java code on a server, this decryption could be done there, and have your server send back the receipts to your game (either decrypted, or encrypted again with some other user-specific key).
EDIT: Ah.. never mind. After some thought, the application key alone probably isn't strong enough for this to work.
Exactly. requestReceipts() is getting the receipts from OUYA's servers. The receipts will be encrypted with your application key and your code will have to decrypt them (code will be supplied by OUYA, but for now the OuyaEncryptionHelper class will help you). You decrypt the receipts and then compare them to your app's own record of what has been purchased.
It is very important to realize that encryption/decryption is ultimately little help when the *client* is responsible for determining whether a purchase is valid or not. Why would a cracker bother with this when it can just bypass the entire receipt check and forward along a fake receipt instead?
It becomes harmful to us developers when we have to *pay* for some piece of internet infrastructure such as hosted DLC or multiplayer servers and then you trust the client to determine authorization or access to those hosted resources. The pirates can simply bypass the entire complicated receipt check, can sniff or reverse engineer our communication protocol, and then have pirated copies download DLC or play MP games on our infrastructure's dime.
It also will affect F2P games that have to rely on the client to report when paid in-game items were purchased. It'll probably make the process of detecting IAP fraud a really difficult process that involves looking for suspicious activity then forwarding receipts to OUYA through their ticketing system.
We ultimately need a receipt validation API from OUYA so that we can validate receipts *on the server, not the client*. This is what Apple provides in the form of the server product model and receipt validation endpoints.
I would hope that OUYA is already aware of this and providing the receipt encryption/decryption routines are just a stopgap because they don't have enough time to do the full receipt validation API until later. It isn't optimal, but it's an insanely fast dev cycle for their platform and we're probably going to have to just go with the flow and be okay with the chaos at first. :)
If receipt decryption always occurs outside of the client, then fake receipts would be a whole lot more difficult to come up with.
If the issue here is not wanting to expose a web service... OUYA could probably solve this by providing a separate receipt encryption key per game/app, and also require the UUID as part of the encryption/decryption process. That way, purchases can be made in client code with the dev key, and decryption could be done on your server without revealing the decryption code for the app.
Presumably, on the server, you'd identify your player records by UUID as they login to your server via the console. From here, you can ensure only one UUID session can exist at a time, watch IP address changes, etc, and kick players appropriately.
Passed receipts would have to decrypt with the app decrypt key (on your server only), along with the UUID (as the user identity for both the console and on the server). The ODK decryption code itself (modified to fit this model, of course) could be used to figure this out (and would give you the option of decrypting in the client if you chose to). Fake receipts would be MUCH more difficult to produce this way (at least for one-time entitlements).
"Consumable" style IAP would probably have to be encrypted on the console with some sort of request-specific identifier. Ask your server for a seed key, encrypt that key with the success/fail status and a shared secret key between the server and client, pass it on, decrypt it, register it on your server, and then invalidate that seed so it can't be used again. This method could probably be done with entitlements too, but would require you to sync up with the server at time of purchase, which would add the bonus of not having to verify receipts at all later. Simply sniffing network traffic and creating fake web requests wouldn't work. This particular way could also be done without any real modification to the current ODK.
The strongest argument against/issue with this is if someone reverse engineers your code and looks at how you're doing your encryption. But if they do that, they're probably just going to bypass all of the IAP logic anyway.
Google IAP version 2 uses receipt signatures that you can verify, without talking to their servers, on your own server or in the app on the client. Your choice. They provide a public key that is unique per app to use for the verification process. They keep a private key to generate the signatures with. The public key is only good to be able to verify the signatures. Not generate the signatures.
The point is, it's not really a show stopper. Exposing a web service outside of the console's consumption isn't trivial to do in a secure way either (which is probably the real bottle neck here).
Right now, they have the approval process to vet out apps/games doing malicious web requests to their store. They know the number of consoles in circulation. Making the console do the requests funnels interaction with the store/your server through an approved app. There is no such app approval process for server-to-server transactions. Why is this a concern? Even with an SSL cert in place, if your server is compromised, OUYA is open to attack on their web-service.
Not saying it's impossible to implement (as Apple has clearly invested in this to some degree), but I imagine there's a much bigger picture at work here.
Technically, the only place they are weak for receipts coming from the client is the lack of a shared secret (preferably per app/game). If they were to encrypt the receipts that way (as well as the success/failures of consumable purchases since those aren't returned with receipts), they have enough without having to make a web service publicly available.
Google IAP version 2 uses receipt signatures that you can verify, without talking to their servers, on your own server or in the app on the client. Your choice. They provide a public key that is unique per app to use for the verification process. They keep a private key to generate the signatures with. The public key is only good to be able to verify the signatures. Not generate the signatures.
To be honest, I don't really care how it works as long as it's not too messy for me to implement and it's secure. It just needs to be something the server can validate.
Yes, it is imperative for the server to have authority to validate the receipt of purchase.
Completely agree. This is not an optional thing.
The first rule of security is to never trust the client, yet that seems to be the only option when dealing with Ouya clients right now.If we can't verify purchases from our own server, we will have to assume that all Ouya clients are untrustworthy and prevent them from using IAPs at all.
Comments
1) Full APK with content locks
2) Separate download after unlocking
3) asynchronously download #2 while the player plays the demo (oh god...)
4) finding another profession
Yeah, paying for bandwidth for a pirate to use does seem like a losing business proposition...
Founder of ReachingPerfection.com