Add In-App-Purchases

Hello, everyone,

I’ve been have problems using the purchase functionality. 

What i want to do is:

user go to store, buy some lives, and write the lives in a file.

I already tested using test flight but doesn’t appear the popup with the product name, product price, and buy button.

Anyone knows how to implement in-app purchases? i’m trying implement for app store.

Regards,

Miguel Lima

I’m assuming you’re asking about IAP for iOS.  If I understand correctly, if someone buys an IAP through the App Store app, the first time your app runs and you initialize the store, you will get purchase transactions sent to your transaction listener. Your app would react to those purchases and you could add lives as if they made the IAP from within your app.

Rob

Yes Rob, i’m using the map badger plugin, and works okay one the corona simulator and xcode simulator, but when i try using testflight , when i click in the product i want to purchase, request for user enter the password but doesn’t do nothing more .

Rob can you tell me what is wrong?

local composer = require( “composer” )

local scene = composer.newScene()


– Code outside of the scene event functions below will only be executed ONCE unless

– the scene is removed entirely (not recycled) via “composer.removeScene()”


local function goToMenu()

  local options = {

    effect = “slideRight”,

    time = 500

  }

  composer.gotoScene( “menu”, options)

end

– Initialize variables

local json = require( “json” )

local settings = {}

local filePath = system.pathForFile( “fastFingerSettings100.json”, system.DocumentsDirectory )

---------------------Store Settings------------------------

local store

local targetAppStore = system.getInfo( “targetAppStore” )

if ( “apple” == targetAppStore ) then  – iOS

    store = require( “store” )

elseif ( “google” == targetAppStore ) then  – Android

    store = require( “plugin.google.iap.v3” )

elseif ( “amazon” == targetAppStore ) then  – Amazon

    store = require( “plugin.amazon.iap” )

else

    print( “In-app purchases are not available for this platform.” )

end

local function transactionListener( event )

    local transaction = event.transaction

    if ( transaction.isError ) then

        print( transaction.errorType )

        print( transaction.errorString )

    else

        – No errors; proceed

    end

end

– Initialize store

store.init( transactionListener )

local productIdentifiers = {

    “5lives”,

    “30lives”,

    “100lives”,

    “noAdsPlus100Lives”,

}

local function productListener( event )

    for i = 1,#event.products do

        print( event.products[i].productIdentifier )

    end

end

– Load store products; store must be properly initialized by this point!

store.loadProducts( productIdentifiers, productListener )

local function transactionListener( event )

    local transaction = event.transaction

    if ( transaction.isError ) then

        print( transaction.errorType )

        print( transaction.errorString )

    else

        – No errors; proceed

        if ( transaction.state == “purchased” or transaction.state == “restored” ) then

            – Handle a normal purchase or restored purchase here

            print( transaction.state )

            print( transaction.productIdentifier )

            print( transaction.date )

            local storeAddLives = composer.getVariable(“lives”)

            table.remove(settings,3)

            table.insert( settings, 3, storeAddLives )

            saveLives()

        elseif ( transaction.state == “cancelled” ) then

            – Handle a cancelled transaction here

        elseif ( transaction.state == “failed” ) then

            – Handle a failed transaction here

        end

        – Tell the store that the transaction is complete

        – If you’re providing downloadable content, do not call this until the download has completed

        store.finishTransaction( transaction )

    end

end

– Initialize store

store.init( transactionListener )


---------------------Load lives------------------------

