licensing verify problem...

It looks like my call:

licensing.verify (t)

is not getting anything back from the listener. What can cause NOTHING getting back from the listener… no event?

Hi @d.mach,

Can you show more of your code? I assume you followed all of the required steps to get licensing working?

Brent

if system.getInfo("platformName") == "Android" then     licensing = require "licensing"     provider = "google"     storeX = require("store")     -- Initializes the licensing module for this particular provider.     t = {}     function t:licensing( event )       --Prints the name of this event, "licensing".       response.text = (event.isError)       --Prints the name of the provider for this licensing instance, "google"       print(event.provider)       --Prints true if it has been verified else it prints false.       print(event.isVerified)       --Prints true if there was an error during verification else it will return nil.  Errors can be anything from configuration errors to network errors.       print(event.isError)       --Prints the type of error, "configuration" or "network".  If there was no error then this will return nil.       print(event.errorType)       --Prints a translated response from the licensing server.       print(event.response)       --Prints the expiration time of the expiration time of the cached license.       print(event.expiration)       local verifiedText = "NOT verified :("       if event.isVerified then         verifiedText = "Verified! :)"         -- important: we need a timer which is starting the game in case the licensing listener is NOT starting the game         -- important: we need a timer which is starting the game in case the licensing listener is NOT starting the game         if \_G.licenseStartTimer then             timer.cancel(\_G.licenseStartTimer)             \_G.licenseStartTimer=nil         end         timer.performWithDelay(200,startGameNow,1)       else         local onComplete=function(event)             -- Handler that gets notified when the alert closes             if ( event.action == "clicked" ) then                 -- leave game now                 --native.requestExit()-- not supported on iOS                 print ("Licensing ERROR!")                 if \_G.analyticsallowed==true then                     analytics.logEvent( "A Player started a PIRATED VERSION and now is getting to the Google Play Store!")                 end                 system.openURL( \_G.CC\_GameStoreLink )                 if \_G.licenseStartTimer then                     timer.cancel(\_G.licenseStartTimer)                     \_G.licenseStartTimer=nil                 end                 timer.performWithDelay(200,startGameNow,1)             end          end         -- quit the app here now because the app was NOT loaded via Google Play!         native.showAlert("Licensing ERROR!", "Info...",{ "YES" },onComplete)       end       response.text = verifiedText     end     if storeX.target == provider then        licensing.init( provider )     else         if \_G.licenseStartTimer then             timer.cancel(\_G.licenseStartTimer)             \_G.licenseStartTimer=nil         end         timer.performWithDelay(200,startGameNow,1)     end     -- If the target store isn't for this provider then the verify will not call the listener.     if storeX.target == provider then        licensing.verify(t)        response.text="verify"     else         if \_G.licenseStartTimer then             timer.cancel(\_G.licenseStartTimer)             \_G.licenseStartTimer=nil         end         timer.performWithDelay(200,startGameNow,1)     end end

I can get to the licensing.verify(t) but don’t get any feedback from the listener after that.

Am I seeing usage of iOS IAP (require “store”) in this Google-based implementation?

Yes… but this is working regarding the provider and storeX.target is giving back “google” here… so shouldn’t it call the listener then? I tried it with the google store implementation also with the same non-responding result.

And you did all of the other proper licensing setup in config.lua and so forth?

Yes. I have checked it more than once.
The only thing this game is doing differently is I’m using some “if’s” in config.lua to get the correct screen size, because it’s a pixel retro game. This is done like the following code (only showing a part of the config.lua to give the idea):

