[Resolved] In-App Demo not working on latest build

I’m trying to use the In-App demo provided here:
http://developer.anscamobile.com/sample-code/in-app-demo

I’m using the latest Xcode 4.3.1 and Corona build 767. When I build the demo, it doesn’t work (in-app buttons do not appear like they are supposed to).

Anyone else having this problem? [import]uid: 82194 topic_id: 23459 reply_id: 323459[/import]

Just wanted to share my solution to the problem as the demo now works for me. I replaced the product ID with mine (e.g. “com.companyname.itemname”) and in iTunes Connect, I had to change the Status of my In-App Purchase Product ID from “Developer Rejected” to “Waiting For Review”. [import]uid: 82194 topic_id: 23459 reply_id: 94190[/import]

Thanks for updating this :slight_smile: [import]uid: 52491 topic_id: 23459 reply_id: 94231[/import]

I have the same problem, when run the demo i cant see the buttons.

I dont understand how test without send the app to review?..

how i send the app for reviews if i can not tested correctly?
thanks you. [import]uid: 12275 topic_id: 23459 reply_id: 96682[/import]

In iTunes Connect, did you already create a new in-app purchase? You should have a “Reference ID” and “Product ID” name for it and also the “Status” should be “Waiting for Review”. Next, in iTunes Connect click the “View Details” button for your app and you should see “In-App Purchases”. Click the EDIT button and then select the Reference ID of your in-app purchase. This will attach your in-app purchase to your app submission. The last thing is to insert your app info into your lua code. I have copied the entire In-App Template below but only changed two things. Look for this in the code:

 -- ENTER THE NAME OF YOUR "PRODUCT ID" HERE:  
 "fullversion"  

and

 validProducts[1] = {}  
 validProducts[1].title = "UNLOCK"  
 validProducts[1].description = "Do you want to unlock one Full Version for $0.99?"  
 validProducts[1].price = 0.99  
 validProducts[1].productIdentifier = "com.companyname.appname.fullversion"  
 unpackValidProducts()   

Following is the complete code for the In-App template with only those two changes I listed above. I just ran this in my simulator and it works – the button appears as it is supposed to.

  
local ui = require("ui")  
local store = require("store") -- Available in Corona build #261 or later  
  
local isSimulator = "simulator" == system.getInfo("environment")  
  
display.setStatusBar( display.HiddenStatusBar )  
  
-- Unbuffer console output for debugging   
io.output():setvbuf('no') -- Remove me for production code  
  
local titlecard  
function showTitle()  
 if isSimulator then  
 local myAlert = native.showAlert( "iTunes Store not available in Corona Simulator",   
 "Offline testing: see console for output.",   
 { "OK" } )  
 end  
 titlecard = display.newImage( "titlecard.png", true )  
 titlecard.x = display.contentCenterX  
 titlecard.y = display.contentCenterY  
end  
  
local bg  
local validProducts, invalidProducts = {}, {}  
local descriptionArea  
  
-------------------------------------------------------------------------------  
-- Product IDs should match the In App Purchase products set up in iTunes Connect.  
-- We cannot get them from the iTunes store so here they are hard coded;  
-- your app could obtain them dynamically from your server.  
-------------------------------------------------------------------------------  
local listOfProducts =   
{  
 -- These Product IDs must already be set up in your store  
 -- We'll use this list to retrieve prices etc. for each item  
 -- Note, this simple test only has room for about 4 items, please adjust accordingly  
  
 -- The iTunes store will not validate bad Product IDs   
  
 -- ENTER THE NAME OF YOUR "PRODUCT ID" HERE:  
 "fullversion"  
}  
  
