In App Purchase Subscription Auto Renewal - iphone

I have implemented a couple of months ago the in app auto renewable subscription on two of my apps. I stored the old receipts of my users and contacted Apple from my server at the end of the subscription period to check if the subscription is still active.
I noticed that some of my users are being auto-renewed form the client code itself.
My app upon entry calls [[SKPaymentQueue defaultQueue] addTransactionObserver:myObserver] and when either SKPaymentTransactionStatePurchased or SKPaymentTransactionStateRestored is returned it calls my server to verify the receipt and give my users the subscription.
I have been trying for quite some time to understand the logic behind the transaction notification the client gets at the end of the renewal period. Does anyone knows why only some of the users get the notifications and the rest require the server to revalidate their receipts? I tried to think maybe it has got something to do with the call to addTransactionObserver. Maybe those users killed the app while it was in the background and entered the app again after the subscription period ended which caused the addTransactionObserver: to be fired and the notification to arrive.
If I can get all of my users to get this notification I wouldn't have to run the server calls anymore at the end of the subscription period as they would be fired from the client when needed.
Any insight would sure help understand this puzzle.
Thanks
Roi

My experience states you'll need to continue periodically verifying receipts on your server. I have noticed the same as you, that these new receipts are sent to the app inconsistently. I think Apple will send the receipt to the client if they happen to freshly launch the app within a certain time frame of the new renewal.

Related

SwiftUI Auto-Renewable Subscription flow

I have implemented In-App Purchase Auto-Renewable Subscription into my app but I'm not sure if I have done it correctly as the app constantly asks for iTunes login.
In the user case: I am subscribed to monthly payments and my first month is over and expect it to auto-renew.
The flow I have at the moment is as follows...
(in App Delegate) Check receipt is valid
(if receipt IS valid) check all receipts for latest expiration date
(if expired - which seems to be the case after the first month is over) call SKReceiptRefreshRequest to get latest receipts. I have put a count check on this otherwise it gets stuck in a never ending loop.
Do final check to see if latest receipt is in-fact expired.
Is this the correct way to go about this? If not could you shine some light on this?
It all seems to be working fine apart from the annoyance of iTunes login. Which I guess would only be once a month outside of the Sandbox environment which isn't too bad but just want to be sure I'm doing this correctly.
Thanks
Don't call SKReceiptRefreshRequest. This request is usually only for the "restore purchases" mechanism. This is why you're getting the sign in dialogue. StoreKit will return to you as long as you an observer to the payment queue: https://developer.apple.com/documentation/storekit/skpaymentqueue/1506042-add so you should add yourself to the payment queue on app launch. Then keep that object aline to listen for changes for the entire app lifecycle. You will receive the renewals in the updatedTransactions callback https://developer.apple.com/documentation/storekit/skpaymenttransactionobserver/1506107-paymentqueue
Secondly, you should be doing receipt validation on your own server and not on the client as it will be susceptible to a MITM attack. You can also easily control the logic there and receive Server to server notifications which is best for managing subscriptions.

How to implement auto renew subscription in app billing google play

