When Users with old IAP Auto-Renewing Subscription (currently in Cancelled/Unsubscribed State), upon “Renewal"/Re-purchase (from a new device), does StoreKit upon purchased state send a receipt?

Greetings,

The reason I am asking this question is I updated my App's code recently to locally verify the latest IAP Subscription formatted receipts (PKCS7 container-by parsing data-validate necessary fields-then extracting 1708 field: Subscription Expiration Date). It properly validates the receipts on recent transactions unlocking its data and restores subscriptions, but I discovered one User who happened to have a very old subscription (Cancelled State), who tried to purchase a new subscription/renew, but the App could not verify their receipt to unlock its data for some reason. It seems upon their successful purchase, StoreKit is not sending a new receipt or is sending old receipt format?


Under this user's AppleID, Manage Subscriptons, their purchase of the subscription shows as active. I then had them try, deleting the App, and doing a Restore Subscription also, and it still does not locally validate a PKCS7 contained formatted receipt ....so I am suspecting their Receipt must be different: in the old original format (IOS 6 type) or not receiving any new receipt??? Under their AppleID's Purchase History, the purchase I see also has the same original Order identifier, and states its a "Renewal" and is not given a new Order ID marked stating "Initial" purchase as other users who just purchased.


Any ideas why the app works fine on all new transactions, but not able to process this one user's old cancelled subscription when purchased/renewed today? FYI ...the old code, now deprecated used was the transaction.transactionReceipt method and resulting receipt handling, and new code uses receiptUrl = Bundle.main.appStoreReceiptURL to fetch the receipt. Did I also wrongly assume the "latest" receipt being retrieved using SKReceiptRefreshRequest returns a PKCS7 contained formatted receipt with an updated Subscription Expires Date and not the deprecated one or no IAP receipt data? Could this be a App Store bug for any old subscriptions that get renewed (re-purchased)?


Has anyone else run into this problem? ...and if I need to add code to handle both old formatted receipts and new PKCS7 contained formatted receipts? Current app I designed for IOS 11 or higher.


Regarding the App failing to restore too in addition to not process a receipt from purchased state, would using restoreCompletedTransactions (all receipts) instead of SKReceiptRefreshRequest (latest receipt) method for Restore Subscriptions return the latest receipt format which will parse and validate correctly? I wanted to reduce the volume of transactions the app validates given it just needs to extract the latest 1708 field's expires date for the subscription purchased.


Thanks in advance for your help.

Replies

TMI.


If a user 'cancelled' the subscription then that means they contacted the App Store and told them the piurchase was an error and asked to get their money refunded. Cancelled differs from expired. Are you certain they cancelled?


The receipt system is pretty good. Most times when a receipt is bad its because the user is hacking the system.


When a user does a restoreCompletedTransaction they get the latest receipt information. In your case that receipt "does not locally validate a PKCS7 contained formatted receipt" - it's unclear what that means - but if it means the receipt is not properly signed by Apple or that the hash in the receipt is incorrect then tell the user they are not making the purchase from the Apple App Store.


You wrote "Under this user's AppleID, Manage Subscriptons, their purchase of the subscription shows as active.....the purchase I see also has the same original Order identifier, and states its a "Renewal". How are you obtaining this information? Does it show "cancelled" ? Are you certain it is valid information? Has the user sent you their receipt from the App Store with their name on it?

Thanks for your reply. The product purchased is of a Auto-Renew Subscription type, which this customer had purchased originally years ago (on a old device), who had "cancelled only the subscription's auto renewal" (under their AppleID Settings, Subscriptions), then tried to "Buy" (re-subscribe) same subscription option within the App's latest update (on a new device). They did not have Apple Cancel & refund previously their subscription. Under their "Purchase History", only one OrderID shows up, and on the date they re-purchased / did a "Buy" again on their new device, Purchase History shows the same OrderID with "Renewal" stated. Other customers can see their first purchase & date with an OrderID stating "Initial" and same OrderID with subsequent dates of Auto-renewal stating "Renewal."


