Issue with auto renewable subscription and status update notifications ios (swift) - ios

We have got a problem with auto renewable subscription.
First, I would like to tell you my case from the beginning to understand my problem totally.
So, I have an app that contains auto renewable subscription. I managed to buy a product from my app, but I would like to validate the receipt from my server. If I understand it well, then I should send the receipt data to my server that will send the receipt data to Apple and verify that receipt.
First question is that, do I know it right that verification means that we send a request to https://sandbox.itunes.apple.com/verifyReceipt ?
Secondly, what happens if I cannot send the receipt data for the server? I mean, in this case should I save the receipt data locally and try to send it again in a different time (my app can be used after registration so I have to send the user id with receipt data to my server)?
Furthermore, there is a subscription status URL for auto renewable subscription in iTunes connect. We set up an URL for this but we do not get any notification from Apple's server. We configured the server as explained in Apple's documentation (protocols, etc.) but we still don't get any notification. Do you have any suggestion why is it?
Do I know it well, that the notifications should be sent automatically if any status update change happens? If not then what should I do in my app or on my server? (e.g. how to detect if user cancels a subscription?)
Do I have to implement both logic for the best user experience?

To validate the receipt you can send it on apple servers, "can" because you can validate the receipt also in app. In this case is not fully safe, because someone can attack you app and tamper your validation code.
Apple has 2 different kind of servers test and production, when you are debugging you send receipt to the test servers, that also means that auto renewable subscription have shorter time, if I remember well a month in test is 5 minutes.
This is documented very well in apple documentation.
A receipt is always present in your app even if it's free. It's up to you how to manage those kind of situation, in my opinion a receipt should aways be valid from the beginning until the server responds in a different way.
The third question is not clear. There is a system to refresh a subscription but this should be done with user permission as far as I know, the subscription itself seems to be already updated automatically from time to time by the purchase mechanism.
You must implement all the logic to manage a subscription, cancellation, revocation etc.

Related

IOS auto-renew subscriptions notification handling

Good day! I'm trying to implement notifications for auto-renew subscriptions and some parts of the whole system are not clear for me. Could you please help?
First of all, when user creates a subscription I get a receipt from user's device, verify it and create a record in database with all needed information. Now, the notifications are coming to server.
INITIAL_BUY notification - When does it come and why? I just got a receipt from device, verified it and I'm happy. Why do I need it?
Correct me if I'm wrong, this part is unclear for me, When user UPGRADES subscription level I get CANCEL notification for oldSubscription and a receipt with a new purchase for newSubscription, right?
So theoretical question is - if on my server side content available in oldSubscription and content available in newSubscription are different entities than when I get CANCEL for oldSubscription I just deny user's access to oldSubscription content and when I get receipt from client I create newSubscription with access to new content, right?
DOWNGRADE and CROSSGRADE. As far as I see I get DID_CHANGE_RENEWAL_PREF or DID_CHANGE_RENEWAL_STATUS. So I will get auto_renew_status in notification for this subscription and when payed period will expire I will get a receipt from user device with info about new purchase? Or I have to figure out how to handle DOWNGRADE and CROSSGRADE only by DID_CHANGE_RENEWAL_PREF and DID_CHANGE_RENEWAL_STATUS notifications?
Thank you
The problem with server receipt validation is that there is not only one way. There are endless possibility to implement this and it depends on your use case of the usage of subscriptions and how you want the communication between your app and server to happen.
In your second paragraph is the first example of those possibilities: your server will get the receipt from the device only if you implemented it that way. Also, maybe you update your database solely based on the notifications instead of the send receipt. You see, it is all up to you ;-)
Regarding you questions:
1)
Occurs at the user’s initial purchase of the subscription.
See documentation
Theoretically this is correct, but your described use case isn't an upgrade. Would be odd, if the better subscription wouldn't contain the content of the lower one.
There isn't much to handle with down- or crossgrade. The notifications only tell you that there will be a change with the next auto-renewal. Because, the user is still eligible to access the better content until the next auto-renewal. After the better subscription expired you will receive a normal DID_RENEW with the down- or crsssgrade product id.

Can we store iOS in app purchase receipt to our server

I am developing an in app purchase app (auto renewal) and purchase/cancellation should effect on all platform (Android, iOS, Web).
My question is what is best way to keep track the latest status of the purchase. I know there is a way called server to server notification using web hook, but I am thinking can we store the receipt data to server and validate this receipt time to time with iTunes apis?
Does receipt data change over the updates on subscription or it is same even after changing the device?
All I want to validate it at server side, because there is a possibility that user can uninstall the app or not using it.
You can validate the receipts at server end. There are two options.
Enabling server to server notifications.
Store all receipts in your databases and verify it with server for latest update.
You need to use meta data from the receipt under key "latest_receipt" to get the latest update in the subscription.
Below is the link for reference.
https://developer.apple.com/documentation/storekit/in-app_purchase/validating_receipts_with_the_app_store#//apple_ref/doc/uid/TP40010573-CH104-SW1
Initial receipt meta data does not change over the time. You can save initial receipt metadata in your database and use it for further updates like - renewal, cancellation, upgrade or downgrade, refund etc.
Yes, you can, moreover server-to-server validation & observing is most preferable way recommended by Apple. They provided JSON API and accepts your server end-point to post any changes directly to server.
For details read Choosing a Receipt Validation Technique and related in topic.
The common start point is In-App Purchase

