Any tips for geting in-app billing v3 to work?

V2 of the in-app billing works fine. But if I switch to the v3 plugin with the appropriate require, I can’t purchase anything.

transactionCallback: Received event storeTransaction

I/Corona  ( 3800): state: failed

I/Corona  ( 3800): errorType: 5

I/Corona  ( 3800): errorString: Unable to buy item (response: 5:Developer Error)

 

I’ve tried testing on devices registered to other user accounts and have tried giving those accounts alpha build access (and waiting for hours for the builds to register) but no luck. Does anyone have any suggestions?

Share your purchase code here…

Did you make the correct modifications?

On the former version you had to request the purchase passing a table with the sku. On the v3, you only pass the sku string (no more table).

I spent hours yesterday generating builds with higher version codes, uploading those builds to Google Play, waiting for the builds to register, installing the APK by side-load and through alpha testing (with the user accounts registered as testers and with alpha testing access) and with the app in production draft mode. Clearly I’ve missed something because I’m stuck with the same error:

errorType: 5

I/Corona  (12913): errorString: Unable to buy item (response: 5:Developer Error)

 

For passing products, I used a string rather than a table for V2 and V3.  The code below has worked fine for the V2 app I have in the store. In recent builds, I went with “android.test.purchased” as the productID rather than live products. Same result.

store.purchase{products.packThree} -- products.packThree = "productID"

I added the appropriate build & config settings:

["plugin.google.iap.v3"] = { -- required publisherId = "com.coronalabs", },

license =

            {

            google =

               {

               key = “mykey”,

               policy = “serverManaged”,

               },

            },

The store code is as follows:

local products = require("products") function transactionCallback( event ) print("transactionCallback: Received event " .. tostring(event.name)) print("state: " .. tostring(event.transaction.state)) print("errorType: " .. tostring(event.transaction.errorType)) print("errorString: " .. tostring(event.transaction.errorString)) local tstate = event.transaction.state local transaction = event.transaction if store.availableStores.google and tstate == "purchased" then local timeStamp = products.makeTimeStamp(transaction.date,"ctime") if timeStamp + 360 \< os.time() then -- if the time stamp is older than 5 minutes, we will assume a restore. print("map this purchase to a restore") tstate = "restored" restoring = false end end if tstate == "purchased" then print("Transaction succuessful!", transaction.productIdentifier) if transaction.productIdentifier == products.packOne then --update product variable elseif transaction.productIdentifier == products.packTwo then --update product variable elseif transaction.productIdentifier == products.packThree then --update product variable elseif transaction.productIdentifier == products.packFour then --update product variable elseif transaction.productIdentifier == products.packFive then --update product variable end -- Show alert with one button native.showAlert("Thank you!", "Your support is greatly appreciated!", {"Okay"}) -- elseif tstate == "refunded" then if transaction.productIdentifier == products.packFive then print ("Refunded") --update product variable end elseif tstate == "restored" then if transaction.productIdentifier == products.packFive then print("noAds restored") --update product variable end elseif tstate == "cancelled" then print("User cancelled transaction") elseif tstate == "failed" then print("Transaction failed, type:", transaction.errorType, transaction.errorString) else print("unknown event") end store.finishTransaction( transaction ) --save data to json file --update screen display of quantities end store.init( transactionCallback )

For passing products, I used a string rather than a table for V2 and V3.  The code below has worked fine for the V2 app I have in the store. 

In your example, you are passing the product SKU as table, not as string.

And about testing, you don’t need to go thru all those steps to test the iAP.

You can do the following:

1st) Test if the code is correct by simulating purchase using the fakes sku from Google.

  • sku “android.test.purchased” returns always a successful purchase.
  • sku “android.test.canceled” returns a purchase that was cancelled by the user.
  • sku “android.test.item_unavailable” returns that the product does not exist.

2nd) With the sku aboves working as expected, now you can test with your real SKUs. To do that, you just register them on the Google Dev Console and uploads any build that has the billing permission requested. Now, if you install your build (made with the Release key and with the same version name/code that you upload to the store. Note: it does not need to be the same build. Just one with the same name/code version) on your phone, the IAP will already work.

If you add your email to the list of “LICENSE TESTING” all purchases would not be charged.

Ah, so store.purchase{products.packThree} should be store.purchase(products.packThree)?

Thank you. I’ll give that a try.

Yes. Just be careful that this is only for Google IAP v3 and Amazon IAP.  For iOS IAP you pass the sku as table.

Share your purchase code here…

Did you make the correct modifications?

On the former version you had to request the purchase passing a table with the sku. On the v3, you only pass the sku string (no more table).

I spent hours yesterday generating builds with higher version codes, uploading those builds to Google Play, waiting for the builds to register, installing the APK by side-load and through alpha testing (with the user accounts registered as testers and with alpha testing access) and with the app in production draft mode. Clearly I’ve missed something because I’m stuck with the same error:

