Accessing StoreKit receipts directly from a server - ios

I'm building an iOS app, which provides a service which our website already provides. It's a subscription based service, where all features are enabled when you're subscribed. To get people to sign up for regular payments on the app, it seems like I'll have to go through Apple's in app purchasing API, with auto-renewing subscriptions. That's fine, but the problem is the service users will purchase through the app must also be available on the site. But reading through walkthroughs and the developer guide, it looks like the only way to process transactions is through the app itself, which then can be set up to pass the info to the server. But then I'm imagining this scenario:
User purchases a subscription on the iOS app, goes back and forth between using the site and the iOS app. On the day the user is to be charged, and the days after, they're using just the website, for whatever reason. The server doesn't know they've been billed though, and so features are disabled. In order for the server to find out the user has been billed by Apple, the user has to open the app on their iphone or ipad and sync it with both Apple and my server.
Is there any way for my server to ping Apple directly and get information about the purchases made for my app for a given user? I haven't been able to find anything; the two suggested layouts, with or without server, both use the iOS app as the sole communicator with Apple, aside from having the server verify that information is valid. If it's not possible for the server to get this information first hand, what other possible solution could there be?
Try to not use Apple's built in payment system, and risk getting rejected (with the app duplicating a service that's been available for years online, do we no longer have to use their in app purchasing system anyway?)
If a user is paying through Apple, have the server give them a generous buffer between expected payment dates and when features are disabled (makes the problem happen less frequently but doesn't solve it)
When their account seems expired to the server but it doesn't expect that, email the user a message saying they have to open the app or else their account will not be credited for time purchased (seems like a strange and not really great thing to have to ask a user to do in order to use the service)
This is about all I've been able to think up so far. Anyone have any advice on these solutions, or know of others, or know who I could talk to to try and figure this out?

Yes, you can check on the status of a user's account from your server. There are a few caveats:
First and foremost, Auto-Renewing Subscriptions are reserved for periodicals such as magazines and newspapers. If your app doesn't resemble those, Apple may reject it (as they did mine) and request that you use Non-Renewing Subscriptions (read: Manually-Renewing Subscriptions).
Second: This scenario would require you to store all receipts that you receive on the app, on your server.
Finally: I don't know how your username/password system works, but the user would have to login with the same credentials on your app as they do on your website.
Here's how you check the status of a user's account: Store at least one receipt per user on your server. When you want to check the status, follow Apple's procedure for Verifying App Store Receipts. Send them that one receipt and they'll respond with the latest receipt and the expiration date. Now you'll know, at any given moment, if a person's account is current or not.

Related

iOS In App Purchase with Rails Backend

I'm having some confusions when creating in app purchase strategy for my iOS app. Some background info below;
I have an iOS app and a web app which both will work in subscription model. The backend has been developed in Ruby on Rails.
Currently I'm trying to develop the iOS auto-renewal in app purchase. I came across couple of gems which helps to verify in app purchase receipts (e.g Venice). I get that the whole point of verifying the receipts from the backend rather then the client is to make it secure and to be able to keep a copy of the receipt in your own server.
I can foresee a huge problem as explained below;
A user can create an account using the iOS app and subscribe to the service by paying X dollars monthly using x#x.com apple id. By doing this I will have the record of this user in my backend including the expiry date of his subscription which will enable for me to track if he renewed his subscription or not. The problem arises when this user logs out from the app and creates another user. Since his apple id is still x#x.com and as account email address or id doesn't matter at all when making a purchase from apple, the expiry date will still be a month ahead since he just subscribed with his previous account the new user will be identified as an already paid customer. Boom! now his friend can login with this account using the web app and enjoy it without paying a quid.
If this makes sense for you, there must be a solution for this hack. I know that Netflix uses Apple's IAP, Spotify used for a very long time.
Also gems like Venice, they don't put a thorough documentation on their github page therefore I don't know if this problem is solved by them out of the box. Just wanted to check with you guys and I'm sure many of you thought about this.
If you're attributing the auto-renewing purchase to a user in your database you will also want to attribute the original_transaction_id that is found in the receipt. Store this ID with the expires_date and ignore or error any receipts containing the same original_transaction_id the API receives that are already attributed to a different user in the database.
The original_transaction_id will never change for the iTunes user, even if they unsubscribe and re-subscribe at a later date it will remain the same. It will also remain the same if they upgrade/downgrade the duration of the subscription when the product IDs are of the same subscription family.
If you're looking for an alternative to Venice take a look at the itunes_receipt_validator gem (full disclosure: I am the author). It validates the signatures and decodes of both the deprecated transaction receipts and the newer grand unified receipts locally without connecting to Apple's API, but also provides the functionality to retrieve the updated receipt and receipt info from the Apple API.

How to synchronize/verify in-app recurring subscriptions with a web server (cross platform subscription)

We run a SAAS Web app and are going to be launching our app in Apple’s app store (up to now we’ve had a mobile Web app).
We want to offer the ability to purchase a subscription in app due to the ease of use for our customers. No problem, we know how to do that.
The question we have is whether there is an easy way to keep our web app's db updated with the user’s current subscription status so if they access our Web app we know whether their subscription is valid.
Ideally it would be great if Apple offered a web hook option where they would post an update to a url on our server. From what I've read this isn't an option.
We can always post the data to our server from the iPhone app when the user logs in, but if the user doesn’t log in on the iPhone for a while the subscription status recorded on our server will be out of date.
How are other people handling this? Are we missing something?
Update:
The closest I've found is this thread: https://forums.developer.apple.com/message/70707#70707
The app gets a receipt the first time it buys a subscription or
restores a subscription. The app can send that original receipt to
anyone's server. Anyone's server can then use that orignal receipt to
verify the current subscrition anytime it wants. You can't do that
with a non-renewing subscription but with a non-renewing subscription
the user must purchase the extension from the iOS device each time
period.
Followed up with this:
https://hetzel.net/2011-04-01/server-side-auto-renewable-subscription-receipt-verification/
And from Apple it sounds like they definitely do not make any provisions on their end for synchronization:
Cross-Platform Considerations
Product identifiers are associated with a single app. Apps that have
both an iOS and OS X version have separate products with separate
product identifiers on each platform. You could let users who have a
subscription in an iOS app access the content from an OS X app (or
vice versa), but implementing that functionality is your
responsibility. You would need some system for identifying users and
keeping track of what content they’ve subscribed to, similar to what
you would implement for an app that uses non-renewable subscriptions.
Late to the party, but I think this is a relevant reply to this question:
https://stackoverflow.com/a/47537279/543423
Hopefully this is helpful to someone :)

