Google Play Store transactions repeating chaos

Hi there,

In short, it seems that anyone purchasing an in-app item form our game gets a lot more than he/she paid for :slight_smile:

I have set up products and made them appear in our game successfully, but whenever the player buys one item, it seems the function for that item gets repeated an arbitrary number of times, and then the functions for all the other items are being called.

So, for example, if I buy 100 coins, I can end up with 2550 coins and the game unlocked.
I am using the latest daily build of Corona, since the Play Store isn’t supported in the stable build.

This is my code (I am aware that the IDs of 2 of the products are very similar, the error is not related to that):
[lua]module(…, package.seeall)


– Imports

local PlayStore = require ( “store” )
local System = require ( “game.system” )
local Inventory = require ( “game.inventory” )
local Score = require ( “game.score” )


– Transaction callbacks

local function transactionCallback ( event )
local transaction = event.transaction
local id = transaction.productIdentifier
local qty = coinQty : retrieve ( “coins” ) or 0

local unlockGame = function ()
settings : store ( “gameUnlocked”, true )
settings : save ()

Director : changeScene ( “menu.title”, “crossfade” )

checkAchievement ( “thanks_for_your_support” )
end

local addCoins = function ( amount )
coinQty : store ( “coins”, qty + amount )
coinQty : save ()

checkAchievement ( “you_rock” )
end

if transaction.state == “purchased” then
System . showLoading ( false )

if id == “eas_cykdl03” then
addCoins ( 100 )

elseif id == “eas_cykdl04” then
addCoins ( 250 )

elseif id == “eas_cykdl06” then
addCoins ( 500 )

elseif id == “eas_cykldl06” then
unlockGame ()

end

native . showAlert ( “Success!”, “Your transaction was successful.”, { “OK” } )

elseif transaction.state == “cancelled” then
System . showLoading ( false )

native . showAlert ( “Cancelled”, “You cancelled the transaction.”, { “OK” } )

elseif transaction.state == “failed” then
System . showLoading ( false )

native . showAlert ( “Failed”, "Transaction failed, type: " … transaction.errorType … " - " … transaction.errorString, { “OK” } )

else
System . showLoading ( false )

native . showAlert ( “?”, “Something unexpected happened. We’re very sorry. Please try again.”, { “OK” } )

end

PlayStore . finishTransaction ( event.transaction )
end


– Init

PlayStore . init ( “google”, transactionCallback )
PlayStore . restore ()


– Purchase item

function buy ( item, table )
local isSimulator = system.getInfo ( “environment” ) == “simulator”

if isSimulator then
local func = function ()
native . showAlert ( “Win!”, “500 coins added”, { “Awesome!” }, hideIt )
Inventory . reset ()
end

timer . performWithDelay ( 2000, func )

elseif PlayStore.canMakePurchases then
System . showLoading ( true )
PlayStore . purchase ( item )

else
native . showAlert ( “Oh noes!”, “Purchases are disabled on your device, sorry :(”, { “OK” } )

end
end


– List products

function list ( displayProducts )
local productList = { {}, {}, {} }

productList[1].id = “eas_cykdl03”
productList[1].title = “100 crystals”
productList[1].descr = “Adds 100 crystals to your inventory.”

productList[2].id = “eas_cykdl04”
productList[2].title = “250 crystals”
productList[2].descr = “Adds 250 crystals to your inventory.”

productList[3].id = “eas_cykdl06”
productList[3].title = “500 crystals”
productList[3].descr = “Adds 500 crystals to your inventory.”

local isSimulator = system.getInfo ( “environment” ) == “simulator”
local http = require ( “socket.http” )
local noConnection = http.request ( “http://www.google.com” ) == nil

local loadTestProducts = function ()
local items = {}

for i, str in pairs ( productList ) do
local info = {}

info.title = “999 crystals”
info.description = “Adds 999 crystals to your inventory.”
info.localizedPrice = “DKK99.99”
info.productIdentifier = str

table . insert ( items, info )
end

displayProducts ( items )

System . showLoading ( false )
end

local loadStoreProducts = function ( event )
local items = {}

for i, p in pairs ( productList ) do
local info = {}

info.title = p.title
info.description = p.descr
info.localizedPrice = “”
info.productIdentifier = p.id

table . insert ( items, info )
end

displayProducts ( items )

System . showLoading ( false )
end

local goBack = function ()
_G.redirect = “menu.upgrades”
Director : changeScene ( “menu.redirect”, “crossfade” )
end

if noConnection then
local goBack = function ()
if _G.gameIsSender then
local w = current : retrieve ( “world” ) or 1
local l = current : retrieve ( “level” ) or 1

Director : changeScene ( “levels.world” … w … “.level” … l )
else
Director : changeScene ( “menu.upgrades”, “crossfade” )
end
end

local alert = function ()
native . showAlert ( “No network connection!”, “Please check your network connection and try again”, { “OK” }, goBack )
System . showLoading ( false )
end

timerStash.new = timer.performWithDelay ( 1000, alert )

elseif isSimulator then
timerStash.new = timer . performWithDelay ( 1000, loadTestProducts )

else
timerStash.new = timer . performWithDelay ( 1000, loadStoreProducts )
end

System . showLoading ( true )
end[/lua] [import]uid: 117153 topic_id: 27851 reply_id: 327851[/import]

My guess is that the culprit is the function call:
[lua]PlayStore . finishTransaction ( event.transaction )[/lua]
That doesn’t work right. This might be due to some administration delay by Google or some bugginess of the daily build I’m using. [import]uid: 117153 topic_id: 27851 reply_id: 112731[/import]