17

I'm trying to add in-app purchase to my app, following the techniques described here :

Introduction to In-App Purchases in iOS 6 Tutorial

I've added a product via itunes connect, which has an id set up like this:

com.mycompany.myapp.myproduct1

The bundle id (specified in the p-list and also on the app store) is set up like this:

 com.mycompany.myapp

I'm using the helper class from the tutorial, IAHelper, to handle the purchase functionality (relevant code shown below). It also has a subclass which is essentially used to add the id of the in-app product(s) to the IAHelper's array of products ids.

In order to test the code, I created a button labeled "show products" which calls this method:

- (IBAction) showProducts {

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(productsLoaded:) name:kProductsLoadedNotification object:nil];

    Reachability *reach = [Reachability reachabilityForInternetConnection]; 
    NetworkStatus netStatus = [reach currentReachabilityStatus];    
    if (netStatus == NotReachable) {        
        NSLog(@"No internet connection!");        
    } else {        
        if ([InAppMyAppAPHelper sharedHelper].products == nil) {


            // here's where it calls the helper class method to request the products
            [[InAppMyAppAPHelper sharedHelper] requestProducts];

            self.hud = [MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES];
            _hud.labelText = @"Loading vocabulary...";
            [self performSelector:@selector(timeout:) withObject:nil afterDelay:30.0];

        }        
    }

}

This is the method to request products from iTunesConnect, called above:

- (void)requestProducts {

    self.request = [[[SKProductsRequest alloc] initWithProductIdentifiers:_productIdentifiers] autorelease];
    _request.delegate = self;
    [_request start];

}

(Note that the variables preceded by "_" refer to the actual variables of the same name sans the underscore per several synthesize statements)

Finally, this is the method (in IAHelper) that gets notified when the response is received:

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {

    NSLog(@"IAHelper, received products results...");   

    self.products = response.products;
    self.request = nil;    

    // Here's the loop to list the products received
    for (id product in _products){
        NSLog(@"IAHelper, received product is: %@", product); 
    }


    [[NSNotificationCenter defaultCenter] postNotificationName:kProductsLoadedNotification object:_products];    
}

In the above, the log statements show the method is called, but the loop to print the received products doesn't list anything.

So it looks as if it's not finding the product in iTunes connect. Yet, I've set up a product there, and the id of the product is the same as the bundle id, plus the product identifier, i.e.

bundle id:  com.mycompany.myapp
product id: com.mycompany.myapp.product1

I've checked that several times.

I noticed that iTunes lists the status of the ad-in product as "ready to submit". Is there an additional step I need to make to make it available?

Overall, what am I doing wrong?

Umair M
  • 8,566
  • 3
  • 33
  • 67
Jack BeNimble
  • 33,194
  • 33
  • 113
  • 187
  • I had same issue, In my case both catch and then section were executing, dont know why. I was testing in simulator. Testing in real devices works as intended – Khim Bahadur Gurung Dec 22 '20 at 12:02

10 Answers10

46

I run into the exact similar problem. Here are some steps that needs to be adressed/checked after reading this technical note from Apple:

  • Create a unique App ID
  • Enable in-app purchasing for this App ID
  • Generate and install a new provisioning profile on your device
  • Update the bundle ID and code signing profile in Xcode
  • Check that your project’s .plist Bundle ID match your App ID
  • Complete your contract, tax, and banking Information. You need a VALID contract

As mentioned by the official doc there is NO need to submit binaries neither submit screenshot of in-app purchase. I have seen a lot of missleading info about this on various blogs.

After checking you have addressed each point in this list, delete your app and reinstall it.

I was basically missing two things on my side: setting up correctly my contract for ios Paid app and i didn't install the new provisioning profile on my device. May be that was your issue?

