Auto renewable subscription cancel notification : iOS PAYMENT - ios

How can we cancel an auto Renewable subscription from itunes and get a call back in our server?After getting cancelled from itunes I should get notified in my server or in phone so that I can call cancel subscription in my server.
I read something like this somewhere
" When you hit apple server with the last receipt you have saved, it
will return you the code for cancellation of subscription"
My doubt is:
Is there any specific error code returned in case if the subscription is cancelled?
I have a cancel button inside my app to cancel subscription.What I think of doing is to redirect to the setting ->manage subscriptions page for now.After cancellation How can I get notified about this?
OR,shall I set a cron in the backend to check for cancellation?

Related

Detecting IAP Cancellation

I generally understand receipt validation on In App Purchases. Most libraries make this as simple as calling a method.
I'm not so clear on how subscriptions work though -- specifically, how can I detect if the subscription is cancelled?
Subscriptions are cancelled on Apple's iTunes interface only. How is my server supposed to know that a subscription was cancelled?
From the Apple docs:
The user can also cancel their subscription by disabling auto-renew and intentionally letting their subscription lapse. This action triggers the App Store to send your server a status update notification of type DID_CHANGE_RENEWAL_STATUS. Your server can parse the auto_renew_status and the auto_renew_status_change_date to determine the current renewal status of the subscription.
https://developer.apple.com/documentation/storekit/in-app_purchase/subscriptions_and_offers/handling_subscriptions_billing#3221914
The answer from Jacob is correct for the case that the user disables the auto-renewal of his subscription. If the user requested a refund from Apple and they cancel the subscription for him. Your server will receive a CANCEL notification and the receipt will contain a cancellation_date field.
You need to handle both of those cases, because when the user cancels (deactives the auto-renewal) his subscription, it is still valid (till it expires). When Apple customer support cancels the subscription, then it is from this point on invalid.
Note: the CANCEL notification is also triggered when a user up- or downgrades to a different subscription of the same subscription group. See this answer for more details on that.

Question about server-to-server notification

As Apple doc said in this doc: https://developer.apple.com/documentation/appstoreservernotifications/notification_type?changes=_2
Subscription event | Notification types triggered
-----------------------------------------------------------------------------
.
.
.
Auto-renewal disabled (canceled) from
the App Store account's Subscriptions settings | DID_CHANGE_RENEWAL_STATUS
AppleCare refund | CANCEL, DID_CHANGE_RENEWAL_STATUS
When AppleCare refund happend, there are two notification types triggered, one of them is DID_CHANGE_RENEWAL_STATUS. And when cancel subscription happened, its notification type is DID_CHANGE_RENEWAL_STATUS too. So, when i got a notification with notification_type DID_CHANGE_RENEWAL_STATUS, how could i know whether the user has refunded or canceled?
I don't know why Apple triggers CANCEL as well as DID_CHANGE_RENEWAL_STATUS, but technical it is correct. The user cancels his subscription (you get the CANCEL notification) and this also changes the renewal status (you get the DID_CHANGE_RENEWAL_STATUS notification—obviously the subscription won't renew in the future).
To your question: you know a refund happend when you receive the CANCEL notification and when the server response body with the DID_CHANGE_RENEWAL_STATUS notification contains the cancellation_date_ms in Latest_receipt_info.
cancellation_date_ms
The time and date that Apple customer support canceled a transaction or the time and date the user upgraded an auto-renewable subscription.
see here for more details.
Don't worry in the case that a user upgrades his subscription, your server will receive additionally to CANCEL and DID_CHANGE_RENEWAL_STATUS the INTERACTIVE_RENEWAL notification.
In the case the user canceled (deactivated auto-renew) the field auto_renew_status (documentation) in the response body is set to 0.

Subscription change from Subscription screen

Now we grouped the subscription in the way that the user have possibility to downgrade/upgrade or cancel the current subscription from a Subscription Screen (settings/appleId/iTunes&AppStore..).
How to handle this case of user subscription change in app or on the server side ?
In app:
You should get a callback in SKPaymentObserver with the new transaction. It will usually be with the same originalTransactionID.
Server:
Use server to server notification detailed here https://itunespartner.apple.com/en/apps/news/45333106

How to restore and verify auto-renewable subscriptions?

First off there seem to be many questions on SO regarding this topic but most seem outdated and not considering APIs that are available in iOS 9.
1) How are purchases restored?
When a user taps the Restore Purchase button for auto-renewable subscriptions on >=iOS 9, should a SKReceiptRefreshRequest or SKPaymentQueue.defaultQueue().restoreCompletedTransactions() be called? Currently I verify the receipt file to determine the active subscription and parse for the latest_receipt_info, is a receipt file also created on the device when restoreCompletedTransactions is called?
2) How can an auto-renewable subscription be verified?
To verify that an auto-renewable subscription on >= iOS 9 is still active and not cancelled I would call SKReceiptRefreshRequest every time the user launches the app. But the docs say:
Include some mechanism in your app to let the user restore their
purchases, such as a Restore Purchases button. Restoring purchases
prompts for the user’s App Store credentials, which interrupts the
flow of your app: because of this, don’t automatically restore
purchases, especially not every time your app is launched.
Should I call it only once a day or is there another way to verify the subscription?
Update:
For 2) just found this here:
Perform receipt validation immediately after your app is launched,
before displaying any user interface or spawning any child processes.
Implement this check in the main function, before the
NSApplicationMain function is called. For additional security, you may
repeat this check periodically while your application is running.
Apparently the receipt can be validated without user interaction. It is even recommended to do it on one's own server for security purpose. So as long as the receipt is validated by the App Store server there is no need for a receipt refresh request.

IAP - How to cancel a purchased transaction if the content download fails, or the receipt is invalid ?

I am trying to figure out something with IAP.
In the documents I see that I need to call finish transaction only after the purchased content ha successfully downloaded for the user:
Your application should call finishTransaction: only after it has successfully processed the transaction and unlocked the functionality purchased by the user.
I have this situation -
The user purchase the content.
After the purchase is completed, I am sending the receipt to verification on my server.
If there is no problem I am downloading the content to the user.
BUT what if I get an invalid receipt? Should I call finishTransaction ? or simply remove transaction ?
Other scenario is when the download fails, and the user leaves the app for a while. Is there away to cancel the purchase and let him restart it later ?
Thanks
If the validations fails you should call finishsTransaction but not deliver the content and advice the user that something went wrong.
You can't cancel the purchase, once you get a receipt the purchase has been done. You have to code your own mechanism for retrying the download whenever is posible.

Resources