... if displayHeight\<=480 then &nbsp; application = { &nbsp;&nbsp;&nbsp;&nbsp; content = { &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- correct one for portrait: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; width = math.floor(display.pixelWidth/(pix)), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; height = math.floor(display.pixelHeight/(pix)), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --width = math.floor(display.pixelHeight/pix), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --height = math.floor(display.pixelWidth/pix), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --width = math.floor(320/pix), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --height = math.floor(480/pix), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --print ("aspectRatio is "..aspectRatio) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --width = 160 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --height = 240 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scale = "letterBox", &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; antialiasing=true, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fps = 60, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; license = &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; google = &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; key = "CORRECT KEY HERE!!!", &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --policy = "this is optional", &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; policy = "serverManaged", &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }, &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print ("license 1") elseif displayHeight\>480 and displayHeight\<=640 then &nbsp; application = { &nbsp;&nbsp;&nbsp;&nbsp; content = { ...

Am I seeing that you try to verify the license in the same block (runtime step) as you init it? That’s probably not advisable… I’d make 100% sure that it’s initialized before you try to verify.

Also, I suggest you use “system.getInfo( ‘targetAppStore’ )” instead of “store.target” to get the target app store you’re building for, in this case “google”.

https://docs.coronalabs.com/api/library/system/getInfo.html#targetappstore

Take care,

Brent

Thx for your help Brent. One question:

How can you make sure 100% that the init has worked before calling the verify?

Great question! The “licensing.init()” call will return true or false based on its success:

https://docs.coronalabs.com/api/library/licensing/init.html

Also make sure you added the CHECK_LICENSE permission for Android as noted on that page.

Take care,

Brent

Permission is already added.

When checking if the “licensing.init()” is true (or false)… does this mean I have to check (call) “licensing.init()” more than once?

With a timer maybe checking for true… like this:

timer.performWithDelay(1000,function() if licensing.init(“google”) then stopcheckandstartgame() end,0)

I suppose you could, but I’m not sure you’ll need to. If licensing dictates if the player can or can’t continue, then init() it and check for a “true” response. If it’s true, verify() the license, and if it succeeds, continue. Otherwise, you know something went wrong (bad license or some other issue in the licensing setup on Google’s side) and there’s probably no reason to continue.

One more thing:

Can this be tested with a previous .apk file version in the store, using another .apk with DEBUG build on device… or does the version be exact the same on device compared to the one in the store?

It looks like the init is not giving back true when I’m checking for it.

I’m not an expert on licensing, but I would imagine version numbers need to match. Google is likely very specific about these types of things. Hopefully somebody with time-tested expertise with Google licensing can chime in on this thread.

Dear,

I’m having the same problem. When I call the init () method it always returns false and looking in the debugg pops up a warning message saying it was rejected by google. The more interesting that I have an active product and the same opens perfectly for purchase, only validation of the license that does not work, I say this because the product buying part uses the same license code of the application and the version you are Using it must always be the same published in the google play store, that is to say, it is all just the licensing API. * That is not fucnionando.

Can you check if this API is working, can you test it? I’m talking about this because recently google made some changes to these license validations and I’m not sure if this could have affected the corona API.

Att.,

Joéver

Hi @joeversh,

We’ll check into this to see if something has changed drastically on Google’s side…

Thanks,

Brent

Hi Brent,

More information about the debug I made.

--------- beginning of system

--------- beginning of main

V/Corona  ( 9168): > Class.forName: network.LuaLoader

V/Corona  ( 9168): < Class.forName: network.LuaLoader

V/Corona  ( 9168): Loading via reflection: network.LuaLoader

I/Corona  ( 9168): Platform: LG-D805 / ARM Neon / 5.0.2 / Adreno ™ 330 / OpenGL ES 3.0 V@84.0 AU@05.00.02.042.013 (CL@) / 2017.3068 / portugu├¬s | BR | pt_BR | pt

V/Corona  ( 9168): > Class.forName: shared.google.play.services.base.LuaLoader

V/Corona  ( 9168): < Class.forName: shared.google.play.services.base.LuaLoader

V/Corona  ( 9168): Loading via reflection: shared.google.play.services.base.LuaLoader

V/Corona  ( 9168): > Class.forName: CoronaProvider.licensing.google.LuaLoader

V/Corona  ( 9168): < Class.forName: CoronaProvider.licensing.google.LuaLoader

V/Corona  ( 9168): Loading via reflection: CoronaProvider.licensing.google.LuaLoader

V/Corona  ( 9168): > Class.forName: plugin.texttospeech.LuaLoader

V/Corona  ( 9168): < Class.forName: plugin.texttospeech.LuaLoader

V/Corona  ( 9168): Loading via reflection: plugin.texttospeech.LuaLoader

V/Corona  ( 9168): > Class.forName: plugin.brightness.LuaLoader

V/Corona  ( 9168): < Class.forName: plugin.brightness.LuaLoader

V/Corona  ( 9168): Loading via reflection: plugin.brightness.LuaLoader

V/Corona  ( 9168): > Class.forName: plugin.notifications.LuaLoader

V/Corona  ( 9168): < Class.forName: plugin.notifications.LuaLoader

V/Corona  ( 9168): Loading via reflection: plugin.notifications.LuaLoader

I/Corona  ( 9168): Verifica Original

I/Corona  ( 9168): WARNING: licensing.init() was already called for google.

I/Corona  ( 9168): Erro ao carregar licensingInit

I/Corona  ( 9168): applicationStart

V/Corona  ( 9168): > Class.forName: CoronaProvider.ads.admob.LuaLoader

V/Corona  ( 9168): < Class.forName: CoronaProvider.ads.admob.LuaLoader

V/Corona  ( 9168): Loading via reflection: CoronaProvider.ads.admob.LuaLoader

V/Corona  ( 9168): > Class.forName: plugin.google.iap.v3.LuaLoader

V/Corona  ( 9168): < Class.forName: plugin.google.iap.v3.LuaLoader

V/Corona  ( 9168): Loading via reflection: plugin.google.iap.v3.LuaLoader

I/Corona  ( 9168): applicationSuspend

This is my code:

function verificaOriginal() print("Verifica Original") local txt1 = "Circuito Bíblico" local txt2 = "Essa versão do aplicativo pode não ser original ou você está sem acesso à internet para poder válida-la!" local txt3 = "Repetir" local txt4 = "Aplicativo" local txt5 = "Sair" if setLanguage == 'en' then txt1 = "Bible Circuit" txt2 = "This version of the application may not be original or you may not have access to the internet to valid!" txt3 = "Repeat" txt4 = "Application" txt5 = "Exit" end local licensing = require( "licensing" ) local function licensingListener( event ) print\_r(event) if not ( event.isVerified ) then print("Não foi validado") versaoAtual.original = false saveTable(versaoAtual, "versaoApp.json") local function onComplete( event ) if ( event.action == "clicked" ) then local i = event.index if ( i == 1 ) then verificaOriginal() elseif ( i == 2 ) then abrePlayStore() GameSair() elseif ( i == 3 ) then GameSair() end else GameSair() end end local alert = native.showAlert( txt1, txt2, { txt3, txt4, txt5 }, onComplete ) else print("Validado") --versaoAtual.original = true --saveTable(versaoAtual, "versaoApp.json") --iniTelaAbertura() end end local licensingInit = licensing.init( "google" ) if ( licensingInit == true ) then print('carregado com sucesso') licensing.verify( licensingListener ) else print('Erro ao carregar licensingInit') local platform = system.getInfo('platformName') if platform ~= 'Win' and \_isPRO then versaoAtual.original = false saveTable(versaoAtual, "versaoApp.json") local function onComplete( event ) if ( event.action == "clicked" ) then local i = event.index if ( i == 1 ) then verificaOriginal() elseif ( i == 2 ) then abrePlayStore() GameSair() elseif ( i == 3 ) then GameSair() end else GameSair() end end local alert = native.showAlert( txt1, txt2, { txt3, txt4, txt5 }, onComplete ) else --versaoAtual.original = true --saveTable(versaoAtual, "versaoApp.json") --iniTelaAbertura() end end end

config.lua

application = { license = { google = { key = "Here was my license code obtained from the google play console", policy = "serverManaged" }, }, content = { scale = "adaptive", fps = 60, imageSuffix = { ["@1x"] = 1, ["@2x"] = 2, ["@3x"] = 3, }, }, }

Build.settings

settings = { plugins = { ["plugin.google.play.services"] = {publisherId = "com.coronalabs"}, ["plugin.google.iap.v3"] = {publisherId = "com.coronalabs"}, ['plugin.texttospeech'] = {publisherId = 'com.spiralcodestudio'}, ["CoronaProvider.native.popup.social"] = {publisherId = "com.coronalabs"}, ["plugin.pasteboard"] = {publisherId = "com.coronalabs"}, ["plugin.notifications"] = {publisherId = "com.coronalabs"}, ["plugin.brightness"] = {publisherId = "com.keetiz"}, }, orientation = { default ="portrait", supported = { "portraitUpsideDown", "portrait" }, }, android = { usesPermissions = { "android.permission.INTERNET", "android.permission.ACCESS\_NETWORK\_STATE", "android.permission.WRITE\_EXTERNAL\_STORAGE", "android.permission.RECEIVE\_BOOT\_COMPLETED", "com.android.vending.CHECK\_LICENSE", "com.android.vending.BILLING", }, }, }

Thank you for your help. I await your return.

Att.,

Joéver

still can’t get this to work also!

Hi @joeversh and @d.mach

I tried to implement the licensing like the documentation example (https://docs.coronalabs.com/api/library/licensing/) and got a bit confused with the errors, because I taked the same error than @joeversh:

WARNING: licensing.init() was already called for google.

Then I’ve tested the Licensing project from Corona SDK Samples and I noted that the documentation example is different. After a lot of tests, I created the following code to manage the licensing of my app:

License = {} License.provider = "google" -- licensing is only available for google License.store = require("store") License.gotoURL = "https://goo.gl/zYuhif" License.appName = "Your App Name" function License:licensing( event ) -- Handler that gets notified when the alert closes local function goToStore( event ) if ( event.action == "clicked" ) then system.openURL( License.gotoURL ) native.requestExit() end end if event.isVerified then print("Incredible! Someone bought my game!") else print("BANG!") local alert = native.showAlert( License.appName, "Ooops... something wrong happened... please go to Play Store, uninstall the game and download it again. Thank you!", { "OK" }, goToStore ) end end function License:initLicense() -- verify if is executing in simulator and if the store is correct if ((system.getInfo("environment") ~= "simulator") and (License.store.target == License.provider)) then License.licensingHandler = require( "licensing" ) License.licensingInit = License.licensingHandler.init( License.provider ) end end function License:verifyLicense() if ((system.getInfo("environment") ~= "simulator") and (License.store.target == License.provider)) then License.licensingHandler.verify( License ) end end

And now it´s working!  B)

I hope that it help you too…