tiguero
  • 11,171
  • 5
  • 41
  • 61
  • 6
    Valid contract. That was my problem... :( – JP Illanes Jul 27 '15 at 02:12
  • made all from this list, and much more from other discussions. I thought it was my provision profile, but after fight with certificate hell, have same result... – Dima Deplov Sep 03 '15 at 22:30
  • 1
    I'm trying for sandbox testing at the moment, is this mandatory for contract, tax, and banking Information Valid. my current status pending... – Rajesh Jul 14 '16 at 16:08
  • 3
    Hope they fire the stupid ass that thought "valid contracts before testing IAP". – elemento Dec 18 '18 at 02:59
2

Getting no valid products returned in productsRequest:didReceiveResponse is a well known issue. There are many reasons, some given in TN2259 especially FAQ#6. Usually the problem is that the app is not directing itself towards the sandbox. Often that is because the developer did not do these 3 things in order: 1) delete old builds of the app (delete, not overwrite) 2) log out of the app store on the device using the settings app 3) run the app from Xcode on a device (not a simulator) and log into the store using a test user only when asked by the app store.

Peter B. Kramer
  • 15,751
  • 1
  • 14
  • 19
1

I have same problem while i m testing application on simulator.Try it in Device and its work for me.

Harin
  • 867
  • 11
  • 23
1

I had the same issue. I filled the agreement for in app purchase, complete your contract, tax, and banking information so you have a valid contract. Also I added screenshots to the sections (App Store Promotion (Optional) and Review Information even though its says optional) in App Store Connect (in app purchases). Make sure your products in In-App Purchases have status Ready to Submit. Finally after that I got products.

Anita
  • 1,381
  • 15
  • 21
0

I had a similar problem. I used code that was working in another app for IAPs so it should have been working, but I was getting an Invalid Product ID error and no results received. It turned out that it was a timing issue. I was trying to process the returned products before they'd been returned to the app, so the error was terminating the app before the products had time to be loaded! My program logic was:

  • User opens store view & IAP products are loaded
  • A UITableView is loaded with a list of the products (but from a locally held array)
  • The user clicks the buy button on a table cell - if this happens too quickly, the actual products haven't been returned yet - app crashes

Answer for me was to build the table from the returned products (should have been obvious to me in the first place!) so the user couldn't continue until they had been loaded correctly

JanB
  • 864
  • 9
  • 14
0

Answer for Swift projects with same error:

My error was here:

//identifiers: [String]
let productIDs = Set(arrayLiteral: identifiers) as Set<NSObject>!
let request = SKProductsRequest(productIdentifiers: productIDs)

But this code will lead to an error with code = 0 message Cannot connect to iTunes Store. Let's look to the SKProductsRequest input argument type:

SKProductsRequest(productIdentifiers: Set<NSObject>!)

So, code above looks legit. But it doesn't! Swift Set is the problem, considering that in input argument we see Swift Set!

Found the answer while iterating some IAP lesson. Here is the working code:

let productIDs = NSSet(array: identifiers)
let request = SKProductsRequest(productIdentifiers: productIDs as! Set<NSObject>)

You must use NSSet for now, although Swift Set is already available and it's set as input argument type! Looks like a bug for me, I'll fire a bug.

Dima Deplov
  • 3,538
  • 6
  • 41
  • 73
0

We were stuck a while with the same problem trying to run it on the simulator.

After try it on a real Apple TV device (connected via USB) we started getting valid product IDs.

Then you only have to request the payment of one of these products on your code and you should be able to be requested to authenticate (with a sandbox user) and approve your purchase on the Apple TV.

Ricardo Barroso
  • 364
  • 5
  • 8
0

If you're following Apple's documentation you may end up in the same boat as me. If you're setting up for sandbox testing you need to make sure that the .storekit file is not set. Apple's documentation is a bit involved with this and it does ask you to do this under the section "Enable StoreKit Testing in Xcode"

Follow these instructions but make sure that StoreKit Configuration is set to None

Source: https://developer.apple.com/documentation/xcode/setting_up_storekit_testing_in_xcode#3625696

Scott
  • 1,068
  • 1
  • 11
  • 24
-1

I think I may have found the answer here.

This wording from the in-app purchase web page led me to it:

The first In-App Purchase for an app must be submitted for review at the same time that you submit an app version. You must do this on the Version Details page. Once your binary has been uploaded and your first In-App Purchase has been submitted for review, additional In-App Purchases can be submitted using the table below.

What you can do to get around the catch-22 of not wanting to submit an app for review when you haven't tested the in-app purchase code is to submit it for review, and then immediately reject it on your own. This gives it a status of "developer rejected".

Than you can add your product, According to the blog,

After saving the product, just choose the “Submit with app binary” option. This will tie the product to the app binary, so when you finally submit the 100% complete app binary, the product will be submitted as well.
Jagat Dave
  • 1,633
  • 3
  • 22
  • 30
Jack BeNimble
  • 33,194
  • 33
  • 113
  • 187
  • 4
    This statement from the blog you are mentioning is outdated or incorrect. As per mentioned by the official doc: http://developer.apple.com/library/ios/#technotes/tn2259/_index.html: Testing In-App Purchase does not require uploading a binary. – tiguero Jul 29 '12 at 07:41
  • The technote even says that you SHOULD NOT UPLOAD a binary. If it is rejected, or developer rejected, you need to have an app approved before you can test again!! – Joris van Liempd iDeveloper Dec 14 '12 at 14:33