19

I am trying to implement in-app billing into my application, I have the buying part working right but how do I take care of issuing a refund?

Under the Testing In-App Billing section it says that you have to watch for IN_APP_NOTIFY but when you click about that it takes you to v2 of the api where you have to register a broadcast receiver. In v3 however it gives no information on what to do or if even IN_APP_NOTIFY is still used the same or supported.

The sample app does not handle refunds either so how am I suppose to handle refunds in v3?

A--C
  • 36,351
  • 10
  • 106
  • 92
tyczj
  • 71,600
  • 54
  • 194
  • 296
  • As far as I know, refunds are not supported for in-app purchases. The reason is that the goods may have been already consumed. – Henry Jan 27 '13 at 17:34
  • @Henry but for non-consumable items such as unlocking more of an app like a premium upgrade or something where you have full access to the whole application. I dont believe that they would not implement something for this. It appears it was available in v2 too – tyczj Jan 27 '13 at 17:38
  • 3
    Have a look at http://support.google.com/googleplay/android-developer/bin/answer.py?hl=en&answer=1153485 – Henry Jan 27 '13 at 18:04
  • @Henry well thats annoying, thanks for the info – tyczj Jan 27 '13 at 20:46

1 Answers1

32

You are supposed to handle them the same way as in v2: when a user requests a refund, cancel or refund the order via the Checkout console. Then the app should check the status of the purchase when starting up, etc. and do the right thing (typically allow access for refunded purchases, and deny for cancelled ones). Unfortunately the provided sample doesn't bother doing this, so you will have to add it yourself. Even more unfortunate is the fact that due to local caching and/or bugs on the server side, purchases will stay in the purchased state long after you cancel or refund them. There is not much you can do about it though ATM.

Assuming you are using the Trivial Drive sample, you might want to add something like this to your app:

Purchase purchase = inventory.getPurchase(product);
Log.d(TAG, "Purchase state: " + purchase.getPurchaseState());
// 0 (purchased), 1 (canceled), or 2 (refunded).
if (purchase.getPurchaseState() == 0
     || purchase.getPurchaseState() == 2) {
   showPremiumVersion();
} else {
   showFreeVersion();
}
Nikolay Elenkov
  • 52,576
  • 10
  • 84
  • 84
  • So since I check he purchase state of all the purchases when the app starts up each time, I could technically do without the `BroadcastReceiver`? – tyczj Feb 02 '13 at 16:17
  • 1
    Yes, a `BroadcastReceiver` is no longer needed with v3. – Nikolay Elenkov Feb 03 '13 at 02:10
  • 7
    Why use state 2 (refunded) for premium version? Other than that great answer – Rolf ツ Mar 20 '13 at 14:27
  • 3
    To keep users happy :) Someone complains about premium feature X, requests a refund. You refund, but let them keep using it. You fix X in next release, they notice, and if you are lucky give you a few more stars. (rarely works like this, but worth a try). – Nikolay Elenkov Mar 21 '13 at 01:52
  • This is dangerous. Perhaps the user cancels due to having a friend who canceled and continued using paid resources. Thus, it becomes an epidemic. They cancel knowing that they can continue using. In the end, they did not pay. – Cícero Moura Nov 20 '14 at 03:09
  • @CíceroMoura Cancel and refund are different things. A user cannot initiate a refund themselves, it has to be done by the developer. – Nikolay Elenkov Nov 20 '14 at 06:56
  • 1
    Yes, but I am saying that a user buys an item, and then asks the developer to refund. He realizes that he will continue using. So he tells other friends who can do that without having to pay to use, just because they ask to cancel. – Cícero Moura Nov 20 '14 at 11:09
  • 1
    A sudden increase in refunds will be pretty obvious. And even if a few people do this, it won't matter much. In any case, you really want to have a lot of sales (i.e., an app people really *want* to buy), not try to get money out of people who are unwilling to pay (or try to cheat) for some reason or another. – Nikolay Elenkov Nov 20 '14 at 17:41
  • 2
    @Nikolay Elenkov Agreed - if someone wants to steal it, he will probably find the way and it's waste of time to care about it. – Quark Feb 28 '15 at 14:31
  • @NikolayElenkov I refunded my purchase from developer account. But my testing account still showing me purchase state is purchased (i.e. 0). Any idea what is the issue here? – Bipin Vayalu Mar 02 '15 at 17:18
  • Hi how about in case of a canceled Subscription? Normally user will not get $ back for it and still have access for the subscribed period, his subscription will not be renewed. – AlexVPerl Mar 30 '15 at 22:39
  • This does not work at all, because 'purchase.getPurchaseState()' will always return either 1 or 2, but never 0. – Prexx Jun 12 '20 at 12:17