Within the App, this customer's transaction went through the regular prompts to the user and finished with "You're all Set" which they were able to confirm as an active subscription selection (checkmarked) to the Auto-renew Subscription selected under their AppleID, Subscriptions.


The App's code does verify and process valid receipts when received from StoreKit's queue entering purchased state: it verifies the signature of a PKCS7 receipt; parses the receipt's payload and extracts the 1708 field's date (transaction's Subscription Expiration Date) to unlock subcribed data. But for this one customer's "Renewal" transaction, the App does not extract any 1708 field's date at a minimun ....or StoreKit's Purchased State is not sending a receipt containing a 1708 field???


This customer's OrderID, as I stated originally was first purchased years ago, likely with multiple transactions under it, and the transaction made today should be contained in its latest receipt's payload after "Buy" enters purchased state, correct? For some reason, I suspect a receipt is not getting received when its a "Renewal" of a Auto-Renew Subscription that is being purchased (from StoreKit's queue, entering purchased state). Is it possibly becuase they are using a new device different from their original purchase, buying a Renewal?


Another fact, I do know the customer had deleted the App prior, and was running a new install on their device before they tried to Buy the subscription option within the App.


The best user experience is for the App to processes all transaction's receipts when a "Buy" completes within StoreKit ...Intital Purchases, and Renewals. I'm trying to figure out why Initial purchases work fine and Renewals apparently do not? Is there 4th option I need to add or possible to SKPaymentTransactionObserver protocol beyond "Purchased" "Failed" and "Restored"?


- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {


for (SKPaymentTransaction * transaction in transactions) {


switch (transaction.transactionState)

{

case SKPaymentTransactionStatePurchased:

[self completeTransaction:transaction];

break;


case SKPaymentTransactionStateFailed:

[self failedTransaction:transaction];

break;


case SKPaymentTransactionStateRestored:

[self restoreTransaction:transaction];

default: break;

}

}

}


My completeTransaction method verifies transactions and their receipts as valid properly for all other purchases. But if it can not handle "Renewals" from old subscribers in a unsubcribed state who want to subscribe again, that can be a big issue for me. Given the App was a fresh install (was deleted) for this user, why would their Buy (re-subscribe) be any different from a new user buying their first purchase??


When do we use or need to address StoreKit's SKPaymentTransactionStateDeferred? Is that the case I need to consider here?


If not, and all users with Renewals need to be told to do a "Restore." Is calling:

[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];

my only option for Auto-Renew Subscription products too?


I may have wrongly thought I could utilize:

SKReceiptRefreshRequest *request = [[SKReceiptRefreshRequest alloc] init];

request.delegate = self;

[request start];

to only extract just the latest transaction & receipt to lesson the burden on processing all transactions on the app, but this does not work for this user?


It was my understanding that restoreCompletedTransactions restores "All" receipts and is generally used when app unlocks numerous features from multiple purchases, while SKReceiptRefreshRequest, restores just the latest receipt and stores it locally on the device. I'm thinking the issue possibly may be because they are using a new device, and SKReceiptRefreshRequest does NOT send the correct receipt even though last purchase was completed on the new device??


If its not a SKPaymentTransctionStateXXXX issue, or SKReceiptRefreshRequest could it remotely be the receipt's format? Its hard for me to debug what's truly going on here in production environment for this user.


I'm thinking I should make my Restore Subscriptions function, only utilize restoreCompletedTransactions method and see if then a proper receipt gets received for this user (They will likely though have to do two steps: 1. Buy, then 2. Restore Subscriptions).


With other users who have purchased a subscription recently (but on same device), who I had unsubscribe, then after the expiration bought again, their purchased state, the app properly validates, processes a receipt + extracts the 1708 subscription expiration date field and unlocks data properly in one step (1. Buy)


Thanks to all of you for your help.

TMI means "too much information".


A valid receipt should show a correct value for 1708 expiration date. The subscription is most likely no longer valid on that device. Tell them to do a restoreCompletedTransactions on that device.

Greetings,

I just had this user download my latest App's update that went Ready for Sale, today 12/30/2018 on their new device which implements restoreCompletedTransactions for Restore Subscription, and they got the same result! The exact steps they took were:


1. From App they did a "Buy" of the Auto-renew Subscription, and they received the expected StoreKit's pop ups, that confirm the purchase and ended with "You're All Set."


2. The Receipt Validation did NOT unlock content.


3. They press Restore Subsubscription button that executes restoreCompletedTransaction method to refresh-on a new device.


4. Their Receipt Validation still did NOT unlock content. I suspect the Latest Receipt's transaction's 1708 field must not be present for this user, why????


5. User then checks the new device's Setting, ITunes & App Store, View Apple ID, Subscriptions, Your Subscriptions-Options and confirms Auto-Renew Subscription they just purchased was completed succesfully and is Checkmarked.


6. Then they tried deleting the App, powered off Device, turning it back on, downloading App again, do another Restore Subscription ...and it still does not unlock content???


I'm at a loss why this user's receipt validation still fails to read a 1708 field, while all other users purchased state receipts validate upon a "Buy" and "Subscription Restores" does? If all previous auto-renew subscribers (unsubscribed) who purchased during IOS6 receipt days can not Renew today on a new device, that is a big bug for me and Apple. Any suggestions how to best Debug this user's receipt (OrderID Renewal)?

Can you explain two issues in your description of this user?


1) On December 27th you posted that they purchased the subscription but it didn't work. Then on December 30th you posted that they purchased the subscription again ("1. From App they did a "Buy" of the Auto-renew Subscription, and they received the expected StoreKit's pop ups, that confirm the purchase and ended with 'You're All Set.'and it didn't work.") Why didn't they restore the subscription on December 30th if they purchased it on December 27th? Why did the store say 'you're all set' if they had actually purchased it on December 27th?


2) Is it a coincidence that the first post was on December 27th about a problem with IAP and 3 days later a new release of the app is approved? Is there some relationship between the two events (problem reported by user and new release of app) that you are not decsribing?