I'm researching method to implement auto renew subscription in app billing with google play. I read https://developer.android.com/google/play/billing/billing_subscriptions.html and see
Billing continues indefinitely at the interval and price specified for the subscription. At each subscription renewal, Google Play charges the user account automatically, then notifies the user of the charges afterward by email. For monthly and annual subscriptions, billing cycles will always match subscription cycles, based on the purchase date. (Seasonal subscriptions are charged annually, on the first day of the season.)
When the subscription payment is approved, Google Play provides a purchase token back to the purchasing app through the In-app Billing API. Your apps can store the token locally or pass it to your backend servers, which can then use it to validate or cancel the subscription remotely using the Google Play Developer API.
So have any method to my server know when user's subscription was renewed? Instead of google play send new bill subscription to android app after that android app send this new bill to my server just for validate.
Can google play send a notify to my server when user's subscription renewed such as notify the user by email ? I want to google play send me a notify that user's subscription was renewed automatically so that my backend will update expire their subscription in app increase. Don't need android app have to check bill each time user open store to check have new bill from goole play charge automation or not. Do it implement?
My workfollow
Google charge a new cycle subscription and notify to my server { body such as bundId, bill, product_id or subscription package name, expire date...), also sent mail to user about their subscription automation renewed.
My server determine change subscription of the user and validate in app purchase by google play api and change expire package subscription in your app if validate is valid.
Store newest bill in my db
Is that possible?
[Update] Recommend from goolge play api doc
Recommendation: Include business logic in your app to notify your
backend servers of subscription purchases, tokens, and any billing
errors that may occur. Your backend servers can use the server-side
API to query and update your records and follow up with customers
directly, if needed.
How to implement recommend from google api, any doc or tutorials ?
I have currently exactly the same problem. The concept of Google is not well-conceived. There is a possibility to notify your backend server about financial transactions (see here), but I would not recommend this. You rely your business transactions on a lot of Google services and your server uptime. If anything goes wrong or is down or something, you will not be informed and your backend business logic does not work anymore.
This recommendation of Google you mentioned sucks as well. What happens if there is an auto-renawal (which delivers a new purchaseToken to your app) and the user never opens your app. Then the new subscription data will never be transferred to your server. And if you never got a new token, how can you check, if the user is still a subscriber, since this limited Google Play Developer API stupidly needs a purchaseToken as parameter (see here) that you never get as long as the user does not open your app at least once after an auto-renewal (to submit it to your server).
I think about implementing this in this way:
1.) I continuously check the purchase records by cron job. A purchase record is a database entry which contains all data from the initial subscription (orderId, purchaseToken, and so on, all that is needed for the security validation process on the server). Every purchase record is connected to a user's account (some UserID) in my backend system. As long as the autoRenewing attribute of the purchaseRecord is not false, the subscription is valid. Even if the expiryTimeMillis is exceeded, this one user could still have a valid subscription, because of the use case I described above: Subscription will be auto-renewed by Google, but the user never opens the app, so no transfer token is sent to your server and you are still not informed about the subscription update.
2.) If the use cancels his subscription any when, the autoRenewing would be false at any time. That means that the subscription will indeed end at the expiryTimeMillis.
3.) When the user opens your app and transfers the new purchaseToken to your backend, you will get a new purchase record which is again connected to the user account with his User ID. The user will probably have 2 purchase records now. The old one and the new one. If so, you could delete the old one, and the same process repeats with the new purchase record at step 1.
I didn't have implemented the concept so far, so I don't know if this really works like this. Maybe this could work in a different manner, but maybe it's a step into the right direction.
I don't think, relying upon daily basis cronjob is a feasible way to go about this problem, It is messy and you have to also consider the case when your application is handling too many requests, you have a limit of transactions that made using android developer's api. The better way to implement it would be to use google's recommendation. Which stats:
...
Note: Due to quota restrictions, it is not recommended to check state by polling the Google Play Developer API at regular intervals instead of leveraging Real-time developer notifications.
...
Here, You can follow the following url
How to get expiry date for Subscription with client side in Android? and to implement the auto-renewal subscription.

In-App Purchase Auto-renewable Subscriptions