errorType: 5

I/Corona  (12913): errorString: Unable to buy item (response: 5:Developer Error)

 

For passing products, I used a string rather than a table for V2 and V3.  The code below has worked fine for the V2 app I have in the store. In recent builds, I went with “android.test.purchased” as the productID rather than live products. Same result.

store.purchase{products.packThree} -- products.packThree = "productID"

I added the appropriate build & config settings:

["plugin.google.iap.v3"] = { -- required publisherId = "com.coronalabs", },

license =

            {

            google =

               {

               key = “mykey”,

               policy = “serverManaged”,

               },

            },

The store code is as follows:

local products = require("products") function transactionCallback( event ) print("transactionCallback: Received event " .. tostring(event.name)) print("state: " .. tostring(event.transaction.state)) print("errorType: " .. tostring(event.transaction.errorType)) print("errorString: " .. tostring(event.transaction.errorString)) local tstate = event.transaction.state local transaction = event.transaction if store.availableStores.google and tstate == "purchased" then local timeStamp = products.makeTimeStamp(transaction.date,"ctime") if timeStamp + 360 \< os.time() then -- if the time stamp is older than 5 minutes, we will assume a restore. print("map this purchase to a restore") tstate = "restored" restoring = false end end if tstate == "purchased" then print("Transaction succuessful!", transaction.productIdentifier) if transaction.productIdentifier == products.packOne then --update product variable elseif transaction.productIdentifier == products.packTwo then --update product variable elseif transaction.productIdentifier == products.packThree then --update product variable elseif transaction.productIdentifier == products.packFour then --update product variable elseif transaction.productIdentifier == products.packFive then --update product variable end -- Show alert with one button native.showAlert("Thank you!", "Your support is greatly appreciated!", {"Okay"}) -- elseif tstate == "refunded" then if transaction.productIdentifier == products.packFive then print ("Refunded") --update product variable end elseif tstate == "restored" then if transaction.productIdentifier == products.packFive then print("noAds restored") --update product variable end elseif tstate == "cancelled" then print("User cancelled transaction") elseif tstate == "failed" then print("Transaction failed, type:", transaction.errorType, transaction.errorString) else print("unknown event") end store.finishTransaction( transaction ) --save data to json file --update screen display of quantities end store.init( transactionCallback )

For passing products, I used a string rather than a table for V2 and V3.  The code below has worked fine for the V2 app I have in the store. 

In your example, you are passing the product SKU as table, not as string.

And about testing, you don’t need to go thru all those steps to test the iAP.

You can do the following:

1st) Test if the code is correct by simulating purchase using the fakes sku from Google.

  • sku “android.test.purchased” returns always a successful purchase.
  • sku “android.test.canceled” returns a purchase that was cancelled by the user.
  • sku “android.test.item_unavailable” returns that the product does not exist.

2nd) With the sku aboves working as expected, now you can test with your real SKUs. To do that, you just register them on the Google Dev Console and uploads any build that has the billing permission requested. Now, if you install your build (made with the Release key and with the same version name/code that you upload to the store. Note: it does not need to be the same build. Just one with the same name/code version) on your phone, the IAP will already work.

If you add your email to the list of “LICENSE TESTING” all purchases would not be charged.

Ah, so store.purchase{products.packThree} should be store.purchase(products.packThree)?

Thank you. I’ll give that a try.

Yes. Just be careful that this is only for Google IAP v3 and Amazon IAP.  For iOS IAP you pass the sku as table.

I ran into the same problem today (due to v2 being cut off by Google) and this post saved me a stack of time - only wish I’d looked for it earlier!!

Thanks guys.

One thing that has been frustrating me about testing IAPs is the need to:

  1. do a new build,

  2. upload to Google Play (into Beta),

  3. wait for the thing to become available (seems to be anything from 10 mins to 2 hours) THE WORST PART OF THE PROCESS

  4. download onto test device

  5. perform test

Note that my app is > 50mb so I need to have an expansion file - seems to easy way to get it onto a test device without going through the Google Play loop?

Nathan.

I experience this problem

check if your “Version Code” and “Version Name” match with lastest APK ‘in Prod’ status.

hope this help.

Huh?

I ran into the same problem today (due to v2 being cut off by Google) and this post saved me a stack of time - only wish I’d looked for it earlier!!

Thanks guys.

One thing that has been frustrating me about testing IAPs is the need to:

  1. do a new build,

  2. upload to Google Play (into Beta),

  3. wait for the thing to become available (seems to be anything from 10 mins to 2 hours) THE WORST PART OF THE PROCESS

  4. download onto test device

  5. perform test

Note that my app is > 50mb so I need to have an expansion file - seems to easy way to get it onto a test device without going through the Google Play loop?

Nathan.

I experience this problem

check if your “Version Code” and “Version Name” match with lastest APK ‘in Prod’ status.

hope this help.

Huh?