Linking iOS In-App Subscription to MySQL database

I have followed some tutorials on implementing In-App purchases and subscriptions for iOS (especially Ray Wenderlich) but I have doubts on how to integrate our iOS app with our website so that if someone subscribes to the app they can access the content on the web as well.
Our website and app offer access to videos. All subscribers have access to all videos. Our web works with PHP and MySQL. When someone subscribes on the web, a record for their account is created in our MySQL database and they are flagged as subscribers so that they can access the content.
We want to implement in-app subscription in our app, but we need for a record to be created in our database when the subscription takes place.
The question is, should we do this upon receipt validation (we'll be doing this in PHP)? Also, is there a way to know when a user unsubscribes through iOS so that the database can be updated accordingly?
Our closest example of how we would like it to work is Gaia.
Should we do this upon receipt validation?
Yes, you should wait until you validate the receipt to mark the subscription as active for the user.
Is there a way to know when a user unsubscribes through iOS so that
the database can be updated accordingly?
The correct way to implement this is to store the entire IAP receipt on your server and periodically refresh it with Apple to get the current subscription status. Just because somebody started a subscription doesn't mean it will still be active the next time you check it (e.g. they may have turned off auto-renew or been issued a refund).
This blog posts explains some of the nuances in further detail: iOS Subscriptions Are Hard
Is there a way to know when a user unsubscribes through iOS so that
the database can be updated accordingly?
Use status update notification.
A statusUpdateNotification is a server-to-server notification service
for auto-renewable subscriptions. A notification specifies the status
of a subscription at the time the notification is sent.
As status update notification is not a reliable service, Apple recommend to use this in combination of other method such as polling the verifyreceipt end point. creating a scheduler in server will be best option along with notification.

IOS Subscription Status Url not received by server side

We are trying to use Apple's subscription status url.
We have setup our server to accept the url we provided in the app page and made sure the server is compatible with ATS requirements.
A post test with Postman works. (we see the request and a test json received on our end)
However we are still not receiving any notifications updates from Apple upon renewal (not even initial_buy).
Seen some questions from last year but no valid solution. Does anyone had this problem lately and solved it?
I can't make a comment, and it's hard to see if this is the case here without knowing if you are actually receiving NOTHING at your script, or just receiving no data in $_POST.
If the latter, this should work:
$data = file_get_contents('php://input');
Then you should be able to work with the data by calling json_decode or doing whatever you want with it.
I ran into the same problem. I thought that Apple would call our webhook whenever a new subscription charge is processed (similar to how Paypal, Stripe, Android etc work). But that's a mistake. According to this technical note:
https://developer.apple.com/library/archive/technotes/tn2413/_index.html#//apple_ref/doc/uid/DTS40016228-CH1-SUBSCRIPTIONS-MY_SERVER_PROCESS_RARELY_RECEIVES_RENEWAL_NOTICES_WHEN_THE_AUTO_RENEWING_SUBSCRIPTION_RENEWS_
The App Store attempts to charge the user account 24 hours before an auto-renewing subscription expires. If the renewal is successful, there is no server-to server notification because the auto-renewing subscription did not enter into the expired state.
So Apple will only notify this endpoint when
a new subscription is created (at least that's the case for us, but we have a trial offer)
the subscription status changes from active to expired, or vice-versa.
So you have to keep track of the subscription receipts when the customer signs up. When the subscription is about to expire/has expired, call Apple's receipt validation endpoint to fetch the new receipt. If the receipt says the subscription expired, your webhook should be notified when the user reactivates it.

How to test auto-renewable subscription?

I have an app with an auto-renwable item in the inApp-Purchase.
Let's say, with an period of 7 days.
If a test-User buys the item...
How can I check the expiration-date?
I can observe it with restoreCompletedTransaction, but there will be an Dialog to the user. Which is not so nice. Is there any other way without a server?
How can I handle the test-phase?
I don't see a way to shorten the 7 days... does it mean I have to wait 7 days, to see that I'm handling it right if the user doesn't subscribe again?
thank you
xnz
You can send the receipt to a server of yours and have it check and re check the receipt. When the subscription is prolonged your server receives an additional receipt indicating that.
I am not sure if this is possible within the app. You need a certificate and a shared-secret to verify auto renewables. It might be a bad idea to have the certificate and the shared-secret within your app.
You can find Apples documentation here:
http://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/StoreKitGuide/RenewableSubscriptions/RenewableSubscriptions.html
There is some info by Apple that recommends to verify the receipt on your own server for security reasons:
http://developer.apple.com/library/ios/#releasenotes/StoreKit/IAP_ReceiptValidation/index.html
They also say, to know the status of your IAP (in the article, Consumable, but I guess it would work for subscriptions too) you can save the receipt, recall it when needed and verify it again, receiving an updated receipt.

Resources