I'm working on an iOS app containing in-app purchases. From time to time, we'll release new IAPs for users to buy. To do that, we'll need to release new versions of the app, e.g. we'll release v1.0.4 containing new IAPs. We plan to offer users a way to receive push notifications, telling them when new IAP products are available.
My problem is: how can I send the notification so that users can tap on the notification and immediately purchase the product?
If we send the notification the very instant that v1.0.4 is released, users won't be able to tap on the notification and buy the product, because they can't possibly have downloaded v1.0.4 yet. We could delay the notification for a day or two, but some users/devices will necessarily straggle behind regardless.
We could send a push notification redirecting users to the App Store to update the app. But we wanted users to tap the notification and immediately see the Buy screen for our new IAP. Making users tap on a notification, then tap Update, then wait for the download, then re-open the app, and then buy the IAP is a lot of hassle for our users.
How do other developers handle this problem?
The best way to handle this is to allow the old version of your app to download the content of the new IAP without upgrading to a new binary version.
Apple allows you to submit IAPs that are not associated with a binary; just fill in the metadata, upload a screenshot, and tap "Submit for Review." In that case, Apple just reviews the metadata, because they can't review the IAP's content.
Once that's approved, the old v1.0.3 app can receive a push notification that the new content is available. When the user taps the notification, the app can refresh its list of in-app purchases (e.g. by making a web request to your web site), download the new content, and make it available to users without a new v1.0.4 release.
You might want to submit a new release anyway, to include the content in the app bundle, and so as to present release notes to users in the list of updated apps in the App Store.
Related
We want to add in app purchase (auto renewable subscription) to our app. We do it on a separate branch and don't want it to be part of the app until implemented and tested thoroughly.
To support it, we need to define a IAP on app store connect.
Of course, other features are implemented simultaneously, merged to master, and we submit the app to review once a week.
We are scared that if we'll define the IAP, when submitting to review the IAP will be submitted automatically with the app, before the feature is ready on the client side.
Is it possible to exclude the IAP from review until we are ready to submit it?
If not, how would you approach this?
When you view your IAP on App Store Connect there is a checkbox, "Cleared For Sale". You can keep that unchecked to be safe that your in-app-purchases won't be visible anywhere.
I am in the process of updating my app to new iOS7/8 in-app purchase libraries. I see now that as of iOS7, we have access to appStoreReceiptURL as part of NSBundle.
It appears I can access this URL, and its concomitant data, at any time, without interacting or interfacing with the SKPaymentQueue.
Previously, when a customer installed our app and wanted to restore his in-app subscription, the app would call the restoreCompletedTransactions method of [SKPaymentQueue defaultQueue], and from that obtain receipt information, one transaction at a time, that the app would upload to our server one transaction at a time.
However, while testing in the iOS App Store Sandbox, now I appear to be able to obtain one piece of master receipt data from [[NSBundle mainBundle] appStoreReceiptURL], upload that to my server, obtain a complete history of every in-app transaction this user has made, and then record transactions on my server as appropriate and send notification back to my client.
Consequently, why or when would anyone need to call restoreCompletedTransactions? In my app, I sell a single, auto-renewing in-app subscription; are there other use cases today in iOS7/8 for which this API is still helpful?
If a user has made a purchase on a different device, it can be useful (or necessary) to "restore" that purchase on a new device. restoreCompletedTransactions could enable this restore operation. By default, on this new device, I believe the >= iOS7 style receipt will not have those prior purchases. On >= iOS7, SKReceiptRefreshRequest will work in many cases.
From Apple:
In most cases, all your app needs to do is refresh its receipt and
deliver the products in its receipt. The refreshed receipt contains a
record of the user’s purchases in this app, on this device or any
other device. However, some apps need to take an alternate approach
for one of the following reasons:
If you use Apple-hosted content, restoring completed transactions
gives your app the transaction objects it uses to download the
content.
If you need to support versions of iOS earlier than iOS 7,
where the app receipt isn’t available, restore completed transactions
instead.
If your app uses non-renewing subscriptions, your app is
responsible for the restoration process.
See https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/Restoring.html#//apple_ref/doc/uid/TP40008267-CH8-SW9
I had implemented the restore button in our app but it is causing us a issue where if the member created Account A from our app and pays through the appstore. then if he creates another member in our app and restores the purchase by tapping the restore button and putting in his app id in this fashion using just one apple app id he is able to have multiple platinum members by buying just once fo one single member and restoring multiple times for diferent members.
This is for an upcoming website and app where i have a free/basic plan for anyone who registers and then an upgradable one time/lifetime platinum plan.
Now in my ios app I have received a message from Apple in the resolution center that "To restore previously purchased In-App Purchase products, it would be appropriate to provide a "Restore" button and initiate the restore process when the "Restore" button is tapped by the user."
Now if a member has upgraded from one device and is logging in from another ios device he will not be a basic member as he is already a Platinum member as per our database and hence will not see the buy/upgrade to platinum scene in our app.
Basically Can I avoid a rejection by removing the Restore button.
What will be my solution the the above case
I have selected a Non-Consumable Purchase
is platinum membership associated with a specific login to your server? If so, then on your server, when you process the in-app purchase receipt and associated it with a user account you record the receipt ID. Every time you process a receipt, you check and see if another user has already claimed that purchase first, and don't honor it if it's a repeat. Replay attacks are a pretty classic ploy and easily defeated if the purchase is tied to a user login...
I have an old app with in app purchase items. We are moving to a totally new app that will sell the same items while the old one will not be in use.
Can we move the items to the new app in iTunes connect?
No, you cannot. The IAP process is governed completely by Apple. You can probably set up a server generating promo codes for the users of the old app. And using the promo code unlocks the features in the new app?
Or some document type that could be sent via email and when your app opens it, unlocks the content.
You will need some mechanism to ensure these (either the promo code or the files) are used just once.
I am implementing a digital magazine project for a client. Auto-renewable subscriptions for a period of 3/6/12 months have been included as a feature. My question is while using in-app purchase, is there any way for the server to map the user?? Anyway to identify a particular user is using it? I have done extensive research and know that apple doesn't allow the user's apple-id to be mapped?? Is there any other way to identify a particular user?
The problem arises for subscription. If an user has undertaken a subscription for let's say 3 months, then my app has to show DOWNLOAD button for all the 3 months instead of the regular BUY button. But when a new magazine is launched on to the storefront, how would the app know that this person is subscribed or not and convert the BUY to DOWNLOAD?
When a user buys a subscription, you should store the receipt on your server. This receipt, in a way, becomes your way to identify the user's account. Whenever you want to check the status of an account, send that receipt to iTunes for verification and it'll respond with the latest receipt for that subscription, along with the expiration date. Since you've made a note of which specific device that receipt came from, you can provide the proper UI to that user.
Now, if the user installs your app on a new device they can tap a Restore button that you've provided in your app. That button will call restoreCompletedTransactions which will send all the Auto-Renewing receipts for that user's Apple ID to the device.