HOWTO track auto-renewed subscriptions in iOS In-App Purchases?

We are building a subscriptions based video on demand platform that lets our subscribed users to access films from a variety of devices including iOS, Web etc.
So no matter from where the user has subscribed, they should be able to access the content from any & all devices that we support.
Since I need to maintain user's state at a central system (so that all devices can query & allow/disallow access to paid-content).
I have read through multiple documentation re: iOS In-App Purchases & have determined we are a good fit for auto-renewable subscription category.
I have already integrated subscriptions via Roku & using that as a reference. For users who are subscribing through the Web, I have also integrated payment processors like Amazon Payments, Stripe & PayPal - the transactions for which are triggered by the Subscriptions Billing platform that I have already built.
My server (or an endpoint essentially) needs to be able to receive following bits of information preferably directly from iTunes and not from my app.
Notification when a user subscribes successfully to one of my products
Notification when iTunes sucessfully renews a subscription i.e. if user is subscribed to a monthly product then at start of next month, I need to have notification from iTunes that user has been successfully charged for upcoming month
Notification when iTunes successfully refunds a user for whatever reason
Notification when a user cancels a subcription directly from iTunes (not from the app). I know in this case it will mean that it stops the auto-renewal, but I still need to know that this has happened.
Notification when a user un-cancels the auto-renewal.
Does iTunes support any of these actions via Webhook or Push or IPN (instant payment notifications) etc? I havent come across it, if it does.
I know that there is something called as Validating Receipts but that seems to be not a good solution for me, since I need to know ASAP rom iTunes that one of the above flows has happened.
What, if any, are the workarounds to get this information? I am afraid that getting this info from my app is neither timely nor guaranteed to get it.
If you're expecting a direct feed from iTunes, you need to reevaluate your requirements. The in-app purchase ecosystem simply doesn't work that way. You may have the option to write your own subscription processing system (requires an outside payment processor) but whether Apple will approve it will depend on the exact nature of your content. From your description, you have mutually-exclusive requirements.
If the immovable requirement is that you use iTunes, you will need to validate receipts and forward those results to your server.

iOS Trial App Without In-App Purchase Mechanism

