In-App Purchase failing in iOS 9 after payment update

We have had many users reporting that they have paid for our product via in-app purchase but we have failed to unlock the content. The common denominator between these reports is iOS 9. We have offered IAP for years and haven't experienced this issue until now.


We have found that the issue occurs when the customer is prompted to update their App Store payment information during the IAP process. This takes them out of our app. Then upon returning, the content is still locked. I was also able to replicate this by purchasing our product with a store build.


The Apple staff member in this related forum https://forums.developer.apple.com/thread/6431 indicates that the transaction will move to the a SKPaymentTransactionStateFailed when the user is directed out of the app to update their payment information. After updating their information, a SKPaymentTransactionStatePurchased is received. That forum suggests that finishTransaction should be called on the failed transaction. Then, finishTransaction should be called again after SKPaymentTransactionStatePurchased is received and the content is unlocked. This is what we have been doing for a long time but this doesn't appear to be working with iOS 9. It seems that we are only getting a call for the change to SKPaymentTransactionStateFailed but not for a subsequent SKPaymentTransactionStatePurchased. I can't guaruntee that we are not getting the state SKPaymentTransactionStatePurchased call as we can't use the debugger with our store builds but our code is simple enough to say this is very likely


Here is a simplified version of our code:


- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{
  for (SKPaymentTransaction *transaction in transactions)
    {
        switch (transaction.transactionState)
        {
            case SKPaymentTransactionStatePurchasing:
                break;
            case SKPaymentTransactionStatePurchased:
                [self completeTransaction:transaction];
               [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                break;
            case SKPaymentTransactionStateFailed:
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                break;
            case SKPaymentTransactionStateRestored:
            default:
                break;
        }
    }
}


We would like to know if others are experiencing IAP issue with iOS 9? Also, is it correct to call finishTransaction after SKPaymentTransactionStateFailed? If we do, will we still receive another delegate call for SKPaymentTransactionStatePurchased?


Any help that can be offered would be appreciated.


Bill

Replies

You shoudl also check your code for removeTransactionObserver and be sure that if you are calling that you are also allowing the user to call addTransactionObserver as an option (e.g. "Check for purchases") or the next time your app enters foreground or launches. It is possible the user is sitting there without a transaction observer and StoreKit is patiently waiting for addTransactionObserver.

Good idea but we don't we use that method. Our observer is a singleton that persists through the entire app lifecycle.


Since I posted this, I also replicated this issue with 2 popular apps in the app store not associated with our app (I only tried 2). In-app purchase content didn't unlock although my iTunes account was charged.


We are trying to determine if this a widespread bug in iOS 9 or if something has changed affecting certain apps.

This seems consistent with the behavior we're seeing as well during credit card updates. Are you seeing further purchases succeed after the transaction where a credit card update is required?

Further purchases seem to succeed for us once the credit card is updated but the one made during the update is lost.

Yep, we are seeing the same thing.


Almost exactly the same thing happened a little less than 2 years ago:


https://devforums.apple.com/message/926286


Hopefully Apple will find and fix the problem soon. Of course, it is unlikely that Apple will ever acknowledge that the problem is happening, or that they have fixed it, since Apple is institutionally incapable of effectively communicating with developers.

We have been facing the same issue ever since iOS 9 rolled out.
We have around half a dozen really angry customers who were charged but could not buy our In App Purchase items.

Most (all but 1) of the plaintiffs are on iOS 9.0.1.

Before this, for over a year we never faced any issues regarding In App Purchases.


We are receiving Transactions in the state SKPaymentTransactionStateFailed and are simply finishing them like we always used to, and like the apple documentation tells us to. Sadly, we never receive the transaction in the state SKPaymentTransactionStatePurchased even though the user has been charged. These are legit users and are sharing their credit card statements to prove their point.


Another issue that we are facing with In App Purchases on iOS 9 is that we are receiving an empty in_app array in the iTunes receipt received in :

paymentQueue:updatedTransactions:
//Using :
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];


Is someone else also receiving empty in_app arrays i.e. in_app = [] in their itunes receipts?

Another day of waking up to multiple emails from annoyed customers about problems with their in-app purchases.


Good thing the the App Store status is green and there are no reported problems:


https://www.apple.com/support/systemstatus/

Do you have any references that transactions in SKPaymentTransactionStateFailed should be finished? I could not find anything directly stating that. I'd like to include that in my Radar report if available.

The last line orn this page states that you must finish a failed transaction. (It overstates the case because you do not need to finish 'purchasing' or 'Deferred' but ot c;early indicates you must finish a 'Failed'.)


https://developer.apple.com/library/prerelease/ios/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/DeliverProduct.html#//apple_ref/doc/uid/TP40008267-CH5-SW3

Thanks for this. I'll include this reference in our Radar.

The Apple bug report # for this filed case is 22871139. If you also file a radar, please reference that to possibly bump the issue in priority.

Same problem for us. Any new on this?

Experiencing the same issue. Filed rdar://22940215 and referenced your radar # in it. Fingers crossed.

Some of our users has got this issue too. Does ios 9.0.2 fix it ?

I've looked that the bug report and it's being investigated by the iTunes Production Support staff. I'm wondering whether there is an issue with the update process after an initial transaction response has been initiated (which in this case was the failedTransaction notification) Do any of the production apps discussed here have a simple means to ask the user to refresh the receipt - a restore won't work since a restore only restores acknowledged transactions, but if the receipt is refreshed, the current purchase should appear in the application receipt.


Of course this raises the issue, when the app transitions from the background to the foreground with the transactionObserver active, why isn't the updatedTransactions dlegate mathod being called regarding the "incomplete" transaction.


When I have time later today, I'm going to try and replicate this issue with the StoreKit profile active and submit my own bug report.


rich kubota - rkubota@apple.com

developer technical support CoreOS/Hardware/MFI