Problems with IAP-Code - can someone maybe post his own code that works?

In the past, my IAP was working quite well with the “IAP Badger” plugin (well, the spinner kept spinning after the successful payment, so there never was a positive reply to the customer, but that was at least somewhat okay).

Now I am trying to build a new IAP function for all of my apps and cannot get it to work properly.

The IAP product is quite simple: the user can buy the full version of an app which just sets and saves a couple of variables.

I got this version to work with Android, it was possible to make purchases, the customer gets a positive response (thankyou.lua)… BUT for some reason the code in the function “freischalten” didn’t get called properly. OK, I can fix that probably.

On iOS on the other hand, I don’t get a connection to the app store.

It all seems so easy, but there still must be some faults in my code…?

Can maybe someone post his own IAP code that works?

local function freischalten() -- set variables here to unlock full version !! end local function StoreListener(event) local function afterDelay() -- it seems to be needed to include a delay here! local transaction = event.transaction if transaction == "purchased" then if isGoogleRestore then -- Restore purchase code goes here freischalten() -- add some text message to the user that restore was successful else -- successful purchase. Give user what they paid for freischalten() composer.gotoScene("thankyou") end elseif transaction == "restored" then -- Apple or Amazon restore code goes here freischalten() -- add some text message to the user that restore was successful elseif transaction == "cancelled" then -- User decided to cancel purchase elseif transaction == "failed" then -- Something went wrong. User could not purchase item. -- add some alert message end store.finishTransaction(transaction) end -- End function afterDelay timer.performWithDelay(500, afterDelay) end local function kaufVorgang() -- make a purchase btn.alpha = 0 -- hide button if platform == "amazon" then store.init(StoreListener) else store.init(platform, StoreListener) end if platform == "apple" then if store.canMakePurchases then store.purchase({"Apple product name"}) else -- add some text message: no product available end else store.purchase("Google product name") end end -- /////// BUY-Button /////// ------------------------------------------------------------------ btn = widget.newButton ( { defaultFile = "buy1.png", overFile = "buy2.png", left = 20, top = 370, onEvent = kaufVorgang } ) sceneGroup:insert(btn)

Sorry, forgot the lines above to set the right store:

local btn, meinText, isGoogleRestore, store local platform = system.getInfo("targetAppStore") if platform == "apple" then store = require ("store") elseif platform == "google" then store = require("plugin.google.iap.v3") elseif platform == "amazon" then store = require ("plugin.amazon.iap") end

Hi, if you move your store.init() calls out of the button code will it make any difference? For example if you place init section below the function kaufVorgang()?

Yes, actually I did this now in a newer version. Here the optimized code that worked well with Android and iOS:

------------------------------------- set IAP variables local btn local store local meinText local platform (...) local textOptions = { parent = sceneGroup, text = "Buy the full version!", x = 20, y = 100, width = 266, font = native.systemFont, fontSize = 16, } meinText = display.newText (textOptions) ------------------------ Start IAP-Funktionen ----------------------------- ------------------------------------- choose correct store platform = system.getInfo( "targetAppStore" ) if platform == "apple" then store = require( "store" ) elseif platform == "google" then store = require( "plugin.google.iap.v3" ) elseif platform == "amazon" then store = require( "plugin.amazon.iap" ) end ------------------------------------- store listener local function StoreListener( event ) if event.transaction.state == "purchased" then -- successful purchase OR Google restore -- (code to unlock the full version) store.finishTransaction(event.transaction) composer.gotoScene( "thankyou" ) elseif event.transaction.state == "restored" then -- Apple or Amazon restore -- (code to unlock the full version) meinText.text = "Some text about success with the restore" store.finishTransaction(event.transaction) elseif event.transaction.state == "cancelled" then -- User decided to cancel purchase meinText.text = "Some text that the process has been cancelled" store.finishTransaction(event.transaction) elseif event.transaction.state == "failed" then -- Something went wrong. User could not purchase item. meinText.text = "Some error text" store.finishTransaction(event.transaction) end end ------------------------------------- wait 1 sec, then init store timer.performWithDelay( 1000, function() store.init( StoreListener ) end ) ------------------------------------- user pressed the button to buy local function buyFullVersion() -- make a purchase btn.alpha = 0 -- hide button if store.isActive == true then meinText.text = "Please wait..." end if platform == "apple" then if store.canMakePurchases then store.purchase({"nameFullVersionApple"}) else meinText.text = "Error: no connection to the app store" end else store.purchase("nameFullVersionGoogle") end end ------------------------------------- button to buy full version btn = widget.newButton ( { defaultFile = "buy1.png", overFile = "buy2.png", left = 20, top = 180, onEvent = buyFullVersion } ) sceneGroup:insert(btn)

Sorry, forgot the lines above to set the right store:

local btn, meinText, isGoogleRestore, store local platform = system.getInfo("targetAppStore") if platform == "apple" then store = require ("store") elseif platform == "google" then store = require("plugin.google.iap.v3") elseif platform == "amazon" then store = require ("plugin.amazon.iap") end

Hi, if you move your store.init() calls out of the button code will it make any difference? For example if you place init section below the function kaufVorgang()?

Yes, actually I did this now in a newer version. Here the optimized code that worked well with Android and iOS:

------------------------------------- set IAP variables local btn local store local meinText local platform (...) local textOptions = { parent = sceneGroup, text = "Buy the full version!", x = 20, y = 100, width = 266, font = native.systemFont, fontSize = 16, } meinText = display.newText (textOptions) ------------------------ Start IAP-Funktionen ----------------------------- ------------------------------------- choose correct store platform = system.getInfo( "targetAppStore" ) if platform == "apple" then store = require( "store" ) elseif platform == "google" then store = require( "plugin.google.iap.v3" ) elseif platform == "amazon" then store = require( "plugin.amazon.iap" ) end ------------------------------------- store listener local function StoreListener( event ) if event.transaction.state == "purchased" then -- successful purchase OR Google restore -- (code to unlock the full version) store.finishTransaction(event.transaction) composer.gotoScene( "thankyou" ) elseif event.transaction.state == "restored" then -- Apple or Amazon restore -- (code to unlock the full version) meinText.text = "Some text about success with the restore" store.finishTransaction(event.transaction) elseif event.transaction.state == "cancelled" then -- User decided to cancel purchase meinText.text = "Some text that the process has been cancelled" store.finishTransaction(event.transaction) elseif event.transaction.state == "failed" then -- Something went wrong. User could not purchase item. meinText.text = "Some error text" store.finishTransaction(event.transaction) end end ------------------------------------- wait 1 sec, then init store timer.performWithDelay( 1000, function() store.init( StoreListener ) end ) ------------------------------------- user pressed the button to buy local function buyFullVersion() -- make a purchase btn.alpha = 0 -- hide button if store.isActive == true then meinText.text = "Please wait..." end if platform == "apple" then if store.canMakePurchases then store.purchase({"nameFullVersionApple"}) else meinText.text = "Error: no connection to the app store" end else store.purchase("nameFullVersionGoogle") end end ------------------------------------- button to buy full version btn = widget.newButton ( { defaultFile = "buy1.png", overFile = "buy2.png", left = 20, top = 180, onEvent = buyFullVersion } ) sceneGroup:insert(btn)