Although not relevant to your problem, newly approved IAPs do not appear available for purchase on the App Store for 1-2 days after approval.

Greetings,

In regards to 1, the customer was at the time in a "unsubscribed" state of their Auto-renew Subscription (with 1 week period) when they purchased it again in App, with "You're All Set" executed properly and a "Renewed" state of their subscription showing under by their AppleID (subscription checkmarked). Their auto-renew, prior to trying to buy again this last time, they had done Cancel of Subscription under their AppleID before the Subscription's renews date since the subscription is only for a week period ...so were in unsubscribed status.


In regards to 2, the last release version of App approved, the only change I made was to Restore Subcriptions, which I switched to executing restoreCompletedTransactions vs a SKReceiptRefreshRequest request.


The App tests fine in Sandbox and also works for new users who have recently purchased the same subscription, and even gone into unsubscribed and too renewed. I'm trying to figure it out why there is a failure with with user (who's just an old subscriber)? Why an old subscriber's receipt & transactions would be handled any different from a new subscriber is odd.


I starting to suspect possibly at this time in the app's code:

The old code's handling of the payment queue observer may not follow the latest best practices. The app's [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; currently starts in the app's IAPHelper.m file's method: - (id)initWithProductIdentifiers:(NSSet *)productIdentifiers; and observer is not started under MyAppDelegate.m file's didFinishLaunchingWithOptions, nor removed under applicationWillTerminate.

AppStore’s default application appe support apple developers application update please cancel iTunes sandbox and bustle amazon api all cancel conform cancel immediately application AppStore’s apple support update please

Have you resolved this? I am seeing the same issue all of a sudden without doing any app update.

Unclear what caused the earlier problem. A side issue - the order of renewals in the IAP receipt is no longer first-to-last. That means you have to sort the various renewal receipts and pick the latest expiration date.