I'm completely failing at IAP :-(

Hey all,

I'm having quite a bit of trouble getting a rather simple implementation of IAP going in my app, and was hoping I could get some help. I have the non-consumable item set up in iTunes Connect, and a Test User account set up as well. I also have the proper Product ID.

However, whenever I try to run the purchase function, I get the same error returned: "Could not connect to iTunes store". I'm sure I'm doing something stupid, but I can't figure out what it is. Here's the extent of my code (some things I've omitted because they aren't related to the IAP.)

Oh, also...I just have one item that I'd like to be up for purchase, so I'm just directly imputing it's product ID (in the com.blah.blahblah.productID fashion) directly into the store.purchase() function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
store = require("store")
 
local function buyAction()
   audio.play(clickSound)
   if store.canMakePurchases then
      store.purchase( {"com.loganhasson.crazydriver.startwith2lives"} )
   else
      local alert = native.showAlert( "Rapid Racer", "Purchase are not available", { "OK"})
   end
end
 
local listOfProducts = { 
       "com.loganhasson.crazydriver.startwith2lives",  
    }
    
    local validProducts, invalidProducts = {}, {}
    
    function unpackValidProducts()
        print ("Loading product list")
        if not validProducts then
            native.showAlert( "In-App features not available", "initStore() failed", { "OK" } )        
        else
            for i=1, #invalidProducts do
                native.showAlert( "Item " .. invalidProducts[i] .. " is invalid.",{ "OK" } )
            end
 
        end
    end
    
    function loadProductsCallback( event )
        validProducts = event.products
        invalidProducts = event.invalidProducts    
        unpackValidProducts ()
    end
    
    function setupMyStore (event)
        store.loadProducts( listOfProducts, loadProductsCallback )
    end
 
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.
 
                local alert = native.showAlert( "Rapid Racer", "Transaction Successful!", { "OK"})
 
                doSomethingHere()
 
        elseif  transaction.state == "restored" then
            local alert = native.showAlert( "Rapid Racer", "Transaction restored (from previous session)", { "OK"})
 
 
        elseif transaction.state == "cancelled" then
 
                local alert = native.showAlert( "Rapid Racer", "User cancelled transaction", { "OK"})
 
        elseif transaction.state == "failed" then
 
                local alert = native.showAlert( "Rapid Racer", "Transaction failed!"..transaction.errorString, { "OK"})
            --print("Transaction failed, type:", transaction.errorType, transaction.errorString)
 
        else
 
                local alert = native.showAlert( "Rapid Racer", "Unknown event", { "OK"})
        end
        store.finishTransaction( transaction )
end
 
store.init( storeTransaction )
setupMyStore()

The error regarding connecting could be related to your connection or to your test user ID - have you made sure you're connected to WiFi and signed in using whichever test user ID you created in iTC?

Peach :)

Hey,
Yeah, I'm definitely connected to WiFi every time I try (I've tried on a couple different networks, as well). As far as the Test ID goes, though...am I supposed to log in with that ID in Settings under the App Store? I thought I was only supposed to use the test ID info when the purchase actually starts (aka, when it asks for ID and password)?

Logan

Hi Logan,

I thought you may have been signed into your normal account and that it may cause things not to show up correctly, although actually I think it would still show up, the purchase would just fail. (I have not used IAP in a long time.)

Have you signed the paid app contract?

Peach :)

when i tested my IAP's i logged into my test account in "settings-store". Im not all that sure it was neccessary, but i did it that way just incase.

Are you testing your IAP via an Ad-Hoc build? Im pretty sure they only work when you do it that way..

If youve only just set up your single purchase, then you will need to wait a day or so anyway for it to start working properly for testing.

You have to upload a binary to itunesconnect. Then reject it. Afterwards testing IAPs should work. Its very strange, but that may be the problem...

Hoan

lhvio89 - any of this worked for you?

Hoan, your suggestion is clever - when I did IAP it was to an update of a free app and I never had to do this step.

Peach :)

Hmm...weird. I think I'll go ahead and try the upload-a-binary-and-then-reject-it plan. The other ideas didn't work for me :-/

