So i’m trying to implement IAP for the first time in my app. I have 3 items that can be purchased. Basically I have a menu screen with buttons to go to different scenes. I have made 3 of them with an alpha of 0 and used Rob’s loadsave.lua module to save 3 values to a table. Everytime you go to the menu scene it loads the table and checks those values to see if any of the buttons should be made visible.
On the store scene I have 3 buy buttons that coorospond to 3 products. A successful purchase should change the table to a paid value so next time you load the menu that button should be visible. And vice versa if a refund happens. I’ve tried using both the static response (android.test.purchased) and a test account with a draft APK uploaded.
Both are having the same issue. When you press the button to buy, the android UI pops up, I go through the short process of buying it and get the Purchase Successful UI. But the table is not being updated properly, so the buttons are staying invisible and the natice.showAlert is not firing.
I have checked and tested my coding for using the loadsave.lua module and everything is perfect. The only problem I can see is the that the tstate events in the transactionCallBack function are NOT working. Here is the relevant parts of the code:
local function transactionCallback( event ) print("In transactionCallback", event.transaction.state) local transaction = event.transaction local tstate = event.transaction.state local product = event.transaction.productIdentifier if tstate == "purchased" then print("Transaction succuessful!") if whichOne[1] == product then storeSettings.sinePaid = true elseif whichOne[2] == product then storeSettings.speedPaid = true elseif whichOne[3] == product then storeSettings.boltPaid = true end loadsave.saveTable(storeSettings, "store.json") native.showAlert("Success", "Function is now unlocked!", {"Okay"}) store.finishTransaction( transaction ) elseif tstate == "restored" then print("Transaction restored (from previous session)") if whichOne[1] == product then storeSettings.sinePaid = true end if whichOne[2] == product then storeSettings.speedPaid = true end if whichOne[3] == product then storeSettings.boltPaid = true end loadsave.saveTable(storeSettings, "store.json") store.finishTransaction( transaction ) elseif tstate == "refunded" then print("User requested a refund -- locking app back") if whichOne[1] == product then storeSettings.sinePaid = false elseif whichOne[2] == product then storeSettings.speedPaid = false elseif whichOne[3] == product then storeSettings.boltPaid = false end loadsave.saveTable(storeSettings, "store.json") store.finishTransaction( transaction ) elseif tstate == "cancelled" then print("User cancelled transaction") store.finishTransaction( transaction ) elseif tstate == "failed" then print("Transaction failed, type:", transaction.errorType, transaction.errorString) store.finishTransaction( transaction ) else print("unknown event") store.finishTransaction( transaction ) end print("done with store business for now") end local function purchase( event ) if event.phase == "ended" then if event.target.num == 1 then print("Purchase Sine") store.purchase({"android.test.purchased"}) elseif event.target.num == 2 then print("Purchase Speed") store.purchase({"android.test.refunded"}) elseif event.target.num == 3 then print("Purchase Bolt") store.purchase({"android.test.canceled"}) end end end local function restorePurchases( event ) if event.phase == "ended" then print("Restore all purchases") store.restore() end end function scene:createScene( event ) local screenGroup = self.view Runtime:addEventListener( "key", onKeyEvent ) storeSettings = loadsave.loadTable("store.json") if store.availableStores.apple then timer.performWithDelay(1000, function() store.init( "apple", transactionCallback); end) end if store.availableStores.google then timer.performWithDelay( 1000, function() store.init( "google", transactionCallback ); end) end whichOne = {} whichOne[1] = "android.test.purchased" whichOne[2] = "android.test.refunded" whichOne[3] = "android.test.canceled" sineBuy = widget.newButton { id = "sineBuy", width = 125, label = "Buy", labelColor = { default = {255, 255, 255}, over = {19, 124, 21}}, font = "BerlinSansFB-Reg", fontSize = 16, defaultFile = "Images/buyOver.png", overFile = "Images/buy.png", onRelease = purchase, } sineBuy.num = 1 sineGroup:insert(sineBuy) sineBuy.x = display.actualContentHeight-85 sineBuy.y = 110 speedBuy = widget.newButton { id = "speedBuy", width = 125, label = "Buy", labelColor = { default = {255, 255, 255}, over = {19, 124, 21}}, font = "BerlinSansFB-Reg", fontSize = 16, defaultFile = "Images/buyOver.png", overFile = "Images/buy.png", onRelease = purchase, } speedBuy.num = 2 speedGroup:insert(speedBuy) speedBuy.x = display.actualContentHeight-85 speedBuy.y = 170 boltBuy = widget.newButton { id = "boltBuy", width = 125, label = "Buy", labelColor = { default = {255, 255, 255}, over = {19, 124, 21}}, font = "BerlinSansFB-Reg", fontSize = 16, defaultFile = "Images/buyOver.png", overFile = "Images/buy.png", onRelease = purchase, } boltBuy.num = 3 boltGroup:insert(boltBuy) boltBuy.x = display.actualContentHeight-85 boltBuy.y = 230 restoreButt = widget.newButton { id = "restoreButt", width = 125, label = "Restore", labelColor = { default = {255,255,255}, over = {198,68,68}}, font = "BerlinSansFB-Reg", fontSize = 20, defaultFile = "Images/restoreButtOver.png", overFile = "Images/restoreButt.png", onRelease = restorePurchases, } restoreButt.num = 3 restoreButt.pressed = false screenGroup:insert(restoreButt) restoreButt.x = display.actualContentHeight-85 restoreButt.y = 290
And on the menu page:
function scene:createScene( event ) local screenGroup = self.view storeSettings = loadsave.loadTable("store.json") if (loadsave.loadTable("store.json") == nil) then storeSettings = {} storeSettings.sinePaid = false storeSettings.speedPaid = true --set to true atm to test refunds storeSettings.boltPaid = false loadsave.saveTable(storeSettings, "store.json") end if storeSettings.sinePaid then sineButt.alpha = 1 else sineButt.alpha = 0 end if storeSettings.speedPaid then speedButt.alpha = 1 else speedButt.alpha = 0 end if storeSettings.boltPaid then boltButt.alpha = 1 else boltButt.alpha = 0 end
I can’t for the life of me figure out what is not working