android in-app billing problem

The event.transaction passed to the transactionCallback function contains invalid data. When I print it to the console I get something like “userdata: 0x2c8b38”

Here is my setup and let me know if you can see anything I’m doing wrong:

--initialize in-app purchase handling   
if store.availableStores.apple then  
 store.init("apple", inAppPurchaseCallback)  
elseif store.availableStores.google then  
 store.init("google", inAppPurchaseCallback)  
end   

Then to purchase the item (using a real id in my code):

store.purchase( { "com.mycompany.myapp.myitem" } )  

The transaction listener:

local function inAppPurchaseCallback(event)  
  
 print("inAppPurchaseCallback event data:")  
 for key,value in pairs(event) do  
 print(" ", key, value )  
 end  
 print("inAppPurchaseCallback transaction data:")  
 for key,value in pairs(event.transaction) do  
 print(" ", key, value )  
 end  
  
end  

Here’s the relevent logcat output from my android device:
[blockcode]
I/Corona ( 2062): inAppPurchaseCallback event data:
I/Corona ( 2062): name storeTransaction
I/Corona ( 2062): transaction userdata: 0x2c8b38
I/Corona ( 2062): inAppPurchaseCallback transaction data:
I/Corona ( 2062): Lua Runtime Error: lua_pcall failed with status: 2, error message is: bad argument #1 to ‘pairs’ (table expected, got userdata)
I/Corona ( 2062): inAppPurchaseCallback event data:
I/Corona ( 2062): name storeTransaction
I/Corona ( 2062): transaction userdata: 0x5398f8
I/Corona ( 2062): inAppPurchaseCallback transaction data:
I/Corona ( 2062): Lua Runtime Error: lua_pcall failed with status: 2, error message is: bad argument #1 to ‘pairs’ (table expected, got userdata)
[/blockcode]
Help!!! I’m running very close to a deadline and I could use any help or tips. Thanks in advance!
[import]uid: 192260 topic_id: 33472 reply_id: 333472[/import]

Hello,
This error appears to be as follows: You’re trying to loop through a “userdata” object using the “pairs” method, but that is meant for Lua tables (specifically, tables with a series of named values). The userdata object can’t be manipulated in such a manner. If you look at the code example in the following link, you’ll see that you must access the transaction parameters specifically, not via a pairs loop.

http://docs.coronalabs.com/api/library/store/restore.html

Hope this helps,
Brent [import]uid: 200026 topic_id: 33472 reply_id: 133056[/import]

Thanks, I am able to access those parameters directly. I didn’t realize this was possible in Corona. What I was really needing was a list of the available parameters in the transaction object, and it looks like that’s here:
http://docs.coronalabs.com/api/event/storeTransaction/transaction.html


The table event.transaction supports the following read-only properties:

  • “state” A string containing the state of the transaction. Valid values are “purchased”, “restored”,
  • "cancelled", and "failed".
  • "productIdentifier" The product identifier associated with the transaction.
  • "receipt" A unique receipt returned from the Store. It is returned as a hexadecimal string.
  • "identifier" A unique transaction identifier returned from the Store. It is a string.
  • "date" The date of when the transaction occurred.
  • "originalReceipt" A unique receipt returned from the Store from the original purchase attempt. This is mostly relevant in a case of a restore. It is returned as a hexadecimal string.
  • "originalIdentifier" A unique transaction identifier returned from the Store from the original purchase attempt. This is mostly relevant in a case of a restore. It is a string.
  • "originalDate" The date of when the original transaction occurred. This is mostly relevant in a case of a restore.
  • "errorType" The type of error that occurred when the state is "failed" (a string).
  • "errorString" A (sometimes) more descriptive error message of what went wrong in the "failed" case.

  • ` [import]uid: 192260 topic\_id: 33472 reply\_id: 133133[/import]

    Couple more questions about this. Is there a reason that the date parameter is a string? It would make a whole lot more sense to have it as an os.time object, and then we could store or format that date however we want.

    Is the Android OrderID coming back as the “receipt” or the “transactionIdentifier”?

    Also, it would be very helpful to have access to the INAPP_SIGNATURE and INAPP_SIGNED_DATA so that we can verify those on our server. [import]uid: 192260 topic_id: 33472 reply_id: 133168[/import]

    Hello,
    This error appears to be as follows: You’re trying to loop through a “userdata” object using the “pairs” method, but that is meant for Lua tables (specifically, tables with a series of named values). The userdata object can’t be manipulated in such a manner. If you look at the code example in the following link, you’ll see that you must access the transaction parameters specifically, not via a pairs loop.

    http://docs.coronalabs.com/api/library/store/restore.html

    Hope this helps,
    Brent [import]uid: 200026 topic_id: 33472 reply_id: 133056[/import]

    Thanks, I am able to access those parameters directly. I didn’t realize this was possible in Corona. What I was really needing was a list of the available parameters in the transaction object, and it looks like that’s here:
    http://docs.coronalabs.com/api/event/storeTransaction/transaction.html


    The table event.transaction supports the following read-only properties:

  • “state” A string containing the state of the transaction. Valid values are “purchased”, “restored”,
  • "cancelled", and "failed".
  • "productIdentifier" The product identifier associated with the transaction.
  • "receipt" A unique receipt returned from the Store. It is returned as a hexadecimal string.
  • "identifier" A unique transaction identifier returned from the Store. It is a string.
  • "date" The date of when the transaction occurred.
  • "originalReceipt" A unique receipt returned from the Store from the original purchase attempt. This is mostly relevant in a case of a restore. It is returned as a hexadecimal string.
  • "originalIdentifier" A unique transaction identifier returned from the Store from the original purchase attempt. This is mostly relevant in a case of a restore. It is a string.
  • "originalDate" The date of when the original transaction occurred. This is mostly relevant in a case of a restore.
  • "errorType" The type of error that occurred when the state is "failed" (a string).
  • "errorString" A (sometimes) more descriptive error message of what went wrong in the "failed" case.

  • ` [import]uid: 192260 topic\_id: 33472 reply\_id: 133133[/import]

    One more bit of weirdness: It seems that the transactionCallback gets called on a separate thread. That’s my guess at least, since all of the variables set in my file are nil.

    Fortunately, I was able to handle it by registering a custom event listener on the main thread, and then calling dispatch from the transactionCallback thread. The problem is that this wasn’t documented anywhere (that I found), and it took me several hours and a few dollars of in-app purchases in the Google store to figure out what the problem was.

    My suggestion would be to update your documentation to make it more obvious how the transactionCallback works.

    [import]uid: 192260 topic_id: 33472 reply_id: 133301[/import]

    Couple more questions about this. Is there a reason that the date parameter is a string? It would make a whole lot more sense to have it as an os.time object, and then we could store or format that date however we want.

    Is the Android OrderID coming back as the “receipt” or the “transactionIdentifier”?

    Also, it would be very helpful to have access to the INAPP_SIGNATURE and INAPP_SIGNED_DATA so that we can verify those on our server. [import]uid: 192260 topic_id: 33472 reply_id: 133168[/import]

    One more bit of weirdness: It seems that the transactionCallback gets called on a separate thread. That’s my guess at least, since all of the variables set in my file are nil.

    Fortunately, I was able to handle it by registering a custom event listener on the main thread, and then calling dispatch from the transactionCallback thread. The problem is that this wasn’t documented anywhere (that I found), and it took me several hours and a few dollars of in-app purchases in the Google store to figure out what the problem was.

    My suggestion would be to update your documentation to make it more obvious how the transactionCallback works.

    [import]uid: 192260 topic_id: 33472 reply_id: 133301[/import]