3

I've read several times all the docs in the Android Developer Guide and became familiar with nice Google presentation Evading Pirates and Stopping Vampires

Finally I tried to implement in-app billing scenario involving my own web server in accordance to the presentation above. Here are the main points of interaction with my server:

  1. Before making REQUEST_PURCHASE request to Google I make a request to my web server to register a new purchase. If the request succeeds I get a nonce from the server.
  2. When transaction finishes I receive an array of notification Ids to pass them to GET_PURCHASE_INFORMATION request. At this point I need to use nonce received in step 1 from my server. <- I got stuck here!
  3. When GET_PURCHASE_INFORMATION succeeds I get a signedJson and a signature which I pass to my server. It verifies the purchase and commits the transaction on the server.

What I can not understand so far is two things:

  1. How to identify a previously generated nonce by incoming IN_APP_NOTIFY intent in my case? As far as I understand it can correspond to either current purchase completion or another purchase refund. From what I see we have only notification id which has no relation to a REQUEST_PURCHASE request.
  2. How to securely handle refunds in that way that my server is 100% acknowledged about this event? The most natural way IMHO is to periodically request Google server from my server to retreive the actual status for the order. Unfortunately, in my country developers can not use Google Checkout API. Another way is to periodically check the order state via device using GET_PURCHASE_INFORMATION request passing known notification ids and new nonces. If the check fails during some period the purchase will be automatically expired until the first successful order state verification. Is this scenario possible? Can I use known notification id to make GET_PURCHASE_INFORMATION requests after CONFIRM_NOTIFICATIONS request for the order?

EDIT: Regarding refunds (point 2) there's a related topic Android In-App billing security issues?. Is it correct that there is no built-in end user functionality in Google Play to ask developer to refund in-app purchase? If so, then we might implement a button within our application to send such refund request to our server including all necessary info like verified user credentials and then manually process a refund in both Google merchant account and server's database.

Community
  • 1
  • 1
IPSUS
  • 499
  • 4
  • 15

1 Answers1

1

There is no programmatic way to request a refund. The user has to contact you (by email, etc.) and you can refund their purchase in the developer console. After the refund is processed, the app will get a signed PURCHASE_STATE_CHANGED notification (broadcast) with the new order status (refunded). You can forward this to your server for verification, just as with new purchases and change the order status accordingly. You shouldn't care about what request the nonce is tied to, just check that it is indeed one your generated (Cf. Dungeons sample). If you are doing this on a server, you would typically search your DB to check if the nonce you previously generated is there.

Nikolay Elenkov
  • 52,576
  • 10
  • 84
  • 84
  • Oh, I was afraid to hear something like that about nonces. The only reason I wanted to request a nonce from my server before REQUEST_PURCHASE is to be sure that server is reachable and working currently. Now I suppose to make some kind of ping before REQUEST_PURCHASE to ensure that. As for refund, I will go on with my own refund button to make easier for me to identify that a refund is really originated by a specific user and include orderid details to it. Thank you Nikolay for your complete answer! – IPSUS Oct 10 '12 at 08:13
  • Not sure how you intend to implement it, but for this scheme to be secure the nonce _has to be_ generated and checked on the server. Otherwise the whole idea of a nonce (a random number used only once to prevent replays) looses its meaning. As for your own refund button, this is definitely doable but will require them to provide personal information to the app, which some people might not like. Getting an email from the same account that placed the order is usually sufficient, so you might want to simply start their default email client from the app. – Nikolay Elenkov Oct 10 '12 at 08:27
  • [About nonces] I will have 3 requests to my server: 1. Empty ping 2. Nonce request (nonce will be generated on a server and stored in a server's DB) before GET_PURCHASE_INFORMATION 3. SignedJsonFromGoogle+Signature will be passed in the final step to my server. [About refund] I do not gather any personal information from the Android device so user accounts on my server are not strictly tied to user's Google accounts. And you mean if I get just e-mail I can identify the order in Google merchant account by this e-mail, right (didn't know that)? – IPSUS Oct 10 '12 at 08:42
  • Re: your protocol -- sounds about right. As for the order -- managed orders are tied to the Google account of the user, and it is displayed in the developer console. For unmanaged orders you have to this yourself. – Nikolay Elenkov Oct 10 '12 at 09:28
  • Unfortunately, I deal with unmanaged in-app products. Does it mean that Google order is not tied to a corresponding Google account? – IPSUS Oct 10 '12 at 10:44
  • The order is, but not the purchased item. You cannot restore items automatically or check if the user has already bought it. You have to implement this tracking yourself. – Nikolay Elenkov Oct 10 '12 at 12:13