Google in-app re-buy managed item - android

Is it possible that I can re-buy a manged item?
I am testing my android app and I did not use the checkPayload method when I bought the item first.
now I implemented the checkPayload method and of course now it tells me that the payload isn't the same... Is it possible I can reject the first time buy and re-buy it again?
I anyway would like to re-buy it again, so I can test my code...

Cancel transaction from google play console, wait a lot of time (few hours) and you will be able to purchase it again.
BTW - you should check inventory on Google Play to get purchased items in case of some issues during purchase (i.e. crash between purchase and notifying the application).

You should be using the latest version of the Google In-App Billing system, in which case you can 'consume' a managed product (all products are managed in v3). Once consumed, the user can purchase the item again. Since this is for testing, you'll want to disable this consumption in your release build.
http://developer.android.com/google/play/billing/billing_integrate.html#Consume

Related

Google in-app billing cancel test purchase

I'm testing in-app billing with my own cellphone
I've sucessfully added some acounts to alha track and they can now buy the goods in the test mode.
The thing is due a bug existent in the first alpha version the purchased good wasn't being consumed and now everytime i try to purchage i get
ITEM_ALREADY_OWNED
int ITEM_ALREADY_OWNED
Failure to purchase since item is already owned
reading googles guide about testing in-app billing it says:
Cancel completed test purchases Google Play accumulates completed test
purchases for each user, but does not pass them to financial
processing.
In some cases, you may want to manually cancel a trial purchase to
continue testing. To do so, open the app page in the Play Store. If
the test purchase you want to cancel is a subscription, you can also
use the cancel () method of the Purchases.subscriptions API.
I do not find an option to cancel the test purchases at googles play page of my app, nor in the console neither in the tester account...
how can i cancel it to keep testing?
The problem here is that you need to consume the item, instead of cancelling. The item was purchased, and while not consumed you won't be able to buy it again. Please check this answer on how to consume the item. Hope it helps.

How to make purchasing one in-app product several times possible?

I'm trying to implement in-app billing system in my app to serve ads free version to users. I learned these steps and finally I succeeded to buy my product by using my test account. (I got the OK resposeCode through onPurchasesUpdated() method.)
However I could not buy it again. There was no response after calling launchBillingFlow(). I don't know why. Even if my product is ads free version (I mean permanent item.), I want to know that buying one item several times. Please let me know.
Once a managed product is purchased, it is considered to be "owned".
Managed products in the "owned" state cannot be purchased from Google
Play. You must send a consumption request for the "owned" managed
product before Google Play makes it available for purchase again.
Consuming the managed product reverts it to the "unowned" state, and
discards the previous purchase data
As soon as the User buys a product from your application, just consume it and keep track of the purchase some other way. By storing the credits on your server may be.
More on the developer site
Just be sure to call mBillingClient.endConnection() before calling mBillingClient.startConnection() again.
If you don't call endConnection() onPurchaseUpdated() will be called for every connection that is not closed.
In my case I call mBillingClient.endConnection() inside onDestroy() method of my activity.

"You already own this item" Google play inapp error

I've implemented API version 3 of GooglePlay Inapp purchase.
I'm logged in with the same Google account on two devices.
On device #1, I've just purchased an item using this: https://developer.android.com/google/play/billing/billing_integrate.html#Purchase
When I immediately query the purchased items (on device #1) with: https://developer.android.com/google/play/billing/billing_integrate.html#QueryPurchases it returns the info of the in-app so everything is fine.
When I query the list of purchases on device #2, it won't return the item I've just purchased, it returns an empty list.
When I try to buy the item on device #2 it tells me I already own it.
Any ideas on why the purchase from device #1 is not reflected on device #2 ?
Please note that the inapps are Managed products, so Google should hande the syncing across different devices with the same google account, right ?
Invalidating a purchase to test it again
This applies to products that the user can buy only once. This means that you don’t consume the purchase. More on consumption later.
In this case, after you make a purchase, if you will try to purchase it again you will receive an error saying that you already own this item.
How do you get past that?
You refund the purchase from Google Play Console. But there’s a catch. When you refund it you will have to remove the entitlement for that product, or the user will still get the error that it already owns the item.
For that, you go into Order Management from Google Play Console main menu and select the Order you just made from your app. (If it’s a test order it will say Test: in front of the product name). Then in order details, you click refund and a screen with some options for a refund like the one below will appear.
In this screen, make sure to check the Remove entitlement box, so the user will no longer own the product in his Google Account. After you click refund you will be able to make a purchase again for the given product.
It seems that it takes a while for the changed to actually take place on GooglePlay. The device on which I buy the item, seems to cache that I did so, and instead of asking GooglePlay, it takes that from a local cache.
That's why another device did not know about the purchase.
It took about an hour for the second device to receive the purchase info from GooglePlay.

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.

Canceled a order but still shows in my owned item. android inapp purchase

I did implement the v3 api of google play in app purchase in my application.
Everything goes right but the strange thing is when i am testing it using my test account and canceled the order from my merchant account. in my app it still shows the item is owned by test user and he is able to use all premium functions.
Any suggestions on how can i get rid of this.
i tried it using complete uninstall and reinstall.
I believe what you may be seeing is Google Play's device-side cache. If the user reboots his phone it will clear it, otherwise you must wait for Google Play to update it's cache from the Google Servers. I have the opposite problem sometimes... user purchases, but for some reason Google Play gets an invalid response from Google's servers and caches a not purchased result for a couple of days. Rebooting the device, and in severe cases clearing the Google PLay data in the applications list causes Play to resync everything from Google.
If you have bought before by your account and it`s a non-consumable item, when you try again to buy the server will send you a status 'item bought'. (like a restore trasaction)
Else check all fields of the response from server.
Check the responde code:
http://developer.android.com/google/play/billing/billing_reference.html
BILLING_RESPONSE_RESULT_USER_CANCELED 1 User pressed back or canceled a dialog

Categories

Resources