I'm testing an auto-renewable subscription using a Sandbox account and observing the server-to-server notifications that are received during one purchase cycle (initial purchase, auto-renewals, expiration of a single in-app purchase product).
Logs of the notification_type of each notification that is received:
INITIAL_BUY // initial purchase
DID_CHANGE_RENEWAL_STATUS
DID_RENEW // first renewal
DID_RENEW // second renewal
DID_RENEW // third renewal
DID_RENEW // fourth renewal
DID_RECOVER // why does this happen?
DID_RENEW // fifth (last) renewal
DID_CHANGE_RENEWAL_STATUS // auto-cancellation in sandbox mode
I tried this process repeatedly with different Sandbox testers and noticed the same behavior. Is there an explanation for why the DID_RECOVER notification is received each time?
It's weird that you get that notification, for 2 reasons:
It is a notification related to billing issues
According to the documentation, this notification is not available in Sandbox
https://developer.apple.com/documentation/appstoreservernotifications/notification_type
Test Notification Events with Sandbox (picture)
Related
We have a problem with Apple subscription callback on Sandbox environment. When I purchase an auto-renewable subscription on Sandbox env, apple sends first callback only after 1-2 min. It's ok. But when the first expiration period ends apple not always notify us about extending a subscription. But we should receive notification_type = RENEWAL always at the end of the expiration period. Sometimes we receive notifications sometimes we don't. Do you know how can we check where is the problem? Maybe Apple has some troubles because we couldn't find any problems on our side.
RENEWAL events are sent when a subscription has expired, then later, the user starts the subscription again.
See: Apple Subscription Notifications are Almost Useless
We have setup Apple’s Server notifications for auto-renewable subscriptions. Last month we still able to get all notification type(INITIAL_BUY, RENEWAL, INTERACTIVE_RENEWAL).
Recently when we tested with sandbox (1 year subscription), we receive only 'INITIAL_BUY' server notifications, we were expect to receive 'RENEWAL' server notifications after 1 hour, but we are not getting those notifications.
Question:
I just want to confirm that is it a new notifications service that only send us 'INITIAL_BUY' notifications? And there are no server-to server notification if the renewal is successful?
Note:**
We did validate receipt with verifyReceipt server to check latest_receipt_info.
Correct. 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.
You have to actively call Apple's receipt validation endpoint on or around the expiration date of each receipt (and possible for a few days after that) to fetch the renewal receipts. Apple will not notify your servers.
Using In-App Purchases, Does the subscription status notification via Subscription status URL has a retry mechanism? That is if the receiving server is down what happens to the call made, is it lost?
Apple documents for the same
https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/Subscriptions.html
I created an API to be called by Apple webhook to work with subscription. I've set the API url in Itunes to be called by the webhook.
According to Apple help site https://help.apple.com/app-store-connect/#/dev7e89e149d in regards to the Testing Auto-Renewable Subscription, when testing auto renewable subscriptions in the test environment, the Apple webhook will make a call to the API after 5 minutes if I select 1 month subscription duration.
But the thing is, after making first purchase, apple webhook doesn't follow up call to the API that I created to renew the subs. Even after I waited for more than 5 minutes. So I can't do any processing from the API to renew user subs in the database.
Is there some configuration that I had to make in order to test the auto renew and make apple webhook call the API to renew the sub?
We've found that Apple's subscription update webook calls are rather unreliable.
Based on experience:
Don't count on Apple to notify you of renewals. The notification may arrive arbitrarily late (often leaving a "gap" in time), or not at all. We've resorted to retaining and retrying the original iTunes-provided receipt to revalidate renewals at the end of subscription periods --the expiration dates will change to account for the renewal.
Don't count on Apple to notify you of cancellations, either. Same as above, calculate subscription duration, and retry receipts at the end of a period (the expiration date will NOT be updated if the subscription is cancelled).
Generally, this involves mapping the additional transactions/in_apps that are returned with the retried receipt to the original_transaction_id --and updating the expires_at accordingly on your end.
Hope this helps!
Update: In WWDC2020 Apple announced that they add a new notification type called DID_RENEW which will be sent after any successful auto-renew. More info on that in this video, starting at around 16:00.
Original answer:
I can't find the page you linked to, however this page may shed light on the subject (emphasis by me):
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. However, in the few cases that iTunes is unable to renew the subscription (generally there was a connection problem with the credit card server) and the auto-renewing subscription is not renewed before the expiration_date passes, the auto-renewing subscription is technically considered expired. iTunes may continue to attempt to renew the subscription. If iTunes is successful, then the RENEWAL event is sent.
Meaning, you're not supposed to receive notifications for renewals, but only for cases where the subscription became expired and only then renewed. This might be the case for sandbox renewals as well.
Found this statement in apple documentation:
After a subscription is successfully renewed, Store Kit adds a
transaction for the renewal to the transaction queue. Your app checks
the transaction queue on launch and handles the renewal the same way
as any other transaction.
If I only do this on start:
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
Nothing happens - subscription is not renewed (using test mode).
if I add
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
Then it runs over complete history of purchases which is also not what I want.
What is the proper way to handle it?
One thing you need to understand, when testing auto renewable subscription in sandbox environment, sometimes the subscription doesn't get renewed and you don't get renewal calls from the Store.
This is normal in sandbox and calling restoreCompletedTransactions in sandbox environment sometimes it trigger the renewal on the Store. The duration for the subscription itself is different in the sandbox: Here is a table of duration in sandbox:
Just add [[SKPaymentQueue defaultQueue] addTransactionObserver:self] when your app launches and in production it will get renewed and you will get calls.
Apple in-app purchase storkit document:-
After a subscription is successfully renewed, Store Kit adds a transaction for the renewal to the transaction queue. Your app checks the transaction queue on launch and handles the renewal the same way as any other transaction.
Which means,
If user's subscription is auto renewed and at that time our app is not running, Apple added that renewed transaction in transaction queue. So when you will opened app, we can get those renewed transaction details from transaction queue.
There is another statement mentioned in storekit document like:-
Note that if your app is already running when the subscription renews, the transaction observer is not called; your app finds out about the renewal the next time it’s launched.
Solution: How to handle auto-renewal subscription?
According to Apple storekit best practices, we should add below line in AppDelegate's "didFinishLaunchingWithOptions":-
SKPaymentQueue.defaultQueue().addTransactionObserver(SubscriptionObserverClassReference)
& for verifying subscription, Two ways available:
1) Using Server: Set cron job that verify user subscription arounds user's subscription expiration date. So we can identify user subscription renewed or not based on expiration date.
2) Using StoreKit Observer:- Every time when user subscription is renewed, we get renewed transaction information. So based on that we can take action accordingly.
The commentors and documentation were right: it is sufficient to add transaction observer to the PaymentQueue on start. In my case the renewal has not been triggered for the Sandbox User I used the whole time. I created the new one and it worked!
For my case, in sandbox testing for subscription, it will only auto renew the subscription for 5 only on the FIRST subscription purchase. Subsequent subscription purchase will stop renewing after purchase. The only way to test is to recreate a new sandbox user and test again. Rinse and repeat!