Google Play IAP ridiculous success rate

Hi,

I’ve got a game on google play.

I use IAP, and also flurry for tracking percentages of trials and successes for purchases.

Example :

analytics.logEvent("try to buy 100,000 coins") store.purchase( { "100000.coins" } ) 

And in transactionCallback():

if transaction.state == "purchased" then analytics.logEvent("100000 coins bought") elseif transaction.state == "failed" then analytics.logEvent("Transaction failed, type: " .. transaction.errorType) end

The problem is, checking my flurry dashboard i see " 100000 coins bought" 17 times,

And " Transaction failed, type: invalidClient" Over 3,500 Times!!!

Now, I didn’t expect to get a lot of IAP, but is this success rate too low to be valid…?

Anyone else experiencing this?

Thanks!

Most of the posts I’ve seen about invalidClient have to do with the app, or the items having not propagated through Google’s servers.  Is it possible your app got out into the wild before your items had a chance to make it though google’s servers?

See:  http://forums.coronalabs.com/topic/33372-testing-google-play-iap-while-app-is-in-draft-mode-invalidclient-error/

I don’t know why you would get that on a live app with live items.

Hi Rob, and thanks.

But if you, from the Corona staff, don’t know - who would…?

Would you like me to share more of my code?

Ron

Well the engineers might know more than me since they wrote the code that you’re using and know the Android side better than I, but its going to be helpful to see your build.settings, config.lua, store code etc.  I don’t know if there are any codes in the event table that might help understand the problem more.  See this doc:

http://developer.android.com/google/play/billing/v2/billing_reference.html

Look for Table 6.  I’m not sure if invalidClient refers to a specific message in this list, or if it’s general to several of them and there is a code indicating which one.  But the list includes service down, the client might be in an unsupported country, invalid item codes (though I think this would happen all the time, not some of the time), and a host of other errors. 

Since it works some time, but not all the time, that sounds like an unsupported country issue as the most likely cause.  But lets post a little more information before I take this to the engineers. 

Also what version of Corona SDK are you using?

I’m using build 2013.1135

my Android section in the build.settings is :

android =

    {

        usesPermissions =

        {

            “com.android.vending.BILLING”,

            “android.permission.INTERNET”,

        },

    },

config.lua has only the content width & height.

I don’t think it’s a specific country since the US is #1 in my downloaded from list

Keep in mind the purchases are successful a small percent of the time…

Well 1137 is the latest public build.  There were a couple of issues with 1135, so make sure you grab 1137 and give that a go.  I would still like to see.  I’m not sure the above is enough for the engineers.  Can you post your whole build.settings, config.lua and the relevant store code?

Also any change in your analytics today?

No changes, I’ve got 16 “invalidClient” on July 22nd (and no successful purchases).

This probably has nothing to do with the build number since I’ve worked with many, most of them official.

Also, I have created a completely new set of in-app items, with new ID’s and published another build - Tested and works on my own device.

Would you like to try maybe? (I can cancel the transaction after that, if it works…)

Here is my complete config.lua :

application =

