How to handle pending purchases from Google Play - android

Most of our purchases keep getting canceled after 3 days 30 minutes exactly, which I presume is the result of pending purchase state. However, there is so little documentation about how to handle pending purchases exactly. And, for some reason, even though I am a tester myself, I cannot test it because there is no "Slow card" option on purchase methods. Also, we do not have a backend server to well, back us up.
This is the explanation I've found from the official documentation:
void handlePurchase(Purchase purchase) {
if (purchase.getPurchaseState() == PurchaseState.PURCHASED) {
// Acknowledge purchase and grant the item to the user
} else if (purchase.getPurchaseState() == PurchaseState.PENDING) {
// Here you can confirm to the user that they've started the pending
// purchase, and to complete it, they should follow instructions that
// are given to them. You can also choose to remind the user in the
// future to complete the purchase if you detect that it is still
// pending.
}
}
Look at the explanation on the PENDING state. What does "To complete the purchase, they should follow instructions that are given to them" mean? What are these instructions exactly? Do we need to redirect the user to Google Play or what? It is not specific about what to do and is bugging me out because purchases are getting cancelled for no reason, or for this reason. How does one complete a pending purchase? There is nothing about it, or I cannot find it, hence I ended up here.
I hope you can help me figure this out. Thanks.

I agree the documentation is poor, especially since the one time you want to know exactly what's happening is when you're handling other people's money!
It looks like a 'slow card' transaction is actually a 'pending purchase', something Google have been rolling out in 2019. Here's the probable flow...
In your app the user taps 'Buy now'
They see the Google checkout overlay
They choose "Pay at Freddina's Grocery, Accra" (a local store that's signed up to deal with Google pending purchases)
Google checkout displays a code to show to Freddina
User pays Freddina in cash and Freddina processes the payment using that code
10 mins or so later, the purchase update will land in your app
As for handling unpredictably timed update events, we have an app with a handlePurchaseUpdated method listening out from the moment the app starts, and makes changes based on the Purchase object that comes with it. Here's an example flow:
We listen for purchase updates as soon as the app starts up
User makes a slow purchase
We get a purchase update
The passed Purchase object has purchase state PENDING
We tell the user that we'll notify them when the purchase is complete
At some point in the future (e.g. next day after an app restart) the purchase update comes in
If the purchase state is now PURCHASED we finalise the purchase and tell the user
Note: Ours is a ReactNative app, not native java, but the flow should be the same.
It's complicated to implement because you have to pick your time to make your purchase changes and display the purchase result at a time that makes sense, not necessarily when the purchase update arrives 5 secs after startup (or any other weird time). And it gets more complicated if there are errors during your grant-entitlement or acknowledgement steps, urgh.
Also, you might not be seeing the 'slow card' tester option because you didn't allow it?
Update for 2022: Personally I feel the documentation is still so poor, and the complexity so great, that I would recommend using a service like IAPHUB to manage iaps and subscriptions.

It sounds like you are not acknowledging the purchase. See below from the Google Play Billing documentation:
If you use the Google Play Billing Library version 2.0 or newer, you must acknowledge all purchases within three days. Failure to properly acknowledge purchases results in those purchases being refunded.

According to Google's documentation (https://developer.android.com/google/play/billing/integrate#pending), you need to call enablePendingPurchases() and then your PurchasesUpdatedListener will be notified when the state changes from PENDING to PURCHASED.

Related

What is the new "Resubscribe" feature found in Billing Library 2.0 and how is it different than the old Billing Library 1.2.2's?

In the Android Developer Console, I saw this message
Resubscribe isn't currently available for your users because your app
does not use Billing Library 2.0 in all active APKs
But, I was puzzled. Currently, we are using Billing Library 1.2.2.
This is how we decide, whether to show subscription button to user or not.
During queryPurchases, We will perform List<Purchase> purchases = PurchasesResult.getPurchasesList(). If the subscription's SKU is not found in purchases, we will show the subscription button. If not, we will hide the subscription button.
If this is a new subscriber, there will be no SKU in his purchases. Hence, he will see the subscription button, and allowed to subscribe again.
If this is a previous subscribed, and already cancelled user, we assume there will be no SKU in his purchases too!!! Hence, he will see the subscription button, and allowed to subscribe to the same sku again.
As you can see, even with old Billing Library 1.2.2, we are still allow user to resubscribe to same SKU again, to his previous cancelled subscription.
If that is so, why there is a special feature called "Resubscribe" (https://developer.android.com/google/play/billing/subs#resubscribe) in Billing Library 2.0? How does it different from our current Billing Library 1.2.2 flow?
To be perfectly honest, there isn't any enormous difference between resubscribing to the same sku with old and new approach using the resubscribe feature. Why? (None of these are solidly tested by the way, this is a logical explanation.)
In both cases, the subscription elements will stay the same and they will both return in queryPurchases method as long as the subscription is active.
This relates to the queryPurchases method, I haven't tested this yet, but it is possible that, in the old way, multiple purchases with the same sku might return, which may create a confusion. After resubscribing while canceled subscription is still active, the queryPurchases method will return only 1 subscription, causing queryPurchaseHistoryAsync method to return nothing. In the old way, if queryPurchases method returns only 1 purchase after getting a subscription over a canceled subscription with same sku, queryPurchaseHistoryAsync might actually return the old subscription that was canceled for, even if it was still active in a canceled state.
On Google Play Developer API side, there is a method that links a purchase token to the older one. For this, the Purchase.getLinkedPurchaseToken() function might return different values after subscribing to same sku, between the old way and new way. I presume, resubscribing to an active canceled subscription with the old way will generate a new purchase token, and getLinkedPurchaseToken(). This does not affect the BillingClient itself since there is no getLinkedPurchaseToken() method but logically this should be the result.
Bottom line: The only difference I can say is that resubscribing with the new way might reduce confusions, while on the old way there might be unnecessary data that you want to avoid from. As long as you have a subscription that's returned from queryPurchases where it matches your sku, you can consider that the user has an active subscription.
https://developer.android.com/google/play/billing/subs#resubscribe
Users can resubscribe in a number of different scenarios:
Before the subscription has expired, users can repurchase the same subscription in your app. This generates a new subscription and
purchase token.
Before the subscription has expired, users can restore the subscription in the Google Play subscriptions center. This keeps the
same subscription and purchase token.
After the subscription has expired, users can also repurchase the same SKU up to 1 year after expiration through the Google Play
subscriptions center. This generates a new subscription and purchase
token.
More details are provided in the release notes of 2.0 here: https://developer.android.com/google/play/billing/release-notes
I think the API is for subscriptions made outside your app (for example, from Google Play Subscriptions Center (mentioned in bullet point 3), or at a physical store).
Based on your question, it seems that you already handle the other scenarios regarding a user not having a subscription or having cancelled their subscription - but these flows apply to within the app, not outside. To gracefully handle purchases made outside the app you must use 2.x or higher.
The ability to process subscriptions outside the app, such as Google Play subscription Center or a physical store is not available in 1.x. It is available from 2.x+
Presuming you don't confuse the flow of subscriptions , that will remain as it is. Additional features have been added to Google play billing . As we talk , Google play billing 3.0 is up and ready. Follow this link
https://developer.android.com/google/play/billing/release-notes#3-0-0-summary-changes
Resubscribe feature will make restoring subscriptions easier.
There are scenarios where managing subscription should be made easy .
Subscription Restore and Resubscribe
Lets assume a user for some reason cancels the subscription renewals and before the subscription is expired and wants to subscribe it again. Now if user wants to resume it again. This newly feature will allow to resume the subscription as if they were never cancelled. For this the condition is that the subscription must not have expired . If it has expired , then here it is . Users will have to resubscribe instead. To resume any paused subscription users will need to resubscribe , you will have to treat this as you have been treating it.
Account hold feature
A user subscribes and sometimes users are unable to pay their subscription, whether due to financial woes or an expired credit card. In these cases, developers can initiate an Account Hold instead of cancelling it . This will allow users to manage the subscriptions until they fix the payment at their end.
Developers with existing apps will need to integrate Account Hold and Subscription Restore by November 1st. Unless they opt out, they’ll also need to integrate Subscription Pause and Resubscribe. If they fail to do so by the deadline, future updates may be rejected, thus delaying the launch of new features, bug fixes and metadata.

Google Play Billing library developer error code 5 if I want to consume or acknowledge the purchase

I added the latest Google Play Billing library:
implementation 'com.android.billingclient:billing:2.0.1'
If I make a purchase with a "slow testing card, which always be approved after a couple of minutes" (this is a testing card from Google to test in-app purchases):
val params = BillingFlowParams
.newBuilder()
.setSkuDetails(skuId)
.build()
billingClient.launchBillingFlow(activity, params)
Everything goes fine, until I try to acknowledge or to consume the product:
val consumeParams = ConsumeParams
.newBuilder()
.setPurchaseToken(purchase.purchaseToken)
.build()
billingClient.consumeAsync(consumeParams, this)
I'm getting the following error in the callback:
/**
* Invalid arguments provided to the API. This error can also indicate that the application was
* not correctly signed or properly set up for In-app Billing in Google Play, or does not have
* the necessary permissions in its manifest
*/
int DEVELOPER_ERROR = 5;
I also get a debug message saying that the purchase has an invalid state (PENDING). Probably I can't consume/acknowledge purchases which doesn't have the "SUCCESS" state.
According to Google, I have 3 days to consume or to acknowledge the purchase, otherwise it will be refunded.
But how am I supposed to consume or acknowledge the purchase if they won't allow me to make it right after the purchase was made?
I don't own a server, the consumption/acknowledge should be made on mobile
I can't keep the user with a loading progress dialog/view in the app while the purchase will be validated (getting the SUCCESS state. With a testing account, within 5 - 6 minutes I'm getting the new "SUCCESS" state via onPurchasesUpdated(billingResult: BillingResult?, purchases: MutableList<Purchase>?))
I'm using the MVVM architecture (Activity - ViewModel) and within the Activity I'm keeping the Billing Client library (because the library needs a Context) and in the ViewModel the business logic.
It looks like Google doesn't want us to "bind" the billing client library to an activity/viewmodel and instead use it in a Service and instantiate it in the Application class. Probably communicating with Observers or BroadcastReceivers and listen for purchase updates. And once the Purchase is validated or rejected I should update the user's profile. This already can cause a problem, because I can't start a Service without having a non-dismissable sticky notification because this is a foreground service and I should notify the user that the app is running in the background. This will scare the hell out of the users.
This new purchase flow breaks multiple things. This shouldn't be asynchronous. In real life situation when I purchase something, I give the money to the cashier then I receive my product/service not after 5 minutes! How am I supposed to deal with this? The user makes a purchase, then I notify the user he/she will get the product within 5 minutes after confirmation from Google? This should be instantaneous.
How do you deal with in-app purchases?
The answer is simple. Tell the user that the purchase request has occurred but the payment or request has not been confirmed or processed yet.
This situation should and must be asynchronous because it can happen in some scenarios and is exactly what happens in real life, such as when the user uses a payment method that is not instant. Some payment methods can take days to process - not everyone uses credit/debit cards or gift cards for online payments, and not everyone can! For example, in Brazil there is the Boleto payment system which is easy to pay for but takes a long time to process. People pay for their item, print out a receipt and go stand in line at certain places to pay for stuff. It is done this way because getting an international online card is very difficult, especially among the very poor.
So, what you need to do is you get your new purchase. Check its status. If it is SUCCESS then your payment is complete and tell the user. If it is PENDING, then tell the user that the payment request has been completed and awaiting payment confirmation from Google.
If you get a purchase in the PENDING state, when the payment clears you will get a new purchase request through the flow of your app, but this time it will say that the purchase was SUCCESS.
If this doesn't fit your current architecture then you must change your architecture.
I might be late to the party, but i hope it helped. My case is response code 5 invalid token. I got this error when try to consume a subscription product after successfully acknowledge. I made a mistake to differ which one need to be consume and which one are not.

Are Refunds For Android In App Consumable Purchases Supported? - In App Billing API V3

I'm not specifically looking to have the option to refund a user for an in app purchase of a consumable, but just in the odd case that a user asks for a refund, either through google, or through the developer of an in app purchase of a consumable.
There does not seem any way of handling refunds through the In App Billing api V3. All documentation points to V2 of the api using broadcast receivers. This does not help me in least bit.
So how are refunds handled in the In App Billing v3 api? I'm assuming for a non consumable, the refund is processed, and then google handles the processing through their backend, and then when a getPurchaseState() is conducted, it would return a value of 2 (refunded). If so, this works great for a NON CONSUMABLE product.
When a getPurchaseState() call to a consumable purchase is made, it returns null. That's assuming if the purchase was previously successful, and that the item was consumed and provisioned. I figure I could store the purchase items locally within the app, but then there is still no way of receiving a refund notification for that product. I can check for purchase state, but again, it will return null, as long as it was consumed and provisioned already.
A slight workaround I can think of right now, is to not consume the purchase on provisioning. So that it remains "unconsumed" according to google, and remains in their database. Now, if a refund is requested, I am assuming a call to getPurchaseState() for that consumable will return refunded, thus the application logic can then subtract/deduct the provisioned consumable from user's inventory. If a user would want to repurchase that consumable again, then before the IAB api call is made for the purchase, get the purchaseState() and/or hasPurchase(), and if there is already a purchase there, consume that item without provisioning, this will let the user repurchase that consumable. Only issue with this workaround, is that if A user wants to re purchase the same consumable product, as soon as the select the option to repurchase, the item must be consumed regardless of whether they successfully repurchase the product or not. So if the user does not complete the purchase, the product is already consumed, and I end up back where I am now with inability to check for refund state on the consumable.
I can't think of any other way to do a refund for a consumable in app product, and that is what I ask here. Is the way I thought of sufficient, or is there a proper way to handle refunds using IAP v3 on consumables?
I was thinking I have 3 options:
Don't offer refunds for consumables, no/little exceptions, but the issue with this is if a user requests refund through google, and not through developer, leading to option 3 below)
Find a workaround (either properly through the api, or with my proposed workaround)
Offer refunds, but have no application logic to subtract/deduct the consumable. In this scenario, users could end up taking advantage of free purchases.
I know this is a super late response to this issue, but it took me quite some time to track down info on this issue, so hopefully it can help someone else out. There are a few ways of doing this... In the Google Play Developer console you can click on the left nav saying "Order Management" which will bring up a list of all recent orders though your app. If you need to refund one you can click on it, or multi select them and refund them in this view. Just a heads up... you will most likely need permissions from your account admin to see this view and refund users.
Your other option is though the API docs here. You will need to set up your API account though the Android console, which I will say is a massive pain and not clear. But once that's set up and your "Server Applications" is set up you will need to make sure it has proper permissions as well. Then you should be able to use a library such as this to do the heavy lifting for you, because from what I've read the JWT auth process though the google API is not super straightforward, and their docs are a mess. I hope this helps someone and comment if you have questions... I will do my best to answer.
This same API also can be used to find items that were purchased by users and then refunded, so you can remove these items from those users' apps. Also you can do server side purchase validation through this as well, which is highly recommended, because rooted phones can inject fake purchase requests making your app believe that it's hearing back from the google play store, but in reality it's not. You then send back to your server the purchase token and SKU of the item being purchased and then on your server you just run this. This will give you back a 400 error if it's invalid, and a 200 with a some JSON data if it's a successful purchase.

Playstore subscriptions - testing strategy

Scenario:
I am on the verge of completing my google playstore in-app billing implementation. I am using a monthly or yearly subscription in order to charge my consumers.
Problem: I can't seem to find a way to remove a subscription from active state, since cancellation simply stops the billing from occurring. This doesn't allow QA to thoroughly test the purchase procedure without creating an account for each test, or waiting until the subscription period ends.
Question: Have I missed or am wrong about something? If so, what is it? If not, what should be done to allow QA to do proper testing?
According to what I have understood from your question,
you can not test subscription from the test account. Google play doesn't provide subscription testing using dummy product. you have to test on the real product.
Now question arises how can I test subscription
you can check subscription by purchasing real product and check product status or purchase cancellation using the purchase status api from your server.
you can also get more information from the given link below for the step by step cancellation purchase status:
1) link1
2) link2
you can simply query every day and check your subscription is valid or not and also get it's expiration date.
I also have one other option with out pay for any charges on your real product, you can set trial period in the Google console and before trial period ends up cancel subscription from the Google play store Menu -> MyApp -> Subsciption and cancel product and check above procedure given in the links.
EDIT:
Important: In all cases, you must continue to offer the content that
your subscribers have purchased through their subscriptions, for as
long any users are able to access it. That is, you must not remove any
subscriber’s content while any user still has an active subscription
to it, even if that subscription will terminate at the end of the
current billing cycle. Removing content that a subscriber is entitled
to access will result in penalties. Please see the policies document
for more information.
more information check below links:
1)
http://developer.android.com/google/play/billing/billing_subscriptions.html#cancellation
2) https://support.google.com/googleplay/answer/2476088?hl=en
3)
https://support.google.com/googleplay/android-developer/answer/140504?hl=en
You can not done this with out waiting until the subscription process cycle completes after cancellation of subs product, the only way remaining which is Free trial version it's only the way to provide us to test for the product cancellation in which product cancel immediately after you cancel subscription trial period, it will not continue until even trial periods ends.
more information check below link:
http://developer.android.com/google/play/billing/billing_subscriptions.html#administering
And I think it is better way because in the trial period you should go
with the actual credit card payment process but you doesn't need to
pay anything for it. Google play record the transaction as $0.00 for
the subscription process. And if you cancel the subscription the you
should not pay anything for testing, but yes I am not sure free trial version
is worked before you publish the app but it is only get by efforts only.
Conclusion:
In the current api it is not possible to test subcription product like
normal products and if user has been cancel the subscription product
then you have to wait to purchase the same product until the
subscription cycle has been expired, there is no another way if the
subscription cycle is going on and you can test for the same product
again before subscription cycle ends. And if you still want to test
for the same product then you have to choose another account for
testing it or another way is Free trials, you will not be any charged
until your Free trials period expired or cancel subscription in that
period and for the testing account before publish the app you will be refunded
automatically after 14 days of purchased product according to my
knowledge.
Hope it will solve your problem.
I have a horribly clunky workaround for this problem. Here is what I do every time I want to do a test of in-app subscriptions:
Create a new in-app subscription product in the google play developer console.
Point the android app at the new subscription product you just created.
In your code to check for active subscriptions, add a line to specifically ignore the order number of the previous subscription that you tested.
Export a release build of the app and transfer it directly to your testing device.
After testing, return to step #1 to test the next time.
Don't forget to fix your change from step #2 before deploying the app!
You might want to create many subscriptions in step #1 so you don't have to continually wait hours for them to propagate. Please comment if you know of a better way!
UPDATE: Google now has test subscriptions and is making it easier to use them! https://android-developers.googleblog.com/2018/01/faster-renewals-for-test-subscriptions.html
It seems that nowadays there is better solution:
Open your app page in Google Play Store application
Click "Manage subscriptions"
Click "Cancel subscription"
Go to "Settings", "Apps" in your phone.
Find Google Play Store and clear application data.
You should now be able to re-buy subscription.
Create a mock class that mocks out the Google Play methods that you are using.

