store.canLoadProducts == false

Hello everyone,

We have an app where in-app purchasing works perfectly fine for iOS/Apple, however, for Android/Google it does not. 

We’ve managed to find that the issue lies with store.canLoadProducts always being false, and unsure why.  It seemed as though initializing and using the store for Apple, according to Corona docs, is exactly the same as with Google with the exception of store.init being passed “google” as store type.  It doesn’t even hit our loadProductsCallback function, since canLoadProducts is false.  Below is the code:

local PRODUCT\_LIST = {--SKUs}; local function transactionCallback(e) --etc end store = require("store"); store.init("google", transactionCallback); timer.performWithDelay(1000, function() if (store.canLoadProducts == true) then store.loadProducts(PRODUCT\_LIST, loadProductsCallback); else native.showAlert("Store Failed", "Cannot load products at this time!", {"Okay"}); end end);

And in build.settings for Android we have:

android = { usesPermissions = { "com.android.vending.BILLING", "android.permission.INTERNET", "android.permission.ACCESS\_WIFI\_STATE", "android.permission.ACCESS\_NETWORK\_STATE", }

So, what more is possibly needed to ensure store.canLoadProducts will be true after store.init?  Is the package field when building important to this?  Is this or any other area something we should be double checking?  We are working in Corona public build 2076.

The version of store currently built into the core of Corona uses Google IAB v2 which does not support that functionality.  You should use Corona’s Google IAP v3 plugin instead which does support this functionality.  You can find more information about it here: http://docs.coronalabs.com/plugin/google-iap-v3/index.html

Thanks for the reply, this did seem to solve the current issue with canLoadProducts.  However, I’m running into another issue.  I’m getting “unknown event” back whenever I try store.purchase an item, what would be going wrong in this case?  I have:

store = require("plugin.google.iap.v3"); storeType = "google"; store.init(transactionCallback); timer.performWithDelay(1000, function() if (store.canLoadProducts == true) then store.loadProducts(PRODUCT\_LIST, loadProductsCallback); end end);

The key formatted correctly in my config.lua file, and in build.settings:

plugins = { -- key is the name passed to Lua's 'require()' ["plugin.google.iap.v3"] = { -- required publisherId = "com.coronalabs", }, },

From what I could tell, I followed all the guidelines properly, but for some reason am getting this unknown event back.

Your code snippet doesn’t contain a call to store.purchase.  How are you actually calling it?

Apologies, I had meant to include it but I overlooked it.

local PRODUCT\_LIST = { "com.SKU.unlock", }; store.purchase(PRODUCT\_LIST[1]);

I noted that in the docs you sent me, it specified that purchase() now takes the SKU and not a table of SKUs as before, so now it’s only getting passed in this one SKU.

What exactly do you mean when you say “unknown event”?

If you look at the example Corona has on the docs for the transactionCallback:

function storeTransaction( event ) local transaction = event.transaction if transaction.state == "purchased" then -- If store.purchase() was successful, you should end up in here for each product you buy. print("Transaction succuessful!") print("productIdentifier", transaction.productIdentifier) print("receipt", transaction.receipt) print("transactionIdentifier", transaction.identifier) print("date", transaction.date) elseif transaction.state == "restored" then print("Transaction restored (from previous session)") elseif transaction.state == "cancelled" then print("User cancelled transaction") elseif transaction.state == "failed" then print("Transaction failed, type:", transaction.errorType, transaction.errorString) else print("unknown event") --HERE end --etc store.finishTransaction( transaction ) --figured I'd edit this in so we know this is happening end

it’s hitting that final else statement where it has the print “unknown event.”  I haven’t found anyone else who had a similar problem, so the how and why behind the “unknown event” is pretty much a mystery to me.

From what we can tell, we do have our products loaded successfully, it just seems that, even if we publish the app, the purchasing does not work at all. Is there any way we could try to use Google iAP v2, maybe, or is that phased out?

One other thing… now it seems like the callback isn’t being invoked at all upon a store.purchase request.  What could cause this?

http://developer.android.com/google/play/billing/billing_reference.html#billing-codes

Whats happening is that Google is returning a purchaseState thats not 0, 1, or 2.  The most likely cause is an issue with the setup.  There might be hints in the log that tells you why its not working.

Another thing is to print out transaction.errorType, transaction.errorString

anyways to see if those fields have been populated.

We managed to figure out the issue, thanks for all the assistance.

Another question… let’s say a user purchases something from the Apple store, then uninstalls the app.  They then reinstall the app and try to purchase the same thing as before, and get a message to the effect of “you’ve already purchased this pack, would you like to download it for free?”  This is something that doesn’t seem to be handled the same way as Google (you just get an error that it was already bought, and nothing happens).  I’m assuming there’s nothing we could do and that this is just automatic store functionality, but we figured we would try asking and see if it was possible for us to do something similar to Apple’s prompt, except on Google Play?

It would be helpful to post your solution here for when others stumble upon this thread.

Thanks

Rob

You can call http://docs.coronalabs.com/plugin/google-iap-v3/restore.html to see what items the user has previously purchased.

The version of store currently built into the core of Corona uses Google IAB v2 which does not support that functionality.  You should use Corona’s Google IAP v3 plugin instead which does support this functionality.  You can find more information about it here: http://docs.coronalabs.com/plugin/google-iap-v3/index.html

Thanks for the reply, this did seem to solve the current issue with canLoadProducts.  However, I’m running into another issue.  I’m getting “unknown event” back whenever I try store.purchase an item, what would be going wrong in this case?  I have:

store = require("plugin.google.iap.v3"); storeType = "google"; store.init(transactionCallback); timer.performWithDelay(1000, function() if (store.canLoadProducts == true) then store.loadProducts(PRODUCT\_LIST, loadProductsCallback); end end);

The key formatted correctly in my config.lua file, and in build.settings:

plugins = { -- key is the name passed to Lua's 'require()' ["plugin.google.iap.v3"] = { -- required publisherId = "com.coronalabs", }, },

From what I could tell, I followed all the guidelines properly, but for some reason am getting this unknown event back.

Your code snippet doesn’t contain a call to store.purchase.  How are you actually calling it?

Apologies, I had meant to include it but I overlooked it.

local PRODUCT\_LIST = { "com.SKU.unlock", }; store.purchase(PRODUCT\_LIST[1]);

I noted that in the docs you sent me, it specified that purchase() now takes the SKU and not a table of SKUs as before, so now it’s only getting passed in this one SKU.

What exactly do you mean when you say “unknown event”?

If you look at the example Corona has on the docs for the transactionCallback:

function storeTransaction( event ) local transaction = event.transaction if transaction.state == "purchased" then -- If store.purchase() was successful, you should end up in here for each product you buy. print("Transaction succuessful!") print("productIdentifier", transaction.productIdentifier) print("receipt", transaction.receipt) print("transactionIdentifier", transaction.identifier) print("date", transaction.date) elseif transaction.state == "restored" then print("Transaction restored (from previous session)") elseif transaction.state == "cancelled" then print("User cancelled transaction") elseif transaction.state == "failed" then print("Transaction failed, type:", transaction.errorType, transaction.errorString) else print("unknown event") --HERE end --etc store.finishTransaction( transaction ) --figured I'd edit this in so we know this is happening end

it’s hitting that final else statement where it has the print “unknown event.”  I haven’t found anyone else who had a similar problem, so the how and why behind the “unknown event” is pretty much a mystery to me.

From what we can tell, we do have our products loaded successfully, it just seems that, even if we publish the app, the purchasing does not work at all. Is there any way we could try to use Google iAP v2, maybe, or is that phased out?

One other thing… now it seems like the callback isn’t being invoked at all upon a store.purchase request.  What could cause this?

http://developer.android.com/google/play/billing/billing_reference.html#billing-codes

Whats happening is that Google is returning a purchaseState thats not 0, 1, or 2.  The most likely cause is an issue with the setup.  There might be hints in the log that tells you why its not working.

Another thing is to print out transaction.errorType, transaction.errorString

anyways to see if those fields have been populated.

We managed to figure out the issue, thanks for all the assistance.

Another question… let’s say a user purchases something from the Apple store, then uninstalls the app.  They then reinstall the app and try to purchase the same thing as before, and get a message to the effect of “you’ve already purchased this pack, would you like to download it for free?”  This is something that doesn’t seem to be handled the same way as Google (you just get an error that it was already bought, and nothing happens).  I’m assuming there’s nothing we could do and that this is just automatic store functionality, but we figured we would try asking and see if it was possible for us to do something similar to Apple’s prompt, except on Google Play?

It would be helpful to post your solution here for when others stumble upon this thread.

Thanks

Rob