local function loadLives()

    local file = io.open( filePath, “r” )

    if file then

        file:seek(“set”, 0)

        local contents = file:read( “*l” )

        io.close( file )

        settings = json.decode( contents )

    end

    if ( settings == nil or #settings == 0 ) then

        settings = { 0, 0 , 0,1}

    end

end


---------------------_Save Lives--------------------------

local function saveLives()

    for i = #settings, 5, -1 do

        table.remove( settings, i )

    end

    local file = io.open( filePath, “w” )

    if file then

        file:write( json.encode( settings ) )

        io.close( file )

    end

end


– Scene event functions


– create()

function scene:create( event )

    local shopGroup = self.view

    – Code here runs when the scene is first created but has not yet appeared on screen

    local setaBackward = display.newImage( “setaBackward.png”)

    setaBackward.x = display.contentWidth*0.15

    setaBackward.y = display.contentHeight*0+40

    setaBackward:addEventListener(“tap”, goToMenu)

    logoText = display.newText( “Store”, 150, 80, “FFFFORWA.TTF”, 24 )

    logoText.x = display.contentWidth*0.5

    logoText.y = display.contentHeight*0+40

    logoText:setFillColor( 1,0.843137,0 )

    local hLine = display.newLine( -20, 0, display.contentWidth*1, 0 )

    hLine:setStrokeColor( 0.411765, 0.411765 ,0.411765 )

    hLine.strokeWidth = 4

    hLine.x = display.contentWidth*0

    hLine.y = logoText.y+30

    product1Text = display.newText( “x5”, 150, 80, “FFFFORWA.TTF”, 15 )

    product1Text.x = display.contentWidth*0.35

    product1Text.y = display.contentHeight*0.25

    product1TextH = display.newText( “:heart:”, 150, 80, “FFFFORWA.TTF”, 25 )

    product1TextH.x = product1Text.x+25

    product1TextH.y = product1Text.y-5

    product1TextH:setFillColor( 1,0,0 )

    product1TextP = display.newText( “0.99$”, 150, 80, “FFFFORWA.TTF”, 15 )

    product1TextP.x = product1Text.x+100

    product1TextP.y = product1Text.y

    product1TextP:setFillColor( 1,0.843137,0 )

    local hLine1 = display.newLine( -20, 0, display.contentWidth*1, 0 )

    hLine1:setStrokeColor( 0.411765, 0.411765 ,0.411765 )

    hLine1.strokeWidth = 2

    hLine1.x = display.contentWidth*0

    hLine1.y = product1TextP.y+40

    local product1Rectangle = display.newRect( 0, 0, display.contentWidth*10, 60 )

    product1Rectangle:setFillColor( 0.5 )

    product1Rectangle.x = display.contentWidth*0

    product1Rectangle.y = product1Text.y

    product1Rectangle.alpha = 0.01

    product1Rectangle.id = 1

    --Product 2

    product2Text = display.newText( “x30”, 150, 80, “FFFFORWA.TTF”, 15 )

    product2Text.x = product1Text.x-10

    product2Text.y = product1Text.y+80

    product2TextH = display.newText( “:heart:”, 150, 80, “FFFFORWA.TTF”, 25 )

    product2TextH.x = product1TextH.x

    product2TextH.y = product2Text.y-5

    product2TextH:setFillColor( 1,0,0 )

    product2TextP = display.newText( “2.99$”, 150, 80, “FFFFORWA.TTF”, 15 )

    product2TextP.x = product1TextP.x

    product2TextP.y = product2Text.y

    product2TextP:setFillColor( 1,0.843137,0 )

    local hLine2 = display.newLine( -20, 0, display.contentWidth*1, 0 )

    hLine2:setStrokeColor( 0.411765, 0.411765 ,0.411765 )

    hLine2.strokeWidth = 2

    hLine2.x = display.contentWidth*0

    hLine2.y = product2TextP.y+40

    local product2Rectangle = display.newRect( 0, 0, display.contentWidth*10, 60 )

    product2Rectangle:setFillColor( 0.5 )

    product2Rectangle.x = display.contentWidth*0

    product2Rectangle.y = product2Text.y

    product2Rectangle.alpha = 0.01

    product2Rectangle.id = 2

    --Product 3

    product3Text = display.newText( “x100”, 150, 80, “FFFFORWA.TTF”, 15 )

    product3Text.x = product1Text.x-10

    product3Text.y = product1Text.y+160

    product3TextH = display.newText( “:heart:”, 150, 80, “FFFFORWA.TTF”, 25 )

    product3TextH.x = product1TextH.x

    product3TextH.y = product3Text.y-5

    product3TextH:setFillColor( 1,0,0 )

    product3TextP = display.newText( “5.99$”, 150, 80, “FFFFORWA.TTF”, 15 )

    product3TextP.x = product1TextP.x

    product3TextP.y = product3Text.y

    product3TextP:setFillColor( 1,0.843137,0 )

    local hLine3 = display.newLine( -20, 0, display.contentWidth*1, 0 )

    hLine3:setStrokeColor( 0.411765, 0.411765 ,0.411765 )

    hLine3.strokeWidth = 2

    hLine3.x = display.contentWidth*0

    hLine3.y = product3TextP.y+40

    local product3Rectangle = display.newRect( 0, 0, display.contentWidth*10, 60 )

    product3Rectangle:setFillColor( 0.5 )

    product3Rectangle.x = display.contentWidth*0

    product3Rectangle.y = product3Text.y

    product3Rectangle.alpha = 0.01

    product3Rectangle.id = 3

    --Product 4

    --local product4 = display.newImage( “noAds.png”)

    --product4.x = product1Text.x-80

    --product4.y = product1Text.y+240

    product4Text = display.newText( “x400”, 150, 80, “FFFFORWA.TTF”, 15 )

    product4Text.x = product1Text.x-20

    product4Text.y = product1Text.y+240

    product4TextH = display.newText( “:heart:”, 150, 80, “FFFFORWA.TTF”, 25 )

    product4TextH.x = product1TextH.x

    product4TextH.y = product4Text.y-5

    product4TextH:setFillColor( 1,0,0 )

    product4TextP = display.newText( “5.99$”, 150, 80, “FFFFORWA.TTF”, 15 )

    product4TextP.x = product1TextP.x

    product4TextP.y = product4Text.y

    product4TextP:setFillColor( 1,0.843137,0 )

    local hLine4 = display.newLine( -20, 0, display.contentWidth*1, 0 )

    hLine4:setStrokeColor( 0.411765, 0.411765 ,0.411765 )

    hLine4.strokeWidth = 2

    hLine4.x = display.contentWidth*0

    hLine4.y = product4TextP.y+40

    local product4Rectangle = display.newRect( 0, 0, display.contentWidth*10, 60 )

    product4Rectangle:setFillColor( 0.5 )

    product4Rectangle.x = display.contentWidth*0

    product4Rectangle.y = product4Text.y

    product4Rectangle.alpha = 0.01

    product4Rectangle.id = 4

        function apertou(event)

          print("Apertou "…event.target.id)

          loadLives()

          local totalLives = settings[3]

          print(totalLives)

          local updateLives

          print(totalLives)

            if(event.target.id==1)

              then

                updateLives =  totalLives + 5

                local i = 1

                store.purchase( {“event.products[1].productIdentifier”})

            elseif(event.target.id==2)

              then

                updateLives = totalLives + 30

                store.purchase( {“event.products[2].productIdentifier”})

            elseif(event.target.id==3)

              then

              updateLives = totalLives + 100

              store.purchase( {“event.products[3].productIdentifier”})

            elseif(event.target.id==4)

              then

                updateLives = totalLives + 400

                store.purchase(  {“event.products[4].productIdentifier”})

              end

          composer.setVariable(“lives”,updateLives)

        end

        product1Rectangle:addEventListener(“tap”, apertou)

        product2Rectangle:addEventListener(“tap”, apertou)

        product3Rectangle:addEventListener(“tap”, apertou)

        product4Rectangle:addEventListener(“tap”, apertou)

    shopGroup:insert(logoText)

    shopGroup:insert(setaBackward)

    shopGroup:insert(hLine)

    --shopGroup:insert(product4)

    shopGroup:insert(product1Text)

    shopGroup:insert(product1TextH)

    shopGroup:insert(product1TextP)

    shopGroup:insert(hLine1)

    shopGroup:insert(product1Rectangle)

    shopGroup:insert(product2Text)

    shopGroup:insert(product2TextH)

    shopGroup:insert(product2TextP)

    shopGroup:insert(hLine2)

    shopGroup:insert(product2Rectangle)

    shopGroup:insert(product3Text)

    shopGroup:insert(product3TextH)

    shopGroup:insert(product3TextP)

    shopGroup:insert(hLine3)

    shopGroup:insert(product3Rectangle)

    shopGroup:insert(product4Text)

    shopGroup:insert(product4TextH)

    shopGroup:insert(product4TextP)

    shopGroup:insert(hLine4)

    shopGroup:insert(product4Rectangle)

end

– show()

function scene:show( event )

    local shopGroup = self.view

    local phase = event.phase

    if ( phase == “will” ) then

        – Code here runs when the scene is still off screen (but is about to come on screen)

    elseif ( phase == “did” ) then

        – Code here runs when the scene is entirely on screen

    end

end

– hide()

function scene:hide( event )

    local shopGroup = self.view

    local phase = event.phase

    if ( phase == “will” ) then

        – Code here runs when the scene is on screen (but is about to go off screen)

    elseif ( phase == “did” ) then

        – Code here runs immediately after the scene goes entirely off screen

    end

end

– destroy()

function scene:destroy( event )

    local shopGroup = self.view

    – Code here runs prior to the removal of scene’s view

end


– Scene event function listeners


scene:addEventListener( “create”, scene )

scene:addEventListener( “show”, scene )

scene:addEventListener( “hide”, scene )

scene:addEventListener( “destroy”, scene )


return scene

First and foremost, you should always post code to the forums using code formatting. The easiest way to do this is to use the blue <> button in the row with Bold and Italic. Then paste your code into the popup window. Your code when not formatted is very hard to read.

Secondly, this isn’t a problem, but it causes confusion, is you have two transaction listener functions.

Third, you’re granting additional lives before the purchase is made. I would defer this action until you get a “purchased” transaction, determine what was purchased then grant the lives.

Your saveLives function is defined local but defined after you use it the first time. This could be a problem. Please move that function above your transaction processing function.

Finally, you should be printing out more information to determine what is going on:

local function transactionListener( event ) &nbsp; &nbsp; local transaction = event.transaction print("transaction.state", transaction.state) &nbsp; &nbsp; if ( transaction.isError ) then &nbsp; &nbsp; &nbsp; &nbsp; print( transaction.errorType ) &nbsp; &nbsp; &nbsp; &nbsp; print( transaction.errorString ) &nbsp; &nbsp; else &nbsp; &nbsp; &nbsp; &nbsp; -- No errors; proceed &nbsp; &nbsp; &nbsp; &nbsp; if ( transaction.state == "purchased" or transaction.state == "restored" ) then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -- Handle a normal purchase or restored purchase here &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print( transaction.state ) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print( transaction.productIdentifier ) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print( transaction.date ) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; local storeAddLives = composer.getVariable("lives") &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; table.remove(settings,3) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; table.insert( settings, 3, storeAddLives ) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; saveLives() &nbsp; &nbsp; &nbsp; &nbsp; elseif ( transaction.state == "cancelled" ) then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -- Handle a cancelled transaction here &nbsp; &nbsp; &nbsp; &nbsp; elseif ( transaction.state == "failed" ) then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -- Handle a failed transaction here &nbsp; &nbsp; &nbsp; &nbsp; end &nbsp; &nbsp; &nbsp; &nbsp; -- Tell the store that the transaction is complete &nbsp; &nbsp; &nbsp; &nbsp; -- If you're providing downloadable content, do not call this until the download has completed &nbsp; &nbsp; &nbsp; &nbsp; store.finishTransaction( transaction ) &nbsp; &nbsp; end end

Rob

I’m assuming you’re asking about IAP for iOS.  If I understand correctly, if someone buys an IAP through the App Store app, the first time your app runs and you initialize the store, you will get purchase transactions sent to your transaction listener. Your app would react to those purchases and you could add lives as if they made the IAP from within your app.

Rob

Yes Rob, i’m using the map badger plugin, and works okay one the corona simulator and xcode simulator, but when i try using testflight , when i click in the product i want to purchase, request for user enter the password but doesn’t do nothing more .

Rob can you tell me what is wrong?

local composer = require( “composer” )

local scene = composer.newScene()


– Code outside of the scene event functions below will only be executed ONCE unless

– the scene is removed entirely (not recycled) via “composer.removeScene()”


local function goToMenu()

  local options = {

    effect = “slideRight”,

    time = 500

  }

  composer.gotoScene( “menu”, options)

end

– Initialize variables

local json = require( “json” )

local settings = {}

local filePath = system.pathForFile( “fastFingerSettings100.json”, system.DocumentsDirectory )

---------------------Store Settings------------------------

local store

local targetAppStore = system.getInfo( “targetAppStore” )

if ( “apple” == targetAppStore ) then  – iOS

    store = require( “store” )

elseif ( “google” == targetAppStore ) then  – Android

    store = require( “plugin.google.iap.v3” )

elseif ( “amazon” == targetAppStore ) then  – Amazon

    store = require( “plugin.amazon.iap” )

else

    print( “In-app purchases are not available for this platform.” )

end

local function transactionListener( event )

    local transaction = event.transaction

    if ( transaction.isError ) then

        print( transaction.errorType )

        print( transaction.errorString )

    else

        – No errors; proceed

    end

end

– Initialize store

store.init( transactionListener )

local productIdentifiers = {

    “5lives”,

    “30lives”,

    “100lives”,

    “noAdsPlus100Lives”,

}

local function productListener( event )

    for i = 1,#event.products do

        print( event.products[i].productIdentifier )

    end

end

– Load store products; store must be properly initialized by this point!

store.loadProducts( productIdentifiers, productListener )

local function transactionListener( event )

    local transaction = event.transaction

    if ( transaction.isError ) then

        print( transaction.errorType )

        print( transaction.errorString )

    else

        – No errors; proceed

        if ( transaction.state == “purchased” or transaction.state == “restored” ) then

            – Handle a normal purchase or restored purchase here

            print( transaction.state )

            print( transaction.productIdentifier )

            print( transaction.date )

            local storeAddLives = composer.getVariable(“lives”)

            table.remove(settings,3)

            table.insert( settings, 3, storeAddLives )

            saveLives()

        elseif ( transaction.state == “cancelled” ) then

            – Handle a cancelled transaction here

        elseif ( transaction.state == “failed” ) then

            – Handle a failed transaction here

        end

        – Tell the store that the transaction is complete

        – If you’re providing downloadable content, do not call this until the download has completed

        store.finishTransaction( transaction )

    end

end

– Initialize store

store.init( transactionListener )


---------------------Load lives------------------------

local function loadLives()

    local file = io.open( filePath, “r” )

    if file then

        file:seek(“set”, 0)

        local contents = file:read( “*l” )

        io.close( file )

        settings = json.decode( contents )

    end

    if ( settings == nil or #settings == 0 ) then

        settings = { 0, 0 , 0,1}

    end

end


---------------------_Save Lives--------------------------

local function saveLives()

    for i = #settings, 5, -1 do

        table.remove( settings, i )

    end

    local file = io.open( filePath, “w” )

    if file then

        file:write( json.encode( settings ) )

        io.close( file )

    end

end


– Scene event functions


– create()

function scene:create( event )

    local shopGroup = self.view

    – Code here runs when the scene is first created but has not yet appeared on screen

    local setaBackward = display.newImage( “setaBackward.png”)

    setaBackward.x = display.contentWidth*0.15

    setaBackward.y = display.contentHeight*0+40

    setaBackward:addEventListener(“tap”, goToMenu)

    logoText = display.newText( “Store”, 150, 80, “FFFFORWA.TTF”, 24 )

    logoText.x = display.contentWidth*0.5

    logoText.y = display.contentHeight*0+40

    logoText:setFillColor( 1,0.843137,0 )

    local hLine = display.newLine( -20, 0, display.contentWidth*1, 0 )

    hLine:setStrokeColor( 0.411765, 0.411765 ,0.411765 )

    hLine.strokeWidth = 4

    hLine.x = display.contentWidth*0

    hLine.y = logoText.y+30

    product1Text = display.newText( “x5”, 150, 80, “FFFFORWA.TTF”, 15 )

    product1Text.x = display.contentWidth*0.35

    product1Text.y = display.contentHeight*0.25

    product1TextH = display.newText( “:heart:”, 150, 80, “FFFFORWA.TTF”, 25 )

    product1TextH.x = product1Text.x+25

    product1TextH.y = product1Text.y-5

    product1TextH:setFillColor( 1,0,0 )

    product1TextP = display.newText( “0.99$”, 150, 80, “FFFFORWA.TTF”, 15 )

    product1TextP.x = product1Text.x+100

    product1TextP.y = product1Text.y

    product1TextP:setFillColor( 1,0.843137,0 )

    local hLine1 = display.newLine( -20, 0, display.contentWidth*1, 0 )

    hLine1:setStrokeColor( 0.411765, 0.411765 ,0.411765 )

    hLine1.strokeWidth = 2

    hLine1.x = display.contentWidth*0

    hLine1.y = product1TextP.y+40

    local product1Rectangle = display.newRect( 0, 0, display.contentWidth*10, 60 )

    product1Rectangle:setFillColor( 0.5 )

    product1Rectangle.x = display.contentWidth*0

    product1Rectangle.y = product1Text.y

    product1Rectangle.alpha = 0.01

    product1Rectangle.id = 1

    --Product 2

    product2Text = display.newText( “x30”, 150, 80, “FFFFORWA.TTF”, 15 )

    product2Text.x = product1Text.x-10

    product2Text.y = product1Text.y+80

    product2TextH = display.newText( “:heart:”, 150, 80, “FFFFORWA.TTF”, 25 )

    product2TextH.x = product1TextH.x

    product2TextH.y = product2Text.y-5

    product2TextH:setFillColor( 1,0,0 )

    product2TextP = display.newText( “2.99$”, 150, 80, “FFFFORWA.TTF”, 15 )

    product2TextP.x = product1TextP.x

    product2TextP.y = product2Text.y

    product2TextP:setFillColor( 1,0.843137,0 )

    local hLine2 = display.newLine( -20, 0, display.contentWidth*1, 0 )

    hLine2:setStrokeColor( 0.411765, 0.411765 ,0.411765 )

    hLine2.strokeWidth = 2

    hLine2.x = display.contentWidth*0

    hLine2.y = product2TextP.y+40

    local product2Rectangle = display.newRect( 0, 0, display.contentWidth*10, 60 )

    product2Rectangle:setFillColor( 0.5 )

    product2Rectangle.x = display.contentWidth*0

    product2Rectangle.y = product2Text.y

    product2Rectangle.alpha = 0.01

    product2Rectangle.id = 2

    --Product 3

    product3Text = display.newText( “x100”, 150, 80, “FFFFORWA.TTF”, 15 )

    product3Text.x = product1Text.x-10

    product3Text.y = product1Text.y+160

    product3TextH = display.newText( “:heart:”, 150, 80, “FFFFORWA.TTF”, 25 )

    product3TextH.x = product1TextH.x

    product3TextH.y = product3Text.y-5

    product3TextH:setFillColor( 1,0,0 )

    product3TextP = display.newText( “5.99$”, 150, 80, “FFFFORWA.TTF”, 15 )

    product3TextP.x = product1TextP.x

    product3TextP.y = product3Text.y

    product3TextP:setFillColor( 1,0.843137,0 )

    local hLine3 = display.newLine( -20, 0, display.contentWidth*1, 0 )

    hLine3:setStrokeColor( 0.411765, 0.411765 ,0.411765 )

    hLine3.strokeWidth = 2

    hLine3.x = display.contentWidth*0

    hLine3.y = product3TextP.y+40

    local product3Rectangle = display.newRect( 0, 0, display.contentWidth*10, 60 )

    product3Rectangle:setFillColor( 0.5 )

    product3Rectangle.x = display.contentWidth*0

    product3Rectangle.y = product3Text.y

    product3Rectangle.alpha = 0.01

    product3Rectangle.id = 3

    --Product 4

    --local product4 = display.newImage( “noAds.png”)

    --product4.x = product1Text.x-80

    --product4.y = product1Text.y+240

    product4Text = display.newText( “x400”, 150, 80, “FFFFORWA.TTF”, 15 )

    product4Text.x = product1Text.x-20

    product4Text.y = product1Text.y+240

    product4TextH = display.newText( “:heart:”, 150, 80, “FFFFORWA.TTF”, 25 )

    product4TextH.x = product1TextH.x

    product4TextH.y = product4Text.y-5

    product4TextH:setFillColor( 1,0,0 )

    product4TextP = display.newText( “5.99$”, 150, 80, “FFFFORWA.TTF”, 15 )

    product4TextP.x = product1TextP.x

    product4TextP.y = product4Text.y

    product4TextP:setFillColor( 1,0.843137,0 )

    local hLine4 = display.newLine( -20, 0, display.contentWidth*1, 0 )

    hLine4:setStrokeColor( 0.411765, 0.411765 ,0.411765 )

    hLine4.strokeWidth = 2

    hLine4.x = display.contentWidth*0

    hLine4.y = product4TextP.y+40

    local product4Rectangle = display.newRect( 0, 0, display.contentWidth*10, 60 )

    product4Rectangle:setFillColor( 0.5 )

    product4Rectangle.x = display.contentWidth*0

    product4Rectangle.y = product4Text.y

    product4Rectangle.alpha = 0.01

    product4Rectangle.id = 4

        function apertou(event)

          print("Apertou "…event.target.id)

          loadLives()

          local totalLives = settings[3]

          print(totalLives)

          local updateLives

          print(totalLives)

            if(event.target.id==1)

              then

                updateLives =  totalLives + 5

                local i = 1

                store.purchase( {“event.products[1].productIdentifier”})

            elseif(event.target.id==2)

              then

                updateLives = totalLives + 30

                store.purchase( {“event.products[2].productIdentifier”})

            elseif(event.target.id==3)

              then

              updateLives = totalLives + 100

              store.purchase( {“event.products[3].productIdentifier”})

            elseif(event.target.id==4)

              then

                updateLives = totalLives + 400

                store.purchase(  {“event.products[4].productIdentifier”})

              end

          composer.setVariable(“lives”,updateLives)

        end

        product1Rectangle:addEventListener(“tap”, apertou)

        product2Rectangle:addEventListener(“tap”, apertou)

        product3Rectangle:addEventListener(“tap”, apertou)

        product4Rectangle:addEventListener(“tap”, apertou)

    shopGroup:insert(logoText)

    shopGroup:insert(setaBackward)

    shopGroup:insert(hLine)

    --shopGroup:insert(product4)

    shopGroup:insert(product1Text)

    shopGroup:insert(product1TextH)

    shopGroup:insert(product1TextP)

    shopGroup:insert(hLine1)

    shopGroup:insert(product1Rectangle)

    shopGroup:insert(product2Text)

    shopGroup:insert(product2TextH)

    shopGroup:insert(product2TextP)

    shopGroup:insert(hLine2)

    shopGroup:insert(product2Rectangle)

    shopGroup:insert(product3Text)

    shopGroup:insert(product3TextH)

    shopGroup:insert(product3TextP)

    shopGroup:insert(hLine3)

    shopGroup:insert(product3Rectangle)

    shopGroup:insert(product4Text)

    shopGroup:insert(product4TextH)

    shopGroup:insert(product4TextP)

    shopGroup:insert(hLine4)

    shopGroup:insert(product4Rectangle)

end

– show()

function scene:show( event )

    local shopGroup = self.view

    local phase = event.phase

    if ( phase == “will” ) then

        – Code here runs when the scene is still off screen (but is about to come on screen)

    elseif ( phase == “did” ) then

        – Code here runs when the scene is entirely on screen

    end

end

– hide()

function scene:hide( event )

    local shopGroup = self.view

    local phase = event.phase

    if ( phase == “will” ) then

        – Code here runs when the scene is on screen (but is about to go off screen)

    elseif ( phase == “did” ) then

        – Code here runs immediately after the scene goes entirely off screen

    end

end

– destroy()

function scene:destroy( event )

    local shopGroup = self.view

    – Code here runs prior to the removal of scene’s view

end


– Scene event function listeners


scene:addEventListener( “create”, scene )

scene:addEventListener( “show”, scene )

scene:addEventListener( “hide”, scene )

scene:addEventListener( “destroy”, scene )


return scene

First and foremost, you should always post code to the forums using code formatting. The easiest way to do this is to use the blue <> button in the row with Bold and Italic. Then paste your code into the popup window. Your code when not formatted is very hard to read.

Secondly, this isn’t a problem, but it causes confusion, is you have two transaction listener functions.

Third, you’re granting additional lives before the purchase is made. I would defer this action until you get a “purchased” transaction, determine what was purchased then grant the lives.

Your saveLives function is defined local but defined after you use it the first time. This could be a problem. Please move that function above your transaction processing function.

Finally, you should be printing out more information to determine what is going on:

local function transactionListener( event ) &nbsp; &nbsp; local transaction = event.transaction print("transaction.state", transaction.state) &nbsp; &nbsp; if ( transaction.isError ) then &nbsp; &nbsp; &nbsp; &nbsp; print( transaction.errorType ) &nbsp; &nbsp; &nbsp; &nbsp; print( transaction.errorString ) &nbsp; &nbsp; else &nbsp; &nbsp; &nbsp; &nbsp; -- No errors; proceed &nbsp; &nbsp; &nbsp; &nbsp; if ( transaction.state == "purchased" or transaction.state == "restored" ) then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -- Handle a normal purchase or restored purchase here &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print( transaction.state ) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print( transaction.productIdentifier ) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print( transaction.date ) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; local storeAddLives = composer.getVariable("lives") &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; table.remove(settings,3) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; table.insert( settings, 3, storeAddLives ) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; saveLives() &nbsp; &nbsp; &nbsp; &nbsp; elseif ( transaction.state == "cancelled" ) then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -- Handle a cancelled transaction here &nbsp; &nbsp; &nbsp; &nbsp; elseif ( transaction.state == "failed" ) then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -- Handle a failed transaction here &nbsp; &nbsp; &nbsp; &nbsp; end &nbsp; &nbsp; &nbsp; &nbsp; -- Tell the store that the transaction is complete &nbsp; &nbsp; &nbsp; &nbsp; -- If you're providing downloadable content, do not call this until the download has completed &nbsp; &nbsp; &nbsp; &nbsp; store.finishTransaction( transaction ) &nbsp; &nbsp; end end

Rob