Auto-renewing subcription fails in production environment

We're experiencing a very strange behaviour after purchasing auto-renewable subscription.


Basically, after submitting purchase request, our app listens to SKPaymentQueue events until it encounters an SKPaymentTransaction with matching product ID. Then, it submits receipt to our server for validation/activation. And only after that [SKPaymentQueue finishTransaction:] is called - to ensure that user can resume validation/activation later in case of failure.


It works pretty well in sandbox environment (including resuming interrupted purchases). However, in production, while non-auto-renewable purchases work fine, auto-renewable do not. What happens is that user sees a successful "You're all set" message, but in the same time, app receives transaction update with SKPaymentTransactionStateFailed and cryptic "Cannot connect to iTunes Store" error. The strangest thing is, due to the error, validation request to our server is not made and, thus, [SKPaymentQueue finishTransaction:] never called, but, still, transaction magically finalizes itself (does not appear in pending transactions list, but appears in user's subscriptons list).


Is it a known problem? Any ideas where to dig?


Thanks,

Dmitry

Replies

Ask yourself how your code handles getting two transactions in a row - one 'failed' (because the user needed to update their credit card information) and the next 'purchased' (if the user made the purchase after updating their credit card information). It should finish the 'failed' transaction and then receive the 'purchased' transaction. Code that shuts down the transaction observer after getting that failed transaction are ignoring a transaction in the queue - the app needs to execute an addTransactionObserver

Yes, I was thinking about something like this (multiple events), but it doesn't fit our situation:

- Payment is confirmed via TouchID.

- Store view controller always actively listens to payment queue events and all "unrecognized" transactions are stored in "pending transations" array, from which user can select any to resume validation/activation on our server. In our case, it's empty.

- From my experience with sandbox mode, all "purchased" transactions, which were not finalized, will stay in payment queue forever, even after app restarts (so they can be resumed). In our case, there's nothing in the payment queue, meaning even if there is subsequent successful transaction, it gets magically finalized by itself.

>validation request to our server is not made and, thus, [SKPaymentQueue finishTransaction:] never called, but, still, transaction magically finalizes itself (does not appear in pending transactions list, but appears in user's subscriptons list).


Check your code: "still, transaction magically finalizesI" when combined with "nothing magical happens" suggests your code is not handling the two transactions correctly. I suspect that you are calling finishTransaction on the 'purchased' transaction and not making a request to your server because the previous transaction is 'failed'. Both need to be 'finished'.

I'm following the official guides thorougly: finishTransaction is called on every failed transaction and the only other finishTransaction call is in callback from successful request to our server (I'm 100% sure finishTransaction is not called before "products are delivered", i.e. transaction is validated on our server).
Another thing to note is that non-auto-renewing (consumable) purchases work fine, so I presume it's not about payment flow implementation, but some pecularity about auto-renewing vs non-auto-renewing or just an Apple bug.

Hi, whatever happened with this?

We're experience pretty much the same exact thing.


Thanks!

I have a DTS incident where this same set of symptoms has been reported. I've asked the developer to install the StoreKit profile, then capture a console log taken when the app is launched and the problem replicated. I will then review the contents of the console log to understand the sequence of StoreKit events. However, unless I find some basic fault with the StoreKit responses, this would not be something I would discusson the forum. If you want to submit for a DTS incident, I'd be happy to investigate your issue.


FYI, here's the instructions on how to install the StoreKit profile and to capture the console log.


Here are the instructions to install the StoreKit profile

Install StoreKit profile to an iOS 11+ device

Please login to the Apple Developer Bug Report - Profiles and Logs website

<https://developer.apple.com/bug-reporting/profiles-and-logs/> using Safari on the device you will use to replicate the problem with.

Click the “Profile” URL associated with the “App Store/iTunes Store for iOS” item. You will download the “itmsdebugging.mobileconfig” file.

IMPORTANT - PLEASE RESTART THE DEVICE


CAPTURE THE DEVICE CONSOLE LOG - connect the device to a macOS X Sierra system (macOS X 10.12.x or newer)

1. Launch the Console app on the macOS system, and select the device in the left side of the Console window

2. Before starting the iOS app, click “Clear”.

3. Start the application and perform the steps to replicate the problem.

4. When the issue occurs, save the contents of the Console log

Check the contents of the console log for the string “fetchSoftwareAddOns”. If this string is not present in the log, the profile was not active. Please re-install the StoreKit profile and make sure to restart the device.


If the string is found, save the entire contents of the console log to a text file.


rich kubota - rkubota@apple.com


developer technical support CoreOS/Hardware/MFI