libgdx / gdx-pay

A libGDX cross-platform API for InApp purchasing.
Apache License 2.0
225 stars 83 forks source link

consume purchased item #6

Closed cococool closed 9 years ago

cococool commented 9 years ago

In google play we can't buy item that already owned. How to consume purchased item?

Thanks for creating this wonderful framework :)

noblemaster commented 9 years ago

Right now, consuming items is internally handled. So, whenever you are notified of a consumable item, after you handled it it will be consumed automatically thereafter. If you don't want the item to be consumed (e.g. because the external server where you want to store it is unavailable), you handler should throw an Exception which will prevent the item from being consumed internally.

In any case, whenever you properly handle a purchase, in my opinion it should be the responsibility of the PurchaseManager implementation to consume an item if it is a consumable. We could expose an extra method so you could consume it manually yourself, but I don't quite see any use cases why you would need that? Rather it adds more of a burden to implement the whole payment functionality.

cococool commented 9 years ago

Sorry but when I try with android to purchase consumable item, it was not consume automatically by the manager. When I try to purchase it again, I got error that I owned the item.

just4phil commented 9 years ago

The OUYA backend doesn't support this at the moment either.... We should decide what the backends should do so that I can implement that in the OUYA backend too...

noblemaster commented 9 years ago

When I try to purchase it again, I got error that I owned the item.

That's possibly a bug then. Did you set OfferType.CONSUMABLE when you setup the item for purchase via gdx-pay? If no, then the payment manager for OpenIAB (Google Play, Amazon etc.) doesn't know it's an item that has to be consumed. If you think you set it all up correct, would you mind posting your log output. There might be an error Error while consuming... in your logs. It would greatly help for me to fix things. Thanks!

The OUYA backend doesn't support this at the moment either... We should decide what the backends should do so that I can implement that in the OUYA backend too...

There is no "consume" functionality on iOS/Apple Mac Store. In that sense I would think consuming items has to be handled by the PaymentManager implementations. I would think to make integration easy, users of gdx-pay shouldn't have to take care of consuming purchases. On the other hand, we could add a consume-method too if you guys rather want to manually consume (although that option is not available on iOS)? Opinions?

In the payment manager for OpenIAB, I implemented it so we simply consume all the items after we have notified the app. If the app doesn't throw an Exception we assume everything is fine and consume:

if (offer.getType() == OfferType.CONSUMABLE) {
    // it's a consumable, so we consume right away!
    helper.consumeAsync(purchase, new IabHelper.OnConsumeFinishedListener() {
        @Override
        public void onConsumeFinished (Purchase purchase, IabResult result) {
            if (!result.isSuccess()) {
                // FIXME: if consume fails, the purchase manager should take note and
                //        try to consume again at a later point in time...
                Log.e(TAG, "Error while consuming: " + result);
            }
        }
    });
}
cococool commented 9 years ago

Oops sorry, forgot to set it. Will check again tomorrow. Thanks for the reply.

just4phil commented 9 years ago

@noblemaster hmm.... seems like there is no method to consume CONSUMABLES on OUYA. looks like they are just returned once and thats it.....

noblemaster commented 9 years ago

On iOS, the consumables are returned every time. In that sense I think the best approach is to only return consumables once for every payment-backend. The consumables will all be consumed internally by the corresponding PurchaseManager implementation and only returned once per device.

For iOS, given they are returned every time, we will have to set some default timeout; i.e. if you install an app on a new device, a consumable will only be shown if it is e.g. less than 24h old or so!?

ScarecrowNE commented 9 years ago

I'm a little late to the party but I thought I'd throw this in. While beta testing an app with pay 0-3-0 and gdx 1.4.2, the following can occur. My test app has only 2 consumables available. If purchases of either are made too close together timewise (say within a minute, haven't gotten too scientific with it), an "already owned" error/crash happens on future purchases. If a more realistc period of time between purchases is allowed, there are no problems or errors. The "already owned error" will correct itself over time (anywhere from a few minutes to an hour or so, I suppose depending on Google's level of busyness), or if the purchase is manually cancelled from the Dev Console. Otherwise, gdx-pay is working fantastic! Thanks for your efforts!

noblemaster commented 9 years ago

I haven't tested with 2 consumables of the same type being purchased right after each other. Given your description it seems the error/feature is happening on Google's server. I wonder if this actually an error. Google might just simply have added a minimum time until the same item can be purchased again to prevent double-purchases by mistake?

ScarecrowNE commented 9 years ago

I suspect it's more of a Google issue. Initially, for testing, we set things up so the beta testers would "run out of goodies" at an unrealistically fast rate. The goal being to put the IAB stuff through it's paces without having to wait days. The more gung-ho testers really hammered it, and it was those rapid-fire purchases that caused the error. Now that we've adjusted things a bit so even the geekiest/fastest testers take several minutes between purchases, the error has not resurfaced.
I think it's more a case of overwhelming Google's end, or as you said, Google's way of throttling the action. All systems "go" at this point! Thanks again!

kharindev commented 3 years ago

There is such a problem, if you press the buy button and immediately close the application, then the purchase will not be delivered, and when you return to the application, you will be informed that you already have this content. Hence, we need to manually consume the purchase, for this we need two getOwnedPurchases () methods and consumerPurchase (String productId).

MrStahlfelge commented 3 years ago

What happens if you restore the purchases?