-------------------------------------------------------------------------------  
-- Process and display product information obtained from store.  
-- Constructs a button for each item  
-------------------------------------------------------------------------------  
function unpackValidProducts()  
  
 -- Utility to build a buy button  
 function newBuyButton (index)  
 -- Handler for buy button   
 local buttonDefault = "buttonBuy.png"  
 local buttonOver = "buttonBuyDown.png"  
 local buyThis = function ( product )  
 print ("Ka-ching! Purchasing " ..product)  
 -- Purchase the item  
 if store.canMakePurchases then  
 store.purchase( {product} )  
 else  
 native.showAlert("Store purchases are not available, please try again later",   
 { "OK" } )  
 end  
 end  
 function buyThis\_closure ( index )   
 -- Closure wrapper for buyThis() to remember which button  
 return function ( event )  
 buyThis (validProducts[index].productIdentifier)   
 return true  
 end   
 end  
 local hideDescription = function ( )  
 descriptionArea.text = "Select a product..."  
 end  
 local describeThis = function ( description )  
 -- Display product description for testing  
 print ("About this product: " ..description)  
 -- TODO wrap if necessary  
 descriptionArea.text = description  
 timer.performWithDelay( 2000, hideDescription)   
 end  
 function describeThis\_closure ( index )   
 -- Closure wrapper for describeThis() to remember which button  
 return function ( event )  
 describeThis (validProducts[index].description)   
 return true  
 end   
 end  
 local formatted = string.format("%.2f", validProducts[index].price)  
 local label = validProducts[index].title .. " " ..formatted  
 local myButton = ui.newButton{   
 default = buttonDefault, over = buttonOver,  
 onPress = describeThis\_closure (index), onRelease = buyThis\_closure (index),  
 text = "", textColor = {2, 0, 127, 255}, font="Marker Felt", size = 14, emboss = false  
 }  
 myButton:setReferencePoint(display.CenterLeftReferencePoint)  
 myButton:setText(label)  
 return myButton  
 end  
  
 -- Utility to build a restore button  
 function newRestoreButton ()  
 local buttonDefault = "buttonRestore.png"  
 local buttonOver = "buttonRestoreDown.png"  
 local restore = function ( product )  
 -- Ask the iTunes Store to initiate restore transaction sequence  
 print ("Restoring " )  
 store.restore()  
 end  
 local hideDescription = function ( )  
 descriptionArea.text = "Select a product..."  
 end  
 local describeThis = function ()  
 -- Display info in description area  
 print ("Test restore feature")  
 descriptionArea.text = "Test restore feature"  
 timer.performWithDelay( 2000, hideDescription)   
 end  
 local label = "Test restore"  
 local myButton = ui.newButton{   
 default = buttonDefault, over = buttonOver,  
 onPress = describeThis, onRelease = restore,  
 text = "", textColor = {255, 255, 1, 255}, font="Marker Felt", size = 14, emboss = false  
 }  
 myButton:setReferencePoint(display.CenterLeftReferencePoint)  
 myButton:setText(label)   
 return myButton  
 end  
  
 print ("Loading product list")  
 if not validProducts then  
 native.showAlert( "In App features not available", "initStore() failed", { "OK" } )   
 else  
 print ("Product list loaded")  
 print( "Country: " .. system.getPreference( "locale", "country" ) )   
 -- Show store UI  
 titlecard:removeSelf()  
 bg = display.newImage( "storebg.png", true )  
 bg.x = display.contentCenterX  
 bg.y = display.contentCenterY   
 descriptionArea = native.newTextBox (10, 0.7\*display.contentHeight, display.contentCenterX - 20, display.contentCenterY - 10)  
 descriptionArea.text = "Select a product..."  
 descriptionArea:setTextColor (2, 0, 127)  
 descriptionArea.size = 18  
 descriptionArea.hasBackground = false  
 local buttonSpacing = 5  
 print( "Found " .. #validProducts .. " valid items ")  
 -- display the valid products in buttons   
 for i=1, #validProducts do   
 -- Debug: print out product info   
 print ("Item " .. i .. ": " .. validProducts[i].productIdentifier   
 .. " (" .. validProducts[i].price .. ")")  
 print (validProducts[i].title .. ", ".. validProducts[i].description)  
  
 -- create and position product button  
 local myButton = newBuyButton(i)  
 myButton.x = display.contentWidth - myButton.width - buttonSpacing  
 myButton.y = i \* buttonSpacing + (2 \* i - 1) \* myButton.height / 2  
 end  
 -- create and position Restore button  
 local myButton = newRestoreButton()  
 myButton.x = display.contentWidth - myButton.width - buttonSpacing  
 myButton.y = display.contentHeight - myButton.height / 2 - buttonSpacing  
  
 for i=1, #invalidProducts do  
 -- Debug: display the product info   
 native.showAlert( "Item " .. invalidProducts[i] .. " is invalid.",  
 { "OK" } )  
 print("Item " .. invalidProducts[i] .. " is invalid.")  
 end  
  
 end  
end  
  
-------------------------------------------------------------------------------  
-- Handler to receive product information   
-- This callback is set up by store.loadProducts()  
-------------------------------------------------------------------------------  
function loadProductsCallback( event )  
 -- Debug info for testing  
 print("In loadProductsCallback()")  
 print("event, event.name", event, event.name)  
 print(event.products)  
 print("#event.products", #event.products)  
 io.flush() -- remove for production  
  
 -- save for later use  
 validProducts = event.products  
 invalidProducts = event.invalidProducts   
 unpackValidProducts ()  
  
end  
  
-------------------------------------------------------------------------------  
-- Handler for all store transactions  
-- This callback is set up by store.init()  
-------------------------------------------------------------------------------  
function transactionCallback( event )  
 local infoString   
 print("transactionCallback: Received event ", event.name)  
--[[  
 -- Also available for your app to use:  
 print("transaction", event.transaction)  
 print("state", event.transaction.state)  
 print("errorType", event.transaction.errorType)  
 print("errorString", event.transaction.errorString)  
--]]  
-- print("testing", store.transactionStatePurchased, store.transactionErrorPaymentCancelled, store.transactionStateFailed )  
  
 if event.transaction.state == "purchased" then  
 infoString = "Transaction successful!"  
 print (infoString)  
 descriptionArea.text = infoString  
 elseif event.transaction.state == "restored" then  
 -- Reminder: your app must store this information somewhere  
 -- Here we just display some of it  
 infoString = "Restoring transaction:" ..  
 "\n Original ID: " ..event.transaction.originalTransactionIdentifier ..  
 "\n Original date: "..event.transaction.originalDate  
 print (infoString)  
 descriptionArea.text = infoString  
 print("productIdentifier", event.transaction.productIdentifier)  
 print("receipt", event.transaction.receipt)  
 print("transactionIdentifier", event.transaction.transactionIdentifier)  
 print("date", event.transaction.date)  
 print("originalReceipt", event.transaction.originalReceipt)  
  
 elseif event.transaction.state == "cancelled" then  
 infoString = "Transaction cancelled by user."  
 print (infoString)  
 descriptionArea.text = infoString  
  
 elseif event.transaction.state == "failed" then   
 infoString = "Transaction failed, type: ",   
 event.transaction.errorType, event.transaction.errorString  
 print (infoString)  
 descriptionArea.text = infoString  
 else  
 infoString = "Unknown event"  
 print (infoString)  
 descriptionArea.text = infoString  
 end  
  
 -- Tell the store we are done with the transaction.  
 -- If you are providing downloadable content, do not call this until  
 -- the download has completed.  
 store.finishTransaction( event.transaction )  
end  
  
-------------------------------------------------------------------------------  
-- Setter upper   
-------------------------------------------------------------------------------  
function setupMyStore (event)  
 store.loadProducts( listOfProducts, loadProductsCallback )  
 print ("After store.loadProducts, waiting for callback")  
  
 if isSimulator then  
 -- No Store, so no callbacks, so exercise our GUI "manually"   
 validProducts[1] = {}  
 validProducts[1].title = "UNLOCK"  
 validProducts[1].description = "Do you want to unlock one Full Version for $0.99?"  
 validProducts[1].price = 0.99  
 validProducts[1].productIdentifier = "com.companyname.appname.fullversion"  
 unpackValidProducts()   
 end  
end  
-------------------------------------------------------------------------------  
-- Main  
-------------------------------------------------------------------------------  
  
-- Show title card  
showTitle ()  
  
-- Connect to store at startup  
store.init (transactionCallback )  
print ("After init")  
  
-- Hide title card, run store  
timer.performWithDelay (1000, setupMyStore)  
  
collectgarbage()  

[import]uid: 82194 topic_id: 23459 reply_id: 96712[/import]