IAP work like a charm on Android but on iOS I can’t load the products.
Here is that part of my code.
local productIdentifiers = {
"com.mycompany.mygame.purchase",
}
local function productListener( event )
for i = 1,#event.products do
local plistener = native.showAlert( event.products[i].productIdentifier, "Οκ!", { "Back" } )
end
end
end
local function transactionListener( event )
if ( event.name == "init" ) then
store.loadProducts( productIdentifiers, productListener )
end
end
store.init( transactionListener )
The weird thing is that a few days ago this code was working!
I did my purchases / restores in Testflight!
if ( ( transaction and transaction.isError ) or event.isError ) then
native.showAlert( ":(", "This is an error", { "Got it" } )
elseif ( event.name == "init" ) then
store.loadProducts( productIdentifiers, productListener )
end
Yes, I’ve received that message with some of my apps. Don’t bother about it. You don’t need to do anything. If your code is well implemented, the IAP can be tested in the test environment.
May I ask about receipt validation.
Is it mandatory to be implemented?
Will an update be rejected if not implemented?
When a user is performing a non-consumable purchase I make it very clear that the purchase has been completed by showing on screen message and changing the purchase button to a “bought” image.
Now I got problem handling transaction states purchased and restored.
Could you please share some general code for those too?
Here is my code focused on restore purchases
-- product identifiers
local productIdentifiers = {
"com.mydomain.mygame.testiap"
}
-- product listend
local function productListener( event )
for i = 1,#event.products do
print( event.products[i].productIdentifier )
end
end
-- transaction listener
local function transactionListener( event )
if ( ( transaction and transaction.isError ) or event.isError ) then
native.showAlert( ":(", "This is an error", { "Got it" } )
elseif ( event.name == "init" ) then
store.loadProducts( productIdentifiers, productListener )
elseif ( event.name == "storeTransaction" ) then
if not ( event.transaction.state == "failed" ) then -- Successful transaction
if (event.transaction.state == "restoreCompleted") then
if event.transaction.productIdentifier == "com.mydomain.mygame.testiap" then
print("restore completed") -- this is never triggered because can't get event.transaction.productIdentifier
store.finishTransaction( "com.mydomain.mygame.testiap" )
else
print("no previously purchases") -- always triggered
end
elseif event.transaction.state == "failed" then
store.finishTransaction( "com.mydomain.mygame.testiap" )
else
store.finishTransaction( "com.mydomain.mygame.testiap" )
end
else
store.finishTransaction( "com.mydomain.mygame.testiap" )
end
end
end
-- initialization
store.init( transactionListener )
Note that when the state of a transaction is “failed” you got and error, so the condition if not ( transaction.state == "failed" then inside “init” is not necessary
Changing your code:
-- transaction listener
local function transactionListener( event )
local transaction = event.transaction
if ( ( transaction and transaction.isError ) or event.isError ) then
native.showAlert( ":(", "This is an error", { "Got it" } )
elseif ( event.name == "init" ) then
store.loadProducts( productIdentifiers, productListener )
elseif ( event.name == "storeTransaction" ) then
if transaction.state == "purchased" then
--
elseif transaction.state == "restoreCompleted" then
if transaction.productIdentifier == "com.mydomain.mygame.testiap" then
print("restore completed") -- this is never triggered because can't get event.transaction.productIdentifier
end
elseif transaction.state == "failed" then
print ( "Transaction failed" )
end
store.finishTransaction( transaction )
end
end