Checking if IAP was previously purchased

It looks like I might have misunderstood the loadProducts() function of the Google IAP plugin. https://docs.coronalabs.com/plugin/google-iap-v3/loadProducts.html

This is the brunt of what I have:

local iapStore = require( "plugin.google.iap.v3" ) local function iapDisableAdsListener( event ) -- if product is available to purchase, it's because the user hasn't yet purchased it so make sure adverts are enabled if(#event.products == 1) then globals.settings.adverts = true globals.iaps["disable adverts"].price = event.products[1].localizedPrice else globals.settings.adverts = false end globals.writeSettingsFile() end local function storeTransactionListener( event ) if(event.name == "init") then -- Check to see if the user has purchased the disable advers IAP iapStore.loadProducts({ globals.iaps["disable adverts"].id }, iapDisableAdsListener ) elseif(event.name == "storeTransaction") then -- Calling iapStore.purchase() ends up here if not ( event.transaction.state == "failed" ) then if( event.transaction.productIdentifier == globals.iaps["disable adverts"].id ) then globals.settings.adverts = false globals.writeSettingsFile() end end end end iapStore.init( storeTransactionListener )

So, I’m calling .init() with storeTransactionListener() as the callback. Then I’m doing a loadProducts() call within that, where globals.iaps[“disable adverts”].id is the IAP product ID (this is definitely correct - other parts of the code use the same variable and work just fine), and iapDisableAdsListener() is its callback.

Ref https://docs.coronalabs.com/plugin/google-iap-v3/event/productList/index.html I thought that iapDisableAdsListener() would receive two lists - event.products being the list of valid products and event.invalidProducts being the list of invalid. I expected that an invalid product would be one that’s been purchased already, so the filtered-to-one-product call should result in one or zero products in the valid list, depending on whether the player has already purchased that product or not?

Currently, when I call .purchase() everything works as expected and my globals.settings.adverts variable is set to false but when I restart the app and this code runs, #event.products is still at 1 so the variable is set back to true again. The variable is actually part of a settings file which is correctly rewritten at the appropriate times and is still at false before this code runs.

So, it looks like I might have misunderstood the valid and invalid product lists. But currently the build is in internal testing and payment is via test cards, so it could be that I’ve understood correctly but that the product simply remains in the valid list until a real purchase is made?

Thoughts please?

Nevermind. I found https://docs.coronalabs.com/guide/monetization/IAP/index.html#restoring and realised my idiocy =). I’ve modified the above now, to just update prices when initiated instead of checking for purchases. Players could potentially edit the settings file directly to disable ads but I guess this would require a rooted device and a little know-how, so the likelihood is slim. I’m then just calling .restore() if the settings file is missing, to account for players who erase the app data or change devices.

Amended code, in case it’s helpful to anybody else:

local iapStore = require( "plugin.google.iap.v3" ) local function iapUpdatePricesListener( event ) -- We're only dealing with one IAP so... if(#event.products == 1) then globals.iaps["disable adverts"].price = event.products[1].localizedPrice end end local function storeTransactionListener( event ) if(event.name == "init") then -- Update item prices iapStore.loadProducts({ globals.iaps["disable adverts"].id }, iapUpdatePricesListener ) elseif(event.name == "storeTransaction") then -- Calling iapStore.purchase() ends up here if ( event.transaction.state == "purchased" or event.transaction.state == "restored" ) then if( event.transaction.productIdentifier == globals.iaps["disable adverts"].id ) then globals.settings.adverts = false globals.writeSettingsFile() end end end end iapStore.init( storeTransactionListener )

Nevermind. I found https://docs.coronalabs.com/guide/monetization/IAP/index.html#restoring and realised my idiocy =). I’ve modified the above now, to just update prices when initiated instead of checking for purchases. Players could potentially edit the settings file directly to disable ads but I guess this would require a rooted device and a little know-how, so the likelihood is slim. I’m then just calling .restore() if the settings file is missing, to account for players who erase the app data or change devices.

Amended code, in case it’s helpful to anybody else:

local iapStore = require( "plugin.google.iap.v3" ) local function iapUpdatePricesListener( event ) -- We're only dealing with one IAP so... if(#event.products == 1) then globals.iaps["disable adverts"].price = event.products[1].localizedPrice end end local function storeTransactionListener( event ) if(event.name == "init") then -- Update item prices iapStore.loadProducts({ globals.iaps["disable adverts"].id }, iapUpdatePricesListener ) elseif(event.name == "storeTransaction") then -- Calling iapStore.purchase() ends up here if ( event.transaction.state == "purchased" or event.transaction.state == "restored" ) then if( event.transaction.productIdentifier == globals.iaps["disable adverts"].id ) then globals.settings.adverts = false globals.writeSettingsFile() end end end end iapStore.init( storeTransactionListener )