Failed transaction on subscription change

When implementing IAP renewable subscriptions and changing the renewal option within a subscription group (e.g. changing from a monthly to a yearly subscription) the transaction observer (paymentQueue:queue:transactions:) always gets passed a transaction with a .failed transactionState even though the subscription change seems to have gone through successfully (according to the "Your are all set" alert and the server-to-server notification and receipt validation).


Example:

Assuming that 3 subscription SKUs are available (1-Week, 3-Months, 1-Year):


- Subscribe to 1-Week SKU

- Wait for completion

- Change subscription to 3-Months

- "You are all set" is displayed.

- A transaction with transactionState = .failed is sent to the SKPaymentTransactionObserver. The transaction.error:

Error Domain=SKErrorDomain Code=0 "Cannot connect to iTunes Store"


I also filed this as rdar 47152431 (also on Open Radar).


Is this a known issue?

Replies

The problem which you have described leads me to ask - In the App Store Connect records for your application - what is the order of the subscription items within the subscription group. Is the 1 Week subscription plan an upgrade to the 3 month subscription? or vice versa? The ordering of the subscription items listed in the application records determines whether one subscription item is an upgrade or a downgrade to another item. Duration of subscription is not used to determine whether one subscription item is an upgrade or a downgrade to another subscription item.


As such, per the In-App Purchase Program Guide - Working with subscriptions section, Upgrades and Plan Changes subsection

<https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/Subscriptions.html#//apple_ref/doc/uid/TP40008267-CH7-SW4>


"Users can manage their subscriptions in their account settings on the App Store, or within your app’s interface. For each subscription, the App Store shows all the renewal options that the subscription group offers. Users can easily change their service levels and choose to upgrade, downgrade, or cross-grade as often as they like. Downgrades of any duration or cross-grades with different durations go into effect at the next renewal date."


If the 3 month plan is a downgrade to the 1 week plan, then when the 1 week plan is currently active for a subscriber, then if the user attempts to "downgrade" to the 3 month plan, the iTunes Store should indicate to the user that the new plan will go into effect at the end of the current subscription. In this case, the user account has not been charged. The essence is that the transaction was not a success, but instead a failure. As there is no "user to be charged later" state, the App Store returns the failed transaction result.


Keep in mind, that the app should already know that there is an active subscription in place which the user should still have access to.


There's also server-to-server notifications when this happens, but that was not the question.


rich kubota - rkubota@apple.com

developer technical support CoreOS/Hardware/MFI

Thanks for your detailed answer, Rich. Our current order is Weekly, Yearly, Quarterly (from top to bottom). How should it be and is there a way to change the order in App Store Connect?


However, we receive the .failed transaction regardless of the order of the subscription change. No matter whether we start with Weekly and switch to Quarterly, or start with Quarterly and switch to Weekly, we always get that .failed transaction. So apparently it doesn't matter whether it's a downgrade or upgrade.


Also, shouldn't there be some sort of confirmation from StoreKit that a renewal pref change went through? Seeing an "All set" alert from StoreKit followed by a .failed transaction seems very strange.

One speculative answer - I was always confused about this upgrade/downgrade idea and how the app store can figure out what to charge if you are half way through one subscription and you upgrade to another subscription. In all cases, I think (but I could be wrong) that at the conclusion of the current subscription period (even if the user upgraded or downgraded) the user will be told that the subscription will autorenew to the upgraded or downgraded subscription period and, if they don't object, the subscription for the upgrade (or downgrade) renews. In that case, the change in subscription itself, whether it is an upgrade or a downgrade, would result in nothing being billed until the current subscription expires - and therefore the change itself results in a 'failed' transaction.


And another speculative answer - when a user tries to make a purchase and their credit card info is out of date, the App Store asks them to update the credit card info. After they upgrade the credit card info the App Store asks if they want to go forward with the purchase? If they say yes the App Store generates two successive transactions - one failed and the other purchased. Is that what is going on in the case of an upgrade?

This is all based on the sandbox but what I can say is, there's just one transaction, the failed one.

Hi @ortwin,
This is an area of App Store Connect that really doesn't seem very clear, but hopefully this (alongside this article that I'm sure you've already seen) will help.
Same Subscription Levels:
When you add new subscription SKUs to a group, they get added at the same level - note the "1" at the end of both rows in this screenshot:


pasteboard.co/IbAaCeh.png


When subscriptions are at the same level, a change between subscriptions is always counted as a "Crossgrade". When a crossgrade is between subscriptions of different durations, then it waits until the existing subscription expires before the crossgrade is complete. If they're of the same duration, then the existing subscription is refunded (pro-rated), and the new one is paid for.


Different Subscription Levels:
You can drag the blue handles at the right end of the subscription rows to move them to different levels - note the "1", and "2" in this screenshot:


pasteboard.co/IbAaSrl.png

The behaviour following a change between different levels depends on the direction of that change. I can't find any confirmation of which is higher, but the wording in the linked article seems to say that the top level is #1, and therefore a change to #2 would be a "downgrade". The behaviour in these cases is that an upgrade happens immediately (the existing subscription is refunded pro-rated, and the new one is then paid for immediately), and a downgrade happens at the end of the current period (similarly to a crossgrade between subscriptions of different durations).
In the above screenshot, we'd therefore be better off swapping them around, and counting a change from monthly to yearly as an upgrade.
If you add all of this to what @rich was saying, it might be that you've not actually tried an upgrade or downgrade because your subscriptions are all at the same level. Dragging them so that they are actually numbered differently in App Store Connect might allow you to see the behaviour of an upgrade/downgrade rather than a crossgrade.
Anyway, I hope that this helps, and please let us know how you get on because it's bound to be helpful for us and others.