{

        content =

        {

                width = 320,

                height = 570,

                scale = “zoomEven”

        },

build.settings :

settings = {

plugins =

    {

        – key is the name passed to Lua’s ‘require()’

        [“plugin.tapfortap”] =

        {

            – required

            publisherId = “com.tapfortap”,

        },

    },

    orientation = {

            default = “landscapeRight”,

            content = “landscapeRight”,

            supported = {

                “landscapeRight”

            },

    },

    android =

    {

        usesPermissions =

        {

            “com.android.vending.BILLING”,

            “android.permission.INTERNET”,

        },

    },

    iphone = {

        plist = {

            CFBundleIconFile = “Icon.png”,

            CFBundleIconFiles = {

            “Icon.png”,

            “Icon@2x.png”,

            “Icon-72.png”,

            “Icon-72@2x.png”,

            “Icon-Small.png”,

            “Icon-Small@2x.png”,

            “Icon-Small-50.png”,

            “Icon-Small-50@2x.png”,

            },

            UIApplicationExitsOnSuspend = false,

            CFBundleURLTypes =

            {

                {

                    CFBundleURLSchemes =

                    {

                        “my_FB_app_id”,

                    }

                }

            }

        }

    }

}

and code :

1. 

    function coinItem1:touch(event) 

        if event.phase == “ended” then

            coinItemClicked = 1

            flurry.logEvent(“try to buy 10,000 coins”)

            store.purchase( { “ten_k” } )

        end

    end    

    function transactionCallback( event )

        if event.transaction.state == “purchased” then

            

            if (coinItemClicked == 1) then

                totalCoins = totalCoins + 10000

                flurry.logEvent(“10000 coins bought”)

            end

        elseif event.transaction.state == “failed” then

            flurry.logEvent("Transaction failed, type: " … event.transaction.errorType … " desc: " … event.transaction.errorString)

            native.showAlert("Transaction failed, type: " … event.transaction.errorType, event.transaction.errorString,{“ok”})

        elseif event.transaction.state == “cancelled” then

            flurry.logEvent(“Transaction cancelled”)

        end

        store.finishTransaction( event.transaction )

    end

store.init( “google”, transactionCallback )

I’m waiting to hear back from the engineers. 

Thanks Rob,

I’ll be waiting too… :slight_smile:

I’ve heard back from the engineering team.  Invalid Client happens for these reasons:

  1. You are logged into the Google Play app with your developer account.  These will always fail.  You must use a test account.

  2. You have not setup an account with the Google Play app yet.

  3. You have not agreeded to the Google Play App’s license agreement yet.

  4. The Google Play app is failing to connect to Google’s servers.

Try tapping on the Google Play app and make sure you can connect to the store successfully and view other apps.  If you need additional instructions on testing your app, please see:

http://developer.android.com/google/play/billing/billing_testing.html#billing-testing-static

 

Hi Rob,

This isn’t what I expected…

I’m way passed the test account phase

Again, I have tested on my device and the IAP works, and there are some successful purchases.

The solution to the mystery is one of these two:

  1. More than 99% of google play users never agreed to google’s T&C and never made an IAP (unlikely but theoretically possible)

  2. Something else is wrong, In which case can I ask you or maybe someone from the tech team to download my game (from here: https://play.google.com/store/apps/details?id=com.mumblefish.interpolrunner) and make a purchase? I’ll cancel the transaction from my google checkout dashboard if it works. If it doesn’t, well, we’ll be on to something, since I can’t reproduce the error myself.

Thanks again,

Ron

I’m installing your app and I’ll check it out in a little while.

Some more info:

in the last week there were:

“Transaction failed, type: invalidClient desc: The Android Marketplace app has not been properly configured with an account.” 23 times

but “Transaction failed, type: invalidClient desc:” (with an empty description) 344 times

I guess this addresses the first option I mentioned above. 

Android Marketplace app

This is coming for the app before Google Play.   The empty description is because that’s what we get back from Google in the API call.  The only way to know what is going on is to do an adb logcat and watch for errors from Google Play’s app.

Most of the posts I’ve seen about invalidClient have to do with the app, or the items having not propagated through Google’s servers.  Is it possible your app got out into the wild before your items had a chance to make it though google’s servers?

See:  http://forums.coronalabs.com/topic/33372-testing-google-play-iap-while-app-is-in-draft-mode-invalidclient-error/

I don’t know why you would get that on a live app with live items.

Hi Rob, and thanks.

But if you, from the Corona staff, don’t know - who would…?

Would you like me to share more of my code?

Ron

Well the engineers might know more than me since they wrote the code that you’re using and know the Android side better than I, but its going to be helpful to see your build.settings, config.lua, store code etc.  I don’t know if there are any codes in the event table that might help understand the problem more.  See this doc:

http://developer.android.com/google/play/billing/v2/billing_reference.html

Look for Table 6.  I’m not sure if invalidClient refers to a specific message in this list, or if it’s general to several of them and there is a code indicating which one.  But the list includes service down, the client might be in an unsupported country, invalid item codes (though I think this would happen all the time, not some of the time), and a host of other errors. 

Since it works some time, but not all the time, that sounds like an unsupported country issue as the most likely cause.  But lets post a little more information before I take this to the engineers. 

Also what version of Corona SDK are you using?

I’m using build 2013.1135

my Android section in the build.settings is :

android =

    {

        usesPermissions =

        {

            “com.android.vending.BILLING”,

            “android.permission.INTERNET”,

        },

    },

config.lua has only the content width & height.

I don’t think it’s a specific country since the US is #1 in my downloaded from list

Keep in mind the purchases are successful a small percent of the time…

Well 1137 is the latest public build.  There were a couple of issues with 1135, so make sure you grab 1137 and give that a go.  I would still like to see.  I’m not sure the above is enough for the engineers.  Can you post your whole build.settings, config.lua and the relevant store code?

Also any change in your analytics today?

No changes, I’ve got 16 “invalidClient” on July 22nd (and no successful purchases).

This probably has nothing to do with the build number since I’ve worked with many, most of them official.

Also, I have created a completely new set of in-app items, with new ID’s and published another build - Tested and works on my own device.

Would you like to try maybe? (I can cancel the transaction after that, if it works…)

Here is my complete config.lua :

application =

{

        content =

        {

                width = 320,

                height = 570,

                scale = “zoomEven”

        },

build.settings :

settings = {

plugins =

    {

        – key is the name passed to Lua’s ‘require()’

        [“plugin.tapfortap”] =

        {

            – required

            publisherId = “com.tapfortap”,

        },

    },

    orientation = {

            default = “landscapeRight”,

            content = “landscapeRight”,

            supported = {

                “landscapeRight”

            },

    },

    android =

    {

        usesPermissions =

        {

            “com.android.vending.BILLING”,

            “android.permission.INTERNET”,

        },

    },

    iphone = {

        plist = {

            CFBundleIconFile = “Icon.png”,

            CFBundleIconFiles = {

            “Icon.png”,

            “Icon@2x.png”,

            “Icon-72.png”,

            “Icon-72@2x.png”,

            “Icon-Small.png”,

            “Icon-Small@2x.png”,

            “Icon-Small-50.png”,

            “Icon-Small-50@2x.png”,

            },

            UIApplicationExitsOnSuspend = false,

            CFBundleURLTypes =

            {

                {

                    CFBundleURLSchemes =

                    {

                        “my_FB_app_id”,

                    }

                }

            }

        }

    }

}

and code :

1. 

    function coinItem1:touch(event) 

        if event.phase == “ended” then

            coinItemClicked = 1

            flurry.logEvent(“try to buy 10,000 coins”)

            store.purchase( { “ten_k” } )

        end

    end    

    function transactionCallback( event )

        if event.transaction.state == “purchased” then

            

            if (coinItemClicked == 1) then

                totalCoins = totalCoins + 10000

                flurry.logEvent(“10000 coins bought”)

            end

        elseif event.transaction.state == “failed” then

            flurry.logEvent("Transaction failed, type: " … event.transaction.errorType … " desc: " … event.transaction.errorString)

            native.showAlert("Transaction failed, type: " … event.transaction.errorType, event.transaction.errorString,{“ok”})

        elseif event.transaction.state == “cancelled” then

            flurry.logEvent(“Transaction cancelled”)

        end

        store.finishTransaction( event.transaction )

    end

store.init( “google”, transactionCallback )