[RESOLVED] Problems with IAP

[build.settings was the culprit]

Hi all,

Trying to setup my IAP, and Corona is throwing me a fit :slight_smile:

As soon as I try to use store.availableStores.apple or store.init it throws an error:

attempt to call field ā€˜availableStoresā€™, a nil valueĀ 

or

attempt to call field ā€˜initā€™, a nil value

I required the store module withĀ store = require( ā€œstoreā€ )

Using Basic Subscription so that should be fine.

Anyone can tell me why this doesnā€™t work?

display.setStatusBar( display.HiddenStatusBar ) print("Start") --let's localize these values for faster reading local totalWidth = \_G.totalWidth; local totalHeight = \_G.totalHeight; local leftSide = \_G.leftSide; local rightSide = \_G.rightSide; local topSide = \_G.topSide; local bottomSide = \_G.bottomSide; local centerX = display.contentCenterX; local centerY = display.contentCenterY; -- REQUIRE STORYBOARD local storyboard = require "storyboard" local adsLib = require "adsLib"; local widget = require "widget" local Utils = require "Utils"; local Scene = storyboard.newScene() local Click = audio.loadSound("sounds/click.mp3") local store local v3 = false if ( system.getInfo( "platformName" ) == "Android" ) then print("Android") store = require( "plugin.google.iap.v3" ) v3 = true elseif ( system.getInfo( "platformName" ) == "iPhone OS" ) then print("Apple") store = require( "store" ) else native.showAlert( "Notice", "In-app purchases are not supported in the Corona Simulator.", { "OK" } ) end local currentProductList = nil local appleProductList = { "5000c", "12500c", "25000c", "50000c", "100000c" } local googleProductList = { "5000c", "12500c", "25000c", "50000c", "100000c" } ---------------------------------------------------------------- -- CREATE THE SCENE (WHEN THE SCENE'S VIEW DOES NOT EXIST) ---------------------------------------------------------------- function Scene:createScene( event ) group = self.view -- Handler that gets notified when the alert closes local function onComplete( event ) if "clicked" == event.action then ButtonPressed = false local i = event.index if 1 == i then print("Purchase") if BuyMode == 99 then store.purchase{ "5000c" } elseif BuyMode == 199 then store.purchase{ "12500c" } elseif BuyMode == 299 then store.purchase{ "25000c" } elseif BuyMode == 499 then store.purchase{ "50000c" } elseif BuyMode == 999 then store.purchase{ "100000c" } end elseif 3 == i then -- Do nothing; dialog will simply dismiss end end end storeBackground = display.newImageRect( group, "images/buycoins.jpg", totalWidth, totalHeight) storeBackground.x = centerX storeBackground.y = centerY local manageStore = function(event) if event.phase == "began" then Utils.playSound ( Click ) BuyMode = event.target.Value if event.target.Value == 99 then local alert = native.showAlert( "Buy coins", "Buy 5.000 coins for $0.99?", { "Yes", "No", }, onComplete ) elseif event.target.BuyMode == 199 then local alert = native.showAlert( "Buy coins", "Buy 12.500 coins for $1.99?", { "Yes", "No", }, onComplete ) elseif event.target.BuyMode == 299 then local alert = native.showAlert( "Buy coins", "Buy 25.000 coins for $2.99?", { "Yes", "No", }, onComplete ) elseif event.target.BuyMode == 499 then local alert = native.showAlert( "Buy coins", "Buy 50.000 coins for $4.99?", { "Yes", "No", }, onComplete ) elseif event.target.BuyMode == 999 then local alert = native.showAlert( "Buy coins", "Buy 100.000 coins for $9.99?", { "Yes", "No", }, onComplete ) end end end --- 5 labels which will show the value of the IAP IAPTextArray = {} xPos = 540 yPos = 168 for t = 1,5 do IAPTextArray[t] = display.newText( group, "$ 0.99", 10, 0, "SaranaiGame", 40) IAPTextArray[t].x = xPos IAPTextArray[t].y = yPos yPos = yPos + 78 end btn99 = widget.newButton{ left = 0, top = 1100, defaultFile = "images/Buttons/btnBuy.png", overFile = "images/Buttons/btnBuyS.png", width=285, height=68, onEvent = manageStore } btn99.Value = 99 btn99.x = 806.5 btn99.y = 174 group:insert(btn99) btn199 = widget.newButton{ left = 0, top = 1100, defaultFile = "images/Buttons/btnBuy.png", overFile = "images/Buttons/btnBuyS.png", width=285, height=68, onEvent = manageStore } btn199.Value = 199 btn199.x = 806.5 btn199.y = 251 group:insert(btn199) btn299 = widget.newButton{ left = 0, top = 1100, defaultFile = "images/Buttons/btnBuy.png", overFile = "images/Buttons/btnBuyS.png", width=285, height=68, onEvent = manageStore } btn299.Value = 299 btn299.x = 806.5 btn299.y = 328 group:insert(btn299) btn499 = widget.newButton{ left = 0, top = 1100, defaultFile = "images/Buttons/btnBuy.png", overFile = "images/Buttons/btnBuyS.png", width=285, height=68, onEvent = manageStore } btn499.Value = 499 btn499.x = 806.5 btn499.y = 404 group:insert(btn499) btn999 = widget.newButton{ left = 0, top = 1100, defaultFile = "images/Buttons/btnBuy.png", overFile = "images/Buttons/btnBuyS.png", width=285, height=68, onEvent = manageStore } btn999.Value = 999 btn999.x = 806.5 btn999.y = 481 group:insert(btn999) local manageAd = function(event) if event.phase == "began" then Utils.playSound ( Click ) -- Play Vungle ad end end btnWatchAd = widget.newButton{ left = 0, top = 1100, defaultFile = "images/Buttons/btnWatchAd.png", overFile = "images/Buttons/btnWatchAdS.png", width=285, height=68, onEvent = manageAd } btnWatchAd.x = 806.5 btnWatchAd.y = 564 group:insert(btnWatchAd) local goBack = function(event) if event.phase == "began" then Utils.playSound ( Click ) storyboard.gotoScene( "game" ) end end btnBack = widget.newButton{ left = 0, top = 1100, defaultFile = "images/Buttons/btnBack.png", overFile = "images/Buttons/btnBackS.png", width=285, height=68, onEvent = goBack } btnBack.x = centerX btnBack.y = 707 group:insert(btnBack) --- IAP Stuff function storeTransaction( event ) local transaction = event.transaction if transaction.state == "purchased" then print("Purchased! Transaction succuessful!") if BuyMode == 99 then \_G.Coins = \_G.Coins + 5000 Utils.setSaveValue("coins",\_G.Coins,true) elseif BuyMode == 199 then \_G.Coins = \_G.Coins + 12500 Utils.setSaveValue("coins",\_G.Coins,true) elseif BuyMode == 299 then \_G.Coins = \_G.Coins + 25000 Utils.setSaveValue("coins",\_G.Coins,true) elseif BuyMode == 499 then \_G.Coins = \_G.Coins + 50000 Utils.setSaveValue("coins",\_G.Coins,true) elseif BuyMode == 999 then \_G.Coins = \_G.Coins + 100000 Utils.setSaveValue("coins",\_G.Coins,true) end --txtGameCoins:setText(tostring(\_G.Coins)) native.showAlert("Thank You!", "Thank you for your purchase!", { "OK" }) elseif transaction.state == "restored" then --- Restore elseif transaction.state == "cancelled" then print("User cancelled transaction") elseif transaction.state == "failed" then print("Transaction failed, type:", transaction.errorType, transaction.errorString) infoString = "Transaction failed, type: ", event.transaction.errorType, event.transaction.errorString local alert = native.showAlert("Failed ", infoString,{ "OK" }) else print("Else") infoString = "Transaction failed, type: ", event.transaction.errorType, event.transaction.errorString local alert = native.showAlert("Failed ", infoString,{ "OK" }) end ButtonPressed = false store.finishTransaction( transaction ) end print("Store:",store) if ( v3 == true or store.availableStores.google ) then currentProductList = googleProductList store.init( "google", storeTransaction ) elseif ( store.availableStores.apple ) then print("Store init apple") currentProductList = appleProductList store.init( "apple", storeTransaction ) else print( "In-app purchases are not supported on this system/device." ) end function loadProductsCallback( event ) print("showing products", #event.products) local str = "" --ScreenText.text = #event.products for i=1, #event.products do local currentItem = event.products[i] str = str .. (currentItem.title .. ", ".. currentItem.price .. " USD, " ..currentItem.productIdentifier .. "\n") --IAPTextArray[i].text = print("Product:",str) print(currentItem.description) print(currentItem.price) print(currentItem.productIdentifier) end --print("showing invalidProducts", #event.invalidProducts) for i=1, #event.invalidProducts do print("Invalid: ",event.invalidProducts[i]) end end print("loadProducts") store.loadProducts( currentProductList, loadProductsCallback ) end ---------------------------------------------------------------- -- CALLED IMMEDIATELY AFTER SCENE HAS MOVED ONSCREEN: ---------------------------------------------------------------- function Scene:enterScene( event ) end ---------------------------------------------------------------- -- CALLED WHEN SCENE IS ABOUT TO MOVE OFFSCREEN: ---------------------------------------------------------------- function Scene:exitScene( event ) end ---------------------------------------------------------------- -- CALLED PRIOR TO THE REMOVAL OF SCENE'S "VIEW" (DISPLAY GROUP) ---------------------------------------------------------------- function Scene:destroyScene( event ) end --------------------------------------------------------------------------------- -- END OF YOUR IMPLEMENTATION --------------------------------------------------------------------------------- -- "CREATESCENE" EVENT IS DISPATCHED IF SCENE'S VIEW DOES NOT EXIST Scene:addEventListener( "createScene", Scene ) -- "ENTERSCENE" EVENT IS DISPATCHED WHENEVER SCENE TRANSITION HAS FINISHED Scene:addEventListener( "enterScene", Scene ) -- "EXITSCENE" EVENT IS DISPATCHED BEFORE NEXT SCENE'S TRANSITION BEGINS Scene:addEventListener( "exitScene", Scene ) -- "DESTROYSCENE" EVENT IS DISPATCHED BEFORE VIEW IS UNLOADED, WHICH CAN BE -- AUTOMATICALLY UNLOADED IN LOW MEMORY SITUATIONS, OR EXPLICITLY VIA A CALL TO -- STORYBOARD.PURGESCENE() OR STORYBOARD.REMOVESCENE(). Scene:addEventListener( "destroyScene", Scene ) --------------------------------------------------------------------------------- return Scene

Oh hereā€™s my build.settings

settings = { plugins = { ["CoronaProvider.ads.vungle"] = { publisherId = "com.vungle", }, ["plugin.google.play.services"] = { publisherId = "com.coronalabs", }, ["CoronaProvider.gameNetwork.apple"] = { publisherId = "com.coronalabs",supportedPlatforms = { iphone=true, ["iphone-sim"]=true },}, ["plugin.google.iap.v3"] = { publisherId = "com.coronalabs", supportedPlatforms = { android=true }}, }, orientation = { default = "landscapeRight", supported = { "landscapeRight", }, }, iphone = { plist = { UIAppFonts = { "SaranaiGame-Bold.ttf" }, UIStatusBarHidden=true, }, }, android = { usesPermissions = { "com.android.vending.BILLING", }, }, }

Oh hereā€™s my build.settings

settings = { plugins = { ["CoronaProvider.ads.vungle"] = { publisherId = "com.vungle", }, ["plugin.google.play.services"] = { publisherId = "com.coronalabs", }, ["CoronaProvider.gameNetwork.apple"] = { publisherId = "com.coronalabs",supportedPlatforms = { iphone=true, ["iphone-sim"]=true },}, ["plugin.google.iap.v3"] = { publisherId = "com.coronalabs", supportedPlatforms = { android=true }}, }, orientation = { default = "landscapeRight", supported = { "landscapeRight", }, }, iphone = { plist = { UIAppFonts = { "SaranaiGame-Bold.ttf" }, UIStatusBarHidden=true, }, }, android = { usesPermissions = { "com.android.vending.BILLING", }, }, }