I have an app that sells Virtual Phone Numbers. When an user subscribes, we deliver a new virtual number and the user can manage this number within the app. After that, the user can receive calls but not necesarily through the app. I mean, after the initial purchase the user does not need to open the app to use the service but I need a way to check the subscription status monthly. My question is, can I set up a cron in the server to check the next receipts even the user wont open the app anymore?
Is it possible to sell a subscription service that is not delivered through the app? Thanks.
Take a look at this service that manages IAP and push notifications..
http://urbanairship.com/
IF your service is eligible for auto-renewable subscriptions you can use that ( this is tricky because they reject this if the app dosen't give content. see more here: http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/StoreKitGuide/RenewableSubscriptions/RenewableSubscriptions.html )
I've not done this myself, but the gist I get from the store docs is that you will verify the receipt and get an updated transaction if the subscription has been renewed. So presumably on your server you have some indication of when the original subscription was purchased and the time, so you would check before it expires and get the new transition.
I'd suggest maybe using push notification if this were to fail, to engage the user to update/renew.
You can use the Auto-renewable subscription from apple to serve your users.
When user buy the subscription first time store the receipt in the server.
Maintain the expiry date of the subscription per user in the server DB.
Run the cron job and check for the "Active Status" of the subscription via apple APIs http://tinyurl.com/ay2labm
Depending on the status you can extend the service to your users.
http://tinyurl.com/aeh9f84

Auto-renewable subscriptions calling SubscriptionsUpdated

I have implemented som auto renewable subscriptions in my app and everything works well. I perform a purchase in the app, everything gets synced to a server, and the server then checks the iTunes API as soon as the subscription has expired to detect if the subscription has been renewed.
One thing confuses me though. Every once in a while I get a call to transactionsUpdated within my app with a transaction with status: Purchased. This is usually done after I restart the app.
Why do I get these calls? Has it something to do with the subscription beeing renewed? Can I safely ignore these calls? Everything seems to work fine.
Thanks in advance!
Yes, what Apple is doing is sending you a receipt for an automatic renewal of the subscription. Because all durations are drastically shortened in the sandbox, the subscription will get automatically renewed by Apple every few minutes, for a limited number of times (like 5), before they stop renewing.
Since you're already checking for new receipts at the right time on your server, you can ignore the receipts they're automatically sending to the app on occasion.

How to test the "renew" component of auto-renew subscriptions in iOS App Store Sandbox?

Folks,
I am attempting to verify that auto-renew subscriptions are actually renewing in the sandbox environment. First, it appears that auto-renew subscriptions in sandbox are only valid for 5 minutes. Makes sense. I expect that if I wait for five minutes, then make another call to
https://sandbox.itunes.apple.com/verifyReceipt
With my receipt data, I should see the subscription renewed with an expiry date another five minutes out.
Unfortunately that is not the case. All I see is a response with latest_expired_receipt_info and a status of 21006, which means "This receipt is valid but the subscription has expired" according to the Apple docs.
Can anyone tell me if they are able to test auto-renew subscriptions end-to-end, including this renew component? Or do I have to launch this app and cross my fingers that prod will work as advertised?
Alternatively, is there some sort of client-side magic/API call I have to run prior to re-posting my data to the verifyReceipt URL?
There was some discussion on this topic here, but it's not clear to me if I can/should expect to be able to re-verify subscriptions entirely on the server side by posting to the verifyReceipt URL or if I have to do something on the client side too.
Thanks!
Copied from the Apple's Developer Forum, for those not willing to goto the forum...
Figured it out (but not thanks to the Apple docs):
1 month subscriptions auto-renew every 5 minutes. So far so good. They
auto-renew 5 times and then they stop, so after 25 minutes you'll get
the 21006 error. However even when repurchasing the same subscription
it will NOT auto-renew again on the same test account since it has
already auto-renewed 5 times. So if you want to test renewal and you
have been messing with these subscriptions for a while you need to
create a new itunes connect test user. This is very annoying honestly
and it would be a lot easier if we could just reset the entire
purchase history of a test user account. Also putting all in-app
test information in the Xcode documentation would be a lot better as
opposed to spreading it over Xcode docs/iTunes Connect doc/people
figuring stuff out themselves
Hope this helps.
This conversation in the Apple dev forums may shed some light on this issue for others who discover this post: https://devforums.apple.com/thread/105350?tstart=0
#Lata Sadhwani, App developer
For testing auto-renew subscriptions, the expiration time is 5 minutes
in sandbox (at least for the monthly subscriptions, not sure if this
is different for different periods). So when testing an auto-renew
subscription in sandbox, it should auto-renew every 5 mins and you
know they are working correctly.
But there is one problem. These subscriptions auto-renew only 5 times
(i.e. the purchase happens 6 times). After that you'll get an error
when verifying the receipt. So if you want to test after that, you
will need to test with another IAP test account (yes it is a pain
testing, especially if you have been doing this for quite some time!)
To check if a subscription has been cancelled or is valid, your
receipt verification code will need to parse the response from Apple
servers and they say you should verify each receipt. If the
subscription has expired or has been cancelled, the appropriate error
code will be returned (a non-zero status). If it has been renewed by a
user, the most current receipt is returned by the Apple servers.