Fingers crossed that this'll work!

Also, slightly unrelated question, but with the store.restore() function...do I need to pass it a specific product? Or just call it by itself, and all restorable-products are restored?

Thanks!

I've successfully gotten this to work myself (for non-consumables). Here's what I did:

1. Add a non-consumable purchase to iTunes Connect.
2. Wait 24 hours.
3. Create a test user.
4. Build for your device using either a development or distribution provisioning profile (didn't matter for me)
5. Go to settings on the iOS device and log out of the App Store
6. Start your App, try to purchase the non-consumable, enter your test user's username and password.

I did not need to mess around with uploading binaries or anything else. I based my IAP library code off of the lemonade example.

For the restore question. There are two forms of restore. Let's call them:

1. Restore-on-demand
2. Restore-on-purchase

For restore-on-demand, either the App automatically "restores", or provides a button for the user to do so. In this case, store.restore() is used. No parameters or arguments are passed. You will automatically receive a transaction callback (one at a time) for each item already purchased by the user as a "restored" purchase.

For restore-on-purchase, when the user attempts to purchase a non-consumable item they already own, iTunes will tell them they do not need to pay again, and you will receive a transaction callback for that non-consumable item as a "restored" purchase.

Good luck :)

This is so weird! Absolutely none of these things are working for me :-/
Is there any chance that my store.init() (in my code above) isn't actually getting called? Or maybe it'll start working once the App is actually on the store?

Thanks for everybody's help!
Logan

I see one thing in your code that I don't like: no debug statements. I don't remove mine until something is 100% working (if at all).

Normally, you can do this with print statements, but for device only features (e.g. IAP) you can use alerts. Place them at the beginning and end of each function so you can see what is being called and what is not. Once you know that, the answer should come more easily.

Hey, lhvio89, I had trouble with IAP. My problem was with not building the device build using AdHoc certificate to test IAP against iTunes Connect sandbox -- as soon as I installed AdHoc build, mine worked fine. I don't know what might be causing a problem for you, but take a look at this thorough walk-through. There maybe some steps you are missing:

http://troybrant.net/blog/2010/01/in-app-purchases-a-full-walkthrough/

Plus the accompanying checklist for invalid product id (if you ever get the invalid product id warning):

http://troybrant.net/blog/2010/01/invalid-product-ids/

Also, the example code supplied by d3mac123 helped me out. Maybe it could help you too? Here's the link:

https://developer.anscamobile.com/forum/2011/10/13/app-purchases-help-needed#comment-60894

Good luck!

Naomi

@Naomi - Thanks for those links...I actually followed those guides getting to where I am now, and I am definitely using an Ad Hoc build, with no luck :-/

@blasterv - Yeah, I know...I get lazy with that sometimes. But I threw in some alerts, and it seems like everything is getting called as it should be. Still getting that same "Cannot connect to iTunes store" error. (Which is being thrown by the transaction.state == "failed" part of the transaction callback function.

Any other suggestions? :-/

Have you set up pricing and availability for your IAP?

Yep, that's all been set up in iTunes Connect since a couple of days before I started this thread. But, now, I just tried something that makes me think that it's something odd with my code. I added a restore button, and it calls the store.restore() function. And when I try that button, I get the login prompt. So it seems like maybe there is something wrong with the way I'm calling store.purchase()?

(Also, what is supposed to happen after a failure to restore a purchase? Should it throw the "failed" state error of the callback function? Because if so, then maybe my excitement at getting a login prompt for store.restore() is a bit premature...I get no transaction failure message.)

Thanks so much everybody...I really, really appreciate all this help!
Logan

Your call to store.purchase is in the same format as mine. It looks good to me.

I'm grasping at straws now... what device are you trying this on? what OS is it? what build of Corona are you using?

I'm testing it on both an iPad (running 5.0.1) and an iPhone 4 running the 5.0.1 beta. And I'm using build 671.

Bah, this is so weird!

views:2687 update:2011/11/26 9:01:35
corona forums © 2003-2011