Does Google Play In-App Billing Version 3 support refunds?

I've gotten IAB v3 working and I was able to make a purchase for a managed item. However, to continue developing and testing I wanted to refund the purchase so I could try making the same purchase again. I logged into my Google Checkout Merchant account and successfully refunded the purchase. However, the app still thinks that the user has the item purchased. It has already been several weeks since I made the refund so its not a delay issue.
Basically, in my QueryInventoryFinishedListener implementation, inventory.hasPurchase(SKU_REMOVE_ADS) always returns true, even after the refund (SKU_REMOVE_ADS is the SKU for item I'm selling). I was expecting it to return false after the refund had been processed.
If you look at the 'Handling Refunds' section of the IAB reference, it says that your app needs to be listening to the IN_APP_NOTIFY messages. However the documentation for IN_APP_NOTIFY is specific to v2 of in-app billing. It doesn't seem to be something that's available in v3 since its not mentioned anywhere in the v3 reference nor can I find any reference for it in the sample TrivialDrive app that they are using to demonstrate IAB v3.
So does v3 of IAB support refunds/cancelling purchases? Has any one tried it and got it working?
There really is no difference between a consumable item and a non-consumable item so far as Google Play is concerned; this distinction is entirely based on what you implement within your app. So even though the SKU you are testing is intended to be non-consumable (e.g., a permanent premium upgrade), for testing purposes, you can treat it as a consumable and consume it, so that it can be purchased again.
A convenient approach is to set up a temporary testing menu within your app (e.g., by adding a menu item during testing onto your app's main options menu), and then to have that item's handler invoke the consumeAsync() method of your IabHelper instance for the SKU that you want to test buying again. This will consume the item and thus make it immediately available for repurchase from your device.
You will, of course, still want to refund the purchase from Google Checkout, so that you won't be spending your own money just to test your app.
I would add that consumeAsync() also seems to work just fine for resetting the test SKU android.test.purchased, if you are testing using such static values.
Regarding the updating of purchase state to reflect a refund, I have personally experienced (and there are many similar reports posted by other developers) that manually initiating a refund via Checkout (e.g., for a test purchase from the TrivialDrive app) takes days to result in a change to the purchase state of the product (to INAPP_PURCHASE_STATE_REFUNDED).
(Knowing that misery loves company, some of those additional reports can be found on this discussion thread:
https://plus.google.com/+AndroidDevelopers/posts/R8DKwZDsz5m)
At least part of this is due to Google Play's caching of purchase data on the device.
In my experience, re-booting a device can sometimes cause Google Play to refresh its cache from the GP servers. So it may be that changes due to cancellation or refunding of an order via Checkout could also be detected after a reboot.
It might seem that such a long turnaround period would do you no good, since you can't know when users will reboot. But then again, you know that every device will, eventually, get rebooted, and so if your concern is that a user who receives a refund should eventually be blocked from using the refunded IAB product, a few days of delay may not matter much, so long as it eventually happens.
Of course, remember that this notion that cache will refresh on a reboot is undocumented and anecdotal (like quite a number of IAB3 and TrivialDrive behaviors, thus far). Folklore, they call it.
Another thing that triggers an update is when the user attempts to purchase the product. As soon as the purchase is launched, the system has to be sure that the product is not already owned, and so it updates the Google Play cache. In my personal experience, this has always occurred. But again, this is not a very practical way to check for a refund, because that would involve showing the purchase dialog unbidden, and also an error message that tells the user "you already own this, " (if they do own it).
Where this does come in handy is when the user pays for an IAB item on one of her devices, and then attempts to access that item on a different device that is owned by the same account as was used to buy it. The purchase information in that case has very often not yet been cached. But you can just put a little note in your purchase dialog that if the item has already been purchased, attempting a re-purchase should make it available on the present device at no additional charge. Sometimes it takes two (user-initiated) purchase attempts to finally get the IabHelper.BILLING_RESPONSE_RESULT_ITEM_ALREADY_OWNED response. Yes, a bit klugy, but I think in human terms it will work with appropriate highlighting of the message and apologetic wording of the confirmation dialog telling them that they own the item, etc. :-) ).
As a practical matter, you can see how Google might not want every instance of every IAB app in the world to access its servers every time the app's purchase data is being accessed, especially given that they are advising developers to do a check for what has been purchased each time the app is started. It's also a performance issue for your app - that's what caching is all about. So you need to be aware of the triggers for updating the cache, and I haven't found a single place where this is officially documented (except, we presume, in the code). So get ready to put your hands out in front of you and start feeling around in the dark.
For some additional information regarding Google Play buffering, see this page:
Under What Conditions are In-App Billing Version 3 Server Changes Made Available on Client Devices?
I would note that in your post's code snippet you are calling inventory.hasPurchase(SKU_REMOVE_ADS), but that will only tell you if the purchase is in the list of purchases returned in the inventory object; it will not tell you the state of the purchase for that SKU. I know that this is the approach used by the TrivialDrive app, but that app is not dealing with refunds and cancellations. To detect refunds and canceled orders, you'll need something like this:
Purchase removeAdsPurchase = inventory.getPurchase(SKU_REMOVE_ADS);
if(removeAdsPurchase != null) {
int purchaseStateForRemoveAds = removeAdsPurchase.getPurchaseState();
if(purchaseStateForRemoveAds == 1) {
//Do cancelled purchase stuff here
}
else if(purchaseStateForRemoveAds == 2) {
//Do refunded purchase stuff here
}
}
The good news about refunds and canceled orders is that both are, AFAIK, entirely at the option of the developer. So, if you find that users who get these are able to continue using your app for a long interval thereafter, and if you find that lots of users are taking advantage of this, then you can decide if you want to continue providing the refunds in all cases. My best guess is that it will not be a problem; even if some user who gets a refund gets to use your app for a while after that, that doesn't seen like a very big deal.
It is for testing that you need the ability to re-try a purchase very rapidly, and using consumeAsync() definitely works for that purpose.
I will suggest you to use static product ids while your app is in development phase.
Now make sure you are testing the app with same Gmail Id for which you have refund? To test the refund scenario I think you can use android.test.refundedas product id.
If this is not working then you can first check total purchased item(s) and Available item(s) in google play at first launch of your app and if you are getting same product id in both the calls(which should not be the case if this is the case please report this bug to google) then make api call to make same item as consumed.
Since posting this question, its been brought to my attention that I need to call getPurchase(...).getPurchaseState() and check for its value. Possible values are 0 (purchased), 1 (canceled), or 2 (refunded).
However, in my case its still retuning 0 (purhcased) even though the item is refunded. I'm posting this information here in case it helps someone else.

Categories

Resources