The Google Play store does only support consumable products. If you need non-consumable products it is recommended to use manual fulfilment of purchases and never finish purchases for products that should be non-consumable. As long as a purchase isn’t finished it will be returned as an active purchase when iap.set_listener() is called. If you do not call iap.finish() on a purchase you still need to indicate to Google Play that the purchase has been handled. You can do this by calling iap.acknowledge(). If you do not call iap.acknowledge() the purchase will be automatically refunded by Google after a few days.
Google Play and Apple supports three different product types: subscriptions, consumable and non-consumable products.
Which one is it, does Google Play support non-consumable products such as a one time purchase of “Disable Ads”.
Will I have to go the route of not calling iap.finish() for such purchases? or will the extension handle this? Since its mentioned in next section that Google supports this kind of product.
Google Play supports both consumable and non-consumable one time products:
A consumable product is bought and consumed (and then can be bought again), while a non-consumable product is bought and never consumed (and can not be bought again).
The difference is in how you treat the products in your purchase flow. For a non-consumable product you call acknowledge() but not finish(). I will make sure to clarify the docs.
So for non-consumable iap, such as disable-ads, we do not call iap.finish(), but we must call iap.acknowledge() otherwise the purchase will be refunded.
So looking at the example script in the github:
local function buy_listener(self, transaction, error)
pprint(transaction)
if error then
log("iap.buy() error %s - %s", tostring(error.error), tostring(error.reason))
return
end
if iap.get_provider_id() == iap.PROVIDER_ID_GOOGLE and transaction.ident == NON_CONSUMABLE then
log("iap.buy() ok - google")
gui.set_color(gui.get_node("reset/larrylabel"), vmath.vector4(1,1,1,1))
product_items["reset"] = transaction
else
log("iap.buy() ok %s", transaction.ident)
if self.finish then
log("iap.finish() %s", transaction.ident)
iap.finish(transaction)
elseif self.acknowledge then
log("iap.acknowledge() %s", transaction.ident)
iap.acknowledge(transaction)
end
end
end
should we add iap.acknowledge(transaction) at the end of if block?
Yes, but for transaction.ident == NON_CONSUMABLE, we dont call iap.finish()right? Then in that case we should call iap.acknowledge? As per documentation, otherwise the purchase will be refunded.
I was just trying to clarify if the example code in the github repository missed to call acknowledge() as we are supposed to.
Also, one more thing please, I keep reading in the API docs: if `auto_finish_transactions` is disabled in project settings... And also in the code example in the API
local function iap_listener(self, transaction, error)
if error == nil then
-- purchase is successful.
print(transaction.date)
-- required if auto finish transactions is disabled in project settings
if (transaction.state == iap.TRANS_STATE_PURCHASED) then
-- do server-side verification of purchase here..
iap.finish(transaction)
end
else
print(error.error, error.reason)
end
end
function init(self)
iap.set_listener(iap_listener)
iap.buy("my_iap")
end
But I cant find auto finish transactions anywhere in the game.project file. Is this related to a previous version of the extension?
Ah, thanks for pointing this out. This used to be part of game.project but that is no longer the case. The developer needs to open game.project and manually add it:
Could you please report this in the extension repository? I’d like to fix these documentation issues when we updated to Android Billing 8.0.0 later this year.