In App Purchase - can get product info but can't connect to itunes for purchase - iphone

I'm trying to make "In App Purchase " works in my iphone app.
I created some products and a few test accounts in itunes connect.
I have no problem to retreive the products data (prices etc..) but when I try to make a payment
- I am asked to log in
- I use a test account
-> the transaction always fail with the following error :
failedTransaction with error : Error Domain=SKErrorDomain Code=2 "Connexion à l’iTunes Store impossible" UserInfo=0x65d02a0 {NSLocalizedDescription=Connexion à l’iTunes Store impossible}
I tried with several products and test account (even in other stores like us) but I still get the same error...
NB : I think it worked fine the first time I tried but never still
Any idea will be welcome !
Thanks

For me, I just scoured my code until I found my mistake. I was so certain everything was fine, but it was not. When I requested product information from the store, I used the correct Product Identifier:
self.productRequest= [[[SKProductsRequest alloc] initWithProductIdentifiers: [NSSet setWithObject: #"com.popculturesoft.RC_vCar.fullVersion"]] autorelease];
However, when I went to create the payment, I used the incorrect Product Identifier:
SKPayment *payment = [SKPayment paymentWithProductIdentifier:#"com.popculturesoft.RC_vCar_Lite.fullVerson"];
Using the product Identifier for the payment is not the correct way to do it, although it allows you to do it. It is better to use an SKProduct object. (I had set the fullProduct property earlier in the code:
SKPayment *payment = [SKPayment paymentWithProduct:self.fullProduct];
I was absolutely certain that the store was down, and that was the problem. But the next day I decided to start from the beginning of the process, as described in http://developer.apple.com/library/ios/#technotes/tn2259/_index.html. This is when I found that my incorrect Product Identifier was the problem.

Check out this thread. It seems to be a problem with the Sandbox. Lot's of people having this issue-
iPhone storekit sandbox stopped working

I had the same symptoms and in my case the problem was that I had a test user account with the same name as a real Apple ID account. I resolved the problem by creating a different test user account.

Related

Adding Aviary In-App Purchases iOS

So I have tried to add Aviary's IAP purchases and have had little luck getting them to show up in my application. I have not made sure that following has happening
My Provisioning Profile being used to build the application has IAP's turned on
I have uploaded all of Aviary's IAP's to itunes connect
I have added the required code for IAP's in my app delegate:
[[AFPhotoEditorController inAppPurchaseManager] startObservingTransactions];
[AFPhotoEditorCustomization enableInAppPurchases:#YES];
Before I start my photo editor session I add the following code
AFPhotoEditorController* photoEditor = [[AFPhotoEditorController alloc] initWithImage:imgToBeEdited];
[AFPhotoEditorCustomization enableInAppPurchases:#YES];
mPhotoEditorSession = [photoEditor session];
editorController = photoEditor;
[photoEditor setDelegate:self];
They are not showing up at all and I am uncertain of what Aviary is taking care of and what I should be taking care of
I think it might have to do with this line in the documentation:
Add the following lines to your app delegate's -applicationFinishedLaunchingWithOptions: method before invoking any StoreKit framework methods:
[[AFPhotoEditorController inAppPurchaseManager] startObservingTransactions];
This line adds the in-app purchase manager singleton as an observer of the StoreKit payment queue returned by [SKPaymentQueue defaultQueue], and sets a flag enabling in-app purchase code throughout the SDK.
Has anyone added this to their application and let me know what Storekit methods I need to invoke? Any sample code is helpful.
thanks in advance!

In-App Purchase test fails on IOS 4.01, works on iOS 5+

This is driving me crazy.
I'm trying to debug an App that uses In-App Purchase.
I use the following simple piece of code to get my products (I've got only one product):
NSSet *productIdentifiers = [NSSet setWithObject:PRODUCT_ID];
SKProductsRequest *request = [[[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers] autorelease];
request.delegate = self;
[request start];
On devices running iOS5 and above, I get my product back in the response.products property of productsRequest:didReceiveResponse:. I can also place an order (using a test user) on these devices.
On a device running iOS 4.01, I get an empty array in response.products and my product id in response.invalidProductIdentifiers. If I try to ignore the product information and call addPayment: on this device using the same product id, I'm getting SKPaymentTransactionStateFailed in paymentQueue:updatedTransactions:.
Obviously my setup is correct, since things work flawlessly on my iOS5+ devices.
I also checked and tried everything in http://troybrant.net/blog/2010/01/invalid-product-ids/ to no avail.
Any ideas? Do you think it's safe for me to submit the App under this situation?
This right here helped me out when I was debugging a similar problem - http://teewe.com/2011/10/24/ios-in-app-purchase-programming-troubleshooting-guide-continuously-updating/

In-App Purchases: Stuck at paymentWithProductIdentifiers - which is deprecated

I am stuck with setting up my in-app purchases.
I can't get to get this right:
SKPayment *paymentRequest = [SKPayment paymentWithProduct: #"co.za.nideo.100shotsbuybeer"];
I got it from
SKPayment *paymentRequest = [SKPayment paymentWithProductIdentifiers: #"co.za.nideo.100shotsbuybeer"];
but this seems to be deprecated. How can I get the first piece of code to work?
It seems to nee a SKProduct but I don't know how to create/init such an object.
According to the StoreKit docs and [1] you'd have to:
Create an SKProductsRequest with your product identifiers (initWithProductIdentifiers:)
Set yourself as the delegate
Send this request to Apple (start method)
The Response will call your delegates productsRequest:didReceiveResponse: which contains an SKProductsResponse object
You extract the SKProduct objects from the products property and display them, saving the objects for further purchase.
This seems in line with Important: You must make a product request for a particular product identifier before allowing the user to purchase that product. Retrieving product information from the App Store ensures that you are using a valid product identifier for a product you have marked available for sale in iTunes Connect. from [1]
[1] http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/StoreKitGuide/RetrievingStoreInformation/RetrievingStoreInformation.html#//apple_ref/doc/uid/TP40008267-CH2-SW1

iPhone: Cannot test InAppPurchase in sandbox after it is approved

I have a free iPhone App which uses in app purchase. I tested my first InAppPurchase with sandbox environment and it worked fine. After the InAppPurchase was approved and worked fine in App store, I added several new InAppPurchases in iTunes Connect and tried to test them in the sandbox environment. However I could not find these new InAppPurchases in my app.
The following is the code I uses to get InAppPurchase products:
//....
SKProductsRequest *prodRequest= [[SKProductsRequest alloc] initWithProductIdentifiers:
[NSSet setWithObject: prod]];
prodRequest.delegate = self;
[prodRequest start];
//....
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
int count = [response.products count];
NSLog(#"number of products:%d",count);
for (int i=0; i < count; i++) {
SKProduct* product = [response.products objectAtIndex:i];
NSLog(#"product %d:id=%# title=%# desc=%# price=%#", i, product.productIdentifier, product.localizedTitle,
product.localizedDescription,
product.price);
}
}
If I use the old InAppPurchase product id I can get it, but if I use any newly created product id I got count==0.
From what I saw, I guess may app may not be running in the sandbox environment after my first InAppPurchase was approved, but this is just a guess, because I don't know how to check if my app is in sandbox mode or not.
I searched Internet about this issue and tried the following:
1. created a new version of my app, uploaded it to iTunes connect, and rejected the binary. no use
2. deleted all my provisioning profiles and created new ones. no use
3. created an app id for my app in developer provisioning portal and created provisioning profile for that id and used it in Xcode. no use
My Xcode version was 3.2.5. I upgraded it to 4 but this did not fix the problem.
I am wondering if any one else has seen this issue and found a solution. Thanks.
OK I came across this post and got some hint:
Product Identifiers Are Valid On One Phone But Not Another
I just deleted the app from my iPod Touch, did not reboot, then tried to run my app from Xcode again, and it worked. I guess there was some states saved together with the app which determines whether to use sandbox environment for InAppPurchase or not. Although I could run my newly compiled binary without deleting the old app, I could not get rid of some old state which caused the app not running in the sandbox environment. That is what caused the problem. The solution is to delete the old app from the device before running newly compiled binary.

iPhone consumable product is behaving like a non-consumable product (already purchased...)

Our app has a list of locked products that share the same consumable product id (i.e. one consumable product id for many products). Our server provides me with a list of products and the product id associated with them:
item name="itemA" iphoneProductId="consumable.test.1"
item name="itemB" iphoneProductId="consumable.test.1"
item name="itemC" iphoneProductId="consumable.test.1"
We chose consumable because our items are created dynamically and need to be available to the user instantly (please don't reply suggesting that we use non-consumable, there are a lot of other reasons that are too hard to explain without me giving away private details about the company we are working with, as to why we are using consumable). This allows us to have multiple products share the same price.
When the user purchases itemA (for example), the item is unlocked. However, sometimes, when the user then tries to be itemB, Apple return with 'You have already purchased this but it hasn't been downloaded. Tap OK to download it now’. This should surely never happen for a consumable item. I know our system is quite complex but as far as the apple store kit is concerned, are simply just buying the same product again.
Could this just be a sandbox issue? We can't test in live as the app isn't released yet. In fact, this whole problem is holding off the release as our client is as concerned as we are about this problem.
I've followed the same code from the iphone documentation and the few in app purchase tutorials out there. I see that a lot of people on the forums seem to have witnessed the 'already purchased' dialog above for consumable products, but none of them ever get answered.
Please help! Thanks
The problem is that you are never finishing the transaction. You need to remove it from the queue.
Like:
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
I'll assume you've called -[SKPaymentQueue finishTransaction:].
Off the top of my head, there are a few possibilities:
The store hasn't received the "finish" message yet (I don't know what ordering guarantees there are).
You're trying to purchase a second item before calling finishTransaction: on the first, and the App Store thinks it's a replay.
The App Store detects when you appear to be purchasing the same item repeatedly, and assumes that something must have gone wrong.
A hack is to cycle through a list of several (10? 100?) consumables, assuming that when you get back to one earlier in the list, it will have finished processing.
An alternative solution is to pre-allocate a lot of non-consumables ("product.1", "product.2", ..., "product.100") and assign ones with the appropriate price to products on the server. Changing prices can then be done on iTunes Connect, or by assigning additional product IDs as necessary.
Thanks for your quick response, but my app does seem to be finishing the transaction, etc.
My project's in app purchase classes have become quite complex so I reverted to creating a new basic project with a test consumable product and the standard implementation of in app purchase manager/observer taken from this open source:
http://blog.mugunthkumar.com/coding/iphone-tutorial-%E2%80%93-in-app-purchases/#idc-cover
The same problem occurs. This is the order:
1. Buy the consumable product for the first time (below is the debug I printed out)
_MKStoreManager: buyFeature:test.consumable.1
__MKStoreObserver: SKPaymentTransactionStatePurchased
__MKStoreObserver: completeTransaction
_MKStoreManager: provideContent
2. "Thank you for your purchase" dialog is displayed by Apple
3. Buy the consumable product for the second time:
_MKStoreManager: buyFeature:test.consumable.1
__MKStoreObserver: SKPaymentTransactionStatePurchased
__MKStoreObserver: completeTransaction
_MKStoreManager: provideContent
__MKStoreObserver: SKPaymentTransactionStateFailed
__MKStoreObserver: failedTransaction
4. "You've already purchased this but it hasn't been downloaded. Tap OK to download it now. [Environment: Sandbox]" dialog is displayed by apple.
It just doesn't make sense in step 3 that the transaction is both purchased then failed at the same time. Do you have any ideas.
It is not worth using consumable product for non-cosumable, because Apple will reject it. Here is what happened to me:
I have had the same issue. The message explaining that you have already purchased the item appears only once in a while and mostly if you purchase a lot of things - one after the other immeadiately.
We have put it for review in the App Store anyway and got the following answer:
.....
We have completed the review of your in-app purchase but cannot post it to the App Store because the Purchasability Type is not set correctly. For information on Purchasing and Currency guidelines, please see section 11 of the App Store Review Guidelines [ https://developer.apple.com/appstore/resources/approval/guidelines.html ].
.....
The purchase of a [magazine issue] is set to "consumable", however based on product functionality it should be set as non-consumable instead.
.........
You are required to create a new in-app purchase product with the correct purchasability type.
..........
I hope this saves someone time and headaches.
I was facing the same problems. The mistake I did was deallocating the purchase before the finishTransaction was sent. Make sure you handle the transaction result after finishing the transaction
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
BOOL success = YES;
for (SKPaymentTransaction *transaction in transactions){
switch (transaction.transactionState){
case SKPaymentTransactionStatePurchased:
success = YES;
break;
case SKPaymentTransactionStateFailed:
if (transaction.error.code == SKErrorPaymentCancelled){
if(DEBUG) NSLog(#"Transaction failed => Payment cancelled.");
}else if (transaction.error.code == SKErrorPaymentInvalid){
if(DEBUG) NSLog(#"Transaction failed => Payment invalid.");
}else if (transaction.error.code == SKErrorPaymentNotAllowed){
if(DEBUG) NSLog(#"Transaction failed => Payment not allowed.");
}else if (transaction.error.code == SKErrorClientInvalid){
if(DEBUG) NSLog(#"Transaction failed => client invalid.");
}else if (transaction.error.code == SKErrorUnknown){
if(DEBUG) NSLog(#"Transaction failed => unknown error.");
}else{
if(DEBUG) NSLog(#"I have no idea.");
}
success = NO;
break;
case SKPaymentTransactionStateRestored:
success = YES;
break;
}
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
NSLog(#"transaction finished: %#", transaction);
}
if(success){
// do something
}
}
Hope that helps some of you.
Cheers,
K.
You should put this line [[SKPaymentQueue defaultQueue] finishTransaction:transaction] after the transaction over whether you are doing fresh purchase or restore purchase.
[[SKPaymentQueue defaultQueue] addTransactionObserver:observer];
make sure you have added this method on the controller handling requests.