I am developing an app for a client, where he wishes the app to be able to have users to sign up and try out the app for 14 days, after which they have to make a purchase to continue using the app.
My client does not want to absorb Apple's 30% cut for using Apple's in-app purchase mechanism. Initially I suggested implementing a 3rd party payment gateway, but it seems that Apple does not allow app that unlocks app functionalities via a 3rd party payment gateway.
My question is this: if we submit the app that allows users to sign up and login, but only use the app for 14 days without any form of payment mechanisms in the app to allow the user to continue using the app, will the app be rejected? As I was thinking to just have the payment gateway on a website, and during user sign-up, send the user an email informing them that they can go to the website to make a payment.
I know that Apple rejects trial/demo apps, but this is technically a full fledged app where users that purchased via the website will be able to login and perform full functionality. I will also provide Apple with a test account that is fully functional.
Thanks!
Short answer: Apple will reject you if you allow signups and block functionality after a trial period without allowing IAP. Period.
I have first hand knowledge of this, shameless plug in 3..2..1.., Simple In/Out offers a 45 day free trial, after which users are blocked from using the app. In the early days, we escaped Apple's ban hammer by being small and using a blessed trial account that never expired. Apple would review using test account, never see rejection or blocked alerts and prompts to sign up on our website. That did change one day after requesting an expedited review. We got a lot more scrutiny and they rejected us for essentially steering users to our website for subscribing.
The IAP for trials and subscriptions other than magazines is pretty terrible. It is essentially designed for magazines, and that's it. So beware going in. What we eventually did was allow users to subscribe in the app using IAP. Our server manages who is subscribed and who isn't. It also manages which subscription they have (IAP or our own). There is a lot of weird receipt checks you need to do to manage the subscription from Apple. The user is also stuck if they want to change to a bigger/lower subscription plan. Which kinda works for us because the only way to do it is email us, in which we can convert from IAP (-30%) to our own (-2.5% for card processing).
The moral of this story is that if you plan on allowing users to create accounts inside your app, then you will most likely be obligated to offer subscriptions via IAP. If you want to avoid IAP, then you will also need to strip any references to your website from your app and description. They will bust you on meta if you try and steer them around the IAP process. Once we added IAP, we were allowed to point everyone to our website for "more information" in which we are able to convert more users to our own subscription rather than IAP. Right now, our number of our own subscribers vs. Apple is about 75:1. So we don't lose much over the signups we get from Apple.
I believe this should be perfectly fine as long as the 14 day "trial" is a fully functional version of the app.
Your model seems similar to Spotify. Pay for subscription on their website, but use the service in the app.
These resources may help:
https://news.layervault.com/stories/9695-how-do-apps-like-lyft-uber-airbnb-skirt-apples-30-cut-on-each-transaction
http://www.quora.com/How-does-Apple-define-digital-content-when-taking-its-30-cut

How to implement a licensing mechanism when purchasing an App Store application if the license system is on our own server?

I am looking to start selling an app on the Apple app store however currently the app uses our own servers to generate a license to the customer once they have purchased it. How can our existing licensing system which uses our own servers be implemented if a customer purchases the app from the App Store instead?
The application license will be a yearly renewable one. Therefore, so far, from what I have read, the app on the App Store could just come with an auto-renewal option (opt-out of course) so that would take care of the subscription cycle but how can our own server issue the customer the one year license which they could then renew from iTunes using the auto-renew function of the App Store?
I am sorry if this is not clear but it would go like this:
Customer downloads application from app store with a one year auto
renewal subscription.
Customer pays.
The app store verifies the
payment.
Once payment is verified it contacts our server to create a
license for that purchase and for one year.
That license is sent back
from our server to the purchased app to unlock the subscription.
Please correct me if my understanding on how this works is wrong but if anyone can point me in the right direction or give examples of how an application on the app store can successfully issue licenses from their own server then I would be very grateful.
As an example, look at "Aviation Exam". They let you buy subscriptions on-device as in-app purchases, or on their own website. In each case the details are synced to a user's account on their own server, so the same exam can be used from any device.
Look at the Apple documentation for how in-app purchase subscriptions work on iOS. Then your app can send details of a purchase to your servers, and download further information.
Edit; after discussion in comments:
If you want payment to go via Apple then it has to be via App Purchase or In-App Purchase. In-App Purchase specifically supports the idea of buying a subscription for a limited time. This is explained at the second link above.
If you want the user to create an account on your server you can either have a page in the app for them to input their details, or you can bring up a web page served from your website. Either way, the info can go to your server and it can create an account.
The key thing is, if payment went via Apple then inside the app is the only place you know this. The app can send this info to your server. You need some common identifier (i.e. a user-name) that is known to your server and to your user, then the user keys it in to your app and it can all be matched up.
There is nothing complicated here, to a decent software developer. All they need is an existence proof such as I gave at the top, and they can figure out how to link the info together.
Edit 2
Some tutorials for in-app purchase listed at: In-App purchase server model
Lots of low-level detail at: Verify receipt for in App purchase
If you prefer to handle payment yourself, not via Apple, then the situation is very different. Now, your own systems have to keep track of what has been bought, when subscriptions run out, etc. To begin with, the app won't know this at all. However, once you identify the user by having them enter credentials (username/password), you can fetch all the details from your back-end system to the app and proceed as above. Again, this is all visible in the example I gave at the beginning, which supports both Apple and non-Apple payments.
One thing to note: if you handle payment yourself then Apple isn't getting its 30% cut, which is the usual App Store commission, so they may not like this. The guidelines say:
11.1 Apps that unlock or enable additional features or functionality with mechanisms other than the App Store will be rejected
11.13 Apps that link to external mechanisms for purchases or subscriptions to be used in the App, such as a "buy" button that goes to a web site to purchase a digital book, will be rejected
That's pretty clear-cut, but since there are apps that rely on subscriptions or content purchased elsewhere, they don't seem to follow these rules in every case. Even the Amazon Kindle app was allowed back, once they took the 'buy' button off.

Resources