How to detect canceled or refunded order for Google in-app billing?
Asked Answered
P

2

8

I have red a lot of posts and Google documents, but am still not clear how to tell an in-app purchase has been refunded. I have red carefully In-App Billing v3 - Don't detect refund and Does Google Play In-App Billing Version 3 support refunds?.

I believe that I took the following notes from an official Google document a while ago by copy & paste:

purchaseState: The purchase state of the order. Possible values are 0 (purchased), 1 (canceled), or 2 (refunded).

Now, the official document has the following:

-> purchaseState: The purchase state of the order. It always returns 0-

(purchased).

More specifically, if an IAB purchase is refunded or canceled, is that still in the user's inventory obtained by mHelper.queryInventoryAsync(mGotInventoryListener)? If so, how can one tell the purchase has been canceled or refunded?

Update [2019-12-12]:

I have tested many times and confirmed the following:

If an order is canceled after refunding, it will disappear from the results returned by getPurchasesList. The time it takes for this to happen varies. It could be minutes to over 10 hours. I think this depends on when Google Play refreshes its cache. It seems that one can open Google Play to refresh its cache. In one case, getPurchasesList still returned a refunded purchase more than 10 hours after refunding, but it stopped returning it as soon as Google Play is opened.

Prima answered 3/10, 2017 at 10:59 Comment(9)
Did you ever get any more info on this? After refunding an order I still see purchaseState as 0.Inopportune
@Inopportune No unfortunately. I think one way to deal with this is downloading all the voided orders to your own server, then check the order number against the data. developers.google.com/android-publisher/voided-purchases It is quite some work. I have not done it yet.Prima
That's so strange. Why can't they just make it automatic like they do for subscriptions and just not return that the user has that purchase?Inopportune
@Inopportune I remember that Google offers downloading all orders, but I am unable to find the API now. I will ask them tomorrow. There are quite some fake IAB purchases (check out this video among many hacks: youtu.be/3Zww3s8_A5g). Checking against the downloaded transactions would be a way to deal with these fake purchases.Prima
Did you ever figure a way to do this without needing server-side / API approach? I just asked a similar question here: #62028398Shandishandie
@JosephMcDermott Have you noticed my Update [2019-12-12]? That is sufficient for me.Prima
I did thank you @Hong, but still have questions :) I am going into Google Play Console and clicking 'refund' where I have the option to 'revoke' or not. Whether or not I revoke, I still get the purchase coming in purchasesList (even after 24 hours). The only way I have found to get a meaningful response from Google is to call acknowledgePurchase() to get a "Item is not owned by the user" result, however the docs clearly state to only acknowledge the purchase if it hasn't already been acknowledged, so feel like I shouldn't be calling acknowledgePurchase() over and over again...Shandishandie
@Prima I take it back... it has literally just this second disappeared when I tried again! I think it was from opening Google Play App and refreshing the "My Apps" screen. OK looking good now, the items I marked as 'revoke' are NOT in the purchaseList, whereas the items marked as 'dont revoke' are still active purchases, which makes sense. Thank you for your help!Shandishandie
@JosephMcDermott The cache problem of Google Play has been a chronic headache.Prima
J
5

Have you checked out the voided purchase list API? It returns a list of cancelled, refunded or charged-back purchases.

https://developers.google.com/android-publisher/api-ref/purchases/voidedpurchases/list

Jacqulynjactation answered 12/6, 2018 at 18:31 Comment(0)
C
-4

Scrape the Google Console. That's what I do.

Conclusive answered 12/6, 2018 at 18:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.