In-App Purchase restore fails in iOS 9

Hello


We have number of apps running fine on various iOS versions. In past few days we are receiving complaints from our customers that they are unable to restore In-App purchases in iOS 9.


Please comment if anyone else is facing the similar issue for their apps? Is there any known bug regarding the restoring of In-App purchases in iOS 9?


Thanks!

If you can replicate this problem yourself, I'd submit a bug report - https://bugreport.apple.com. If you do, please send me the bug report number so that I can forward it on to StoreKit engineering for their review.


rich kubota - rkubota@apple.com

developer technical support CoreOS/Hardware/MFI

Hi Rich


Thank your for your swift response. I am testing my app in Xcode 7 Simulator (iPhone iOS 9). I am getting the error while trying to purchase/restore the product under the method restoreCompletedTransactionsFailedWithError with error "Cannot connect to iTunes Store". I am able to fetch localizedTitle, localizedDescription, price and productIdentifier with SKProduct object but the purchase seems to be failing for me. There isn't any error/warning message in the console while purchasing the in-app purchase.

P.S. I have logged in with the Sandbox Apple ID. I have also reported this problem in Apple Bug Reporter. The Bug ID is 22391271.


Thanks!

Are you able to replicate this issue on an actual device with iOS 9 installed. The StoreKit API hasn't been supported on the Xcode simulator for a while now (Xcode 5 and newer). Keep in mind that Apple does not support restoring iOS to an earlier version on a device, so limit the install to one device for test purposes. In a quick test I did with the StoreKitSuite sample code, I did not find an issue with the purchase or restore process.


rich kubota - rkubota@apple.com

developer technical support CoreOS/Hardware/MFI

Hey There, I have the same problem.

It would help to have additional details. Does this problem happen to all users who have upgraded their devices to iOS 9? Or does the problem happen to a select group of users? Are you able to replicate this problem with the production store version of the app? Are you able to obtain the console log from the device taken at the point that the restore process fails?


For the most part, In-App purchase applications continue to work as expected under iOS 9. If this problem is unresolved you may have to submit for help with Developer Technical Support.


rich kubota - rkubota@apple.com

developer technical support CoreOS/Hardware/MFI

We're having a similar problem with purchases themselves. While purchasing works in sandbox mode, it's now frequently failing in the live purchasing environment (though some users are still able to make successful transactions). The behavior we see is that the user goes through the standard purchasing flow, but that the transaction observer we set up gets a response code of SKPaymentTransactionStateFailed (with error code 0). Looking at iTunes transaction history of the purchasing user shows that the transaction apparently went through.


While this could certainly be the result of something we've done wrong in our implementation, I'm not sure how we'd test a fix if it already works in sandbox mode. I've opened a ticket relating to the above issue and included a partial log dump. Hopefully that will help track things down.

When I hear reports of users being charged, but the application not providing content, this tells me that the app is being called via the updatedTransactions delegate method with a successful purchase indication, and the app is making the decision to provide or not provide the content. The number one reason for such discrepancy lies in receipt validation. Since the problem doesn’t happen to all customers, the most common reason is that the receipt validation process is incorrectly encoding the hex receipt into base64. This can be observed when the receipt validation process returns status error 21002.


You also indicated - "The charge only appears once, however - presumably the purchased product is not being consumed, and thus the user can not purchase the product a second time.” Which leads me to believe that because the content is not provided, the app doesn’t make the finishTransaction call (which is the right thing to do) leaving the transaction incomplete. The next attempt to purchase the item will result in an dialog that states you’ve already purchased the item and do you want to try again (something like this).


This is all a guess based on past experience. Looking at the log may help if the app logs the in app purchase progress. As for base64 encoding the receipt, I recommend what is shown in the Receipt Validation PG


NSDictionary *requestContents = @{

@"receipt-data": [receipt base64EncodedStringWithOptions:0]

};


Rather than doing your own custom algorithm. The above NSData method is iOS7 and greater.

rich kubota - rkubota@apple.com

developer technical support CoreOS/Hardware/MFI

I understand what you're saying, but in these cases we're never getting to the receipt validation step because the transaction object itself is reporting purchase failure (SKPaymentTransactionStateFailed) rather than success (SKPaymentTransactionStatePurchased). We only send the receipt-data off to our back-end server for validation if we receive a success code (which we're retrieving directly from the SKPaymentTransaction object). Or have I misunderstood your response?

One thing that can happen in production is the user submitting a purchase request and needing to update their credit card information. After they update their credit card information they can then go through with the purchase. In this case StoreKit sends the device two seperate transactions in rapid succession; a fail and then a purchase. If your app closes the transaction observer immediately after the fail then it will not see the purchase until the next time the user adds a transaction observer. There are various ways to handle this. One is to leave the transaction observer open all the time. A second is to give the user an option of openning a transaction observer like 'Check for purchases'. A third is to delay for a few seconds closing the transaction observer after a failed transaction. If your app does none of these then perhaps this is your problem.

Understood - in our case, we're leaving the transaction observer alive for the lifetime of of the app's execution. Thanks for the suggestion.

Hello

did this solved your issue yet ?

We run into big trouble since our large IAP shop CoachGuitar encounter a dramatic buying rate hole ( from 50 % since start buy to real buy IAP, to 25 % ).

And we cannot see why !

Very frustrating,

Julien

Hello

Is there anything new about this issue?


I'm having the same trouble as rbixby.

We're having a similar problem with purchases themselves. While purchasing works in sandbox mode, it's now frequently failing in the live purchasing environment (though some users are still able to make successful transactions).


I have no idea why this is happening, and I need some more information.

Is there any update on this? I see the same issue here. Consumable IAP works fine on iOS=9 user gets billed, but content is never delivered (consumed), like the observer dies or something. Then a zombie (unfinished) transaction remains, popping up the credentials screen but never clears the queue, that is the worst case scenario: user is billed, does not get content they paid for and cannot even try again because the "iap purchased restored for free" dialog pops up, which is does not make any sense, since it's a consumable IAP. Fact is that something got broke on Storekit iOS 9. Worked great on previous iOS versions, and still does. On iOS9 it fails... What can we try to do and solve this?

Is there any update on this? I see the same issue here. Consumable IAP works fine on iOS older than 9, but, on iOS 9 or newer, user gets billed, but content is never delivered (consumed), like the observer dies or something. Then a zombie (unfinished) transaction remains, popping up the credentials screen but never clears the queue, that is the worst case scenario: user is billed, does not get content they paid for and cannot even try again because the "iap purchased restored for free" dialog pops up, which is does not make any sense, since it's a consumable IAP. Fact is that something got broke on Storekit iOS 9. Worked great on previous iOS versions, and still does. On iOS9 it fails... What can we try to do and solve this?

If the "iap purchased restored for free" dialog pops up, this is a good indication that the updatedTransactions delegate method is being called with a successsfulTransaction notification. Assuming this, then the next question is how is the app handling this case. In my experience, many apps that report a similar issue, perform receipt validation. If this is the case, the I'd look at the validation process. If the updatedTransaction delegate method is being called with a successfulTransaction, the StoreKit has completed the purchase process and has notified the app that the app can make the iAP content available. For some reason, the app encounters a problem and does not call finishTransaction. I'd inspect the code path from the updatedTransactions call to when finishTransaction should be called.


If this is not the case, it would help to have additional details as to what is happening - does the console log show anything??


rich kubota - rkubota@apple.com

developer technical support CoreOS/Hardware/MFI

In-App Purchase restore fails in iOS 9
 
 
Q