I'm trying to implement in app purchases in my app. You can buy access to view a teams extra data. The amount of teams are dynamic so I cannot create a product id for all the teams. What I did now was create 1 consumable with a generic product id. When the user buys access I will save it on my server which one it is, but here is the problem. How do I know when I get called back that a purchase was successful which team it was again. Can I for example add extra data to the payment or something
This does not seem to be feasible currently, neither on App Store or Play Store. (for App Store, you might want to keep an eye on the future of SKPayment's requestData - but I would not be too optimistic)
1st approach: storing [productId: metadata] pairs
Since a user cannot make 2 parallel purchase on the same product id, you could store metadata (such as teamId) associated to the productId
The issue with this workaround is that a purchase can complete after your app has been killed/uninstalled
2nd approach: modified UX
A possible way to solve your issue is to invert your UX flow:
You could ask for the "payment metadata" after the purchase is actually made
Conclusion
I would ideally implement both approach: use the 1st one for most use case, and keep the 2nd as a fallback (as the 1st solution has a smoother UX)
I suppose you have to use non-consumables In-App Purchases for each team.
When you're adding a new team the flow is next:
Go to iTunesConnect and create a new In-App Purchase with id for the
specific team.
Create a new team on your server-side. Assign In-App
Purchase product id to this team into the specific field.
Once your app fetches the list of teams it will fetch product id for
each team (which you have been created in iTunesConnect).
Update In-App Purchases with product IDs fetched from your server.
Now you are able to make purchase.
Related
Our app was rejected in App Store because we were using 3rd party solution for subscription and was decided to use In-App Purchases ( Auto-Renewable Subscriptions). I went through several tutorials and it seems that the subscription has to be created in App Store Connect and only then it will be available to use in app and that's the problem for us.
Our app is something like news app where user can subscribe to some author. List of authors comes from server therefore hardcode every subscription for each author is not the way to go.
So, Is that possible to somehow implement what I want with In-App Purchases? Thanks.
There is no option to create subscription dynamically. Your case is a draw back of iOS subscription platform. I have pointed out this problem to Apple subscription team but they were not ready to accept this and forced us to implement in-app subscription, so we had to restrict the number of subscription in app.
Only possible option is to create a number of subscription groups, lets say 10 groups representing each author.
authorSusbcription1,authorSusbcription2,...authorSusbcription10
I know it's not a viable solution since the number of authors is indefinite. But we don't have any option as of now. You can restrict 10 authors subscription in the app and then prompt users to buy from website if it's exceeds 10.You can show some alert that doesn't violate the in-app rule. For example, "Further subscription is not available in this app" instead of mentioning about your website. Track this user and use an API to send an email to this user asking to subscribe via website.
Unless Apple fix this drawback, we have no other options..!
Dynamic Auto-Renewable Subscriptions creation (and dynamic in-app purchase creation in general) is not possible. Alternatives would be to sell credits to authors (but this is non-auto renewable). Another possibility is to sell tiers of subscriptions that grant access to a number of authors.
Can I create one in-app product for, say, some music, and then vary the exact track based on a database key?
So the user would buy a music product but the app keeps track of the exact data which comprises their instance?
As #Paulw11 said in his comment above, you can setup a consumable product ID that offers one or more "credits". Using the concept of credits is the only way you can dynamically allocate products to purchases without adding a product ID for each song in iTunes Connect.
Consumable products can be purchased multiple times, so allocate credit or direct the user to select the song once they buy the product. Be sure to call finishTransaction to "consume" the purchase, otherwise the transaction will remain in the queue and additional purchases will be blocked.
Be warned though, consumables are not restorable; if the user deletes and re-installs the app all their songs will be lost. One way to deal with this is to keep a server-side registry of songs a user has purchased, which means you will need user management and authentication etc.
Here's another stack question relates to yours.
Have any of you implemented something similar to the below scenario?
Consider an app which provides audiobooks:
The books are maintained dynamically from a web based UI by the authors.
The books become available for users of the iOS app, as in-app purchase items.
By default Apple guidelines suggests using non-consumable IAP, and adding continuously as many IAP items as many books we have. But this is not proper for us, as the authors won’t have access to iTunesConnect, so it cannot be dynamic, “self-serving”.
Therefore we are planning to create a set of generic "consumable" IAP items like “Book worth $0.99”, “Book worth $1.99”, and so on. Then in the app we’ll show the corresponding IAP item for the books as specified by the authors, when they added it to our system.
Of course we store the purchased items on the server side, so the user will always have access to the purchased items -- even if they access it later from another device.
Will Apple approve this implementation?
Does it fit with their IAP policy?
I’ve found some similar quite old topics in the forum but the answers were confusing.
Have you implemented something similar and get approval from Apple?
Apple has accepted our solution, as described in the question.
The point is, as highlighted correctly by #RomOne and #ge0rges that you need to provide the possibility to restore the items later.
As we are storing every purchase in our database, and our users are authenticated (they need to register and log in to purchase), we are able to provide them access to the purchased items forever, even when accessing the app from other device.
We are also storing the associated in-app-purchase's ProductID from iTunesConnect, plus the userID, the price, and the date, to have a detailed register of all purchases.
Important: Apple has rejected our first solution, because they didn't understand how it works, and how a purchase can be restored.
The key to success was describing in detail how the system works and providing a test user access to our web admin site. This allowed the Apple reviewers to see the whole system.
Yeah in my point of view they will accept it. As long as you allow users to retrieve their purchases later on. Your system make me think about a virtual currency I have made where I had to make generic consumable that needed to be actually saved for the user. Apple approved it (and still does) because I was saving all purchases, even if it didn't fit perfectly with IAP policy ;)
The key here is to make sure these purchases are restorable, always. So make sure to store the "IDs" or however you identify the different item in a way that is associated directly to the Apple ID (not account, but Apple ID).
Sorry but I am bit confuse on implementing non renewable subscriptions.
Basic concept of app is user can post item to sell within the app. For each item to post he has to pay $.99. This item will remains there for 20 days.
As per apple documentation this kind of In App Purchase should be non renewable subscription with expiration logic to be implemented on Server side. I am done with everything like creating non-renewable IAP and integrating with app. Server maintains the expiration for each item.
Now my query is since user can post as many item he wants, how should the IAP ids should be maintain.
User Case #1:
- User A posted one item after he pay $.99 for that. So far so good.
- When he try to post next item, he is shown with the message "You have already purchase this, tap to renew or extend it" instead it should be something "Do you want to buy one xxx for $0.99"
Am I missing something here?
Use Case #2: Now say item is expired (after 20 days), For renewing shall I use the same IAP id (Product ID in IAP) to renew? or I need to create different IAP id?
Please guide me on this so that Apple shall not reject the app.
Thanks in advance!!
OK I used following:
non renewable subscription with expiration logic implemented on Server side.
Same Product ID works for me for Buying for first time and renewing after 20 days expiration.
And application got approved!
What I would suggest to you would be using Consummable in-app purchases.
Once the user owns the purchase, manage on your side how long should the registration last (server-side if the user has an account or NSUserDefaults if everything is local).
Once the subscription time is Over, just lock the functionality. During the subscription time, you can either disable the purchase button, or let them own new ones and stack the durations :)
As stated above, I would like to recommend consumable in-app. You have to maintain a database based on post id and date of purchase when user purchases a post.
You'll have to maintain this database such that it can be restorable for example if still 5 days are remaining. So user will be happy.
To maintain this data you can use your server if you have, or else you can use iCloud, any way this is a simple data sheet. Or you can use any third party library which gives free cloud storage.
Last but not least you can save locally, but I would recommend server, iCloud method. So users can restore their purchases.
So this way you can handle multiple subscription logically.
I'm developing an app where the user can purchase digital maps, charts and so on. I'd like to wrap these in in-app-purchases. The thing is that I don't know beforehand how many charts there will be, as I'm getting them from another source from the net. There could be hundreds.
I have a server that periodically gets the charts from that source and stores them locally; there may appear new charts in the future or disappear existing ones. All this without manual intervention.
There are three distinct types of charts.
My first solution was to create three consumable items and let the user buy these; this was working fine but unfortunately Apple rejected it, since they require charts to be "non consumable".
But I'm quite at a loss how to implement what I want with the non-consumable type. If I create these three types as non-consumable, and the user buys one, he will get all the other charts in that group for free, since a non-consumable item can only be bought once.
The only solution I can think of is to create a non-consumable item for every single chart. But that's something I want to avoid at all costs: as it is now, the charts are periodically fetched from the remote source without any manual work on my side. I'd like to keep it that way. I don't want to manually create a new non consumable purchases every time a new chart appears.
Any ideas how to make this scalable?
I can't completely spell it out for you with code but you can handle this problem two ways:
Currency.
You do not sell non-consumable items such as maps. You sell currency. With that currency you purchase maps. The maps you feed dynamically whenever the user hits your store front. That way you only need to track a few purchase options.
The other option:
The company I worked for initially set this up very simply. Our app would launch and we would reach out for a php script that handed us back the app store IDs that we had sitting in it. At that point we'd verify them and use the valid returns. This option allowed us to change our in app purchases through iTunes Connect and then in the script and everything was great.
This is an older post, but I just had the same question and found out there is now a way to dynamically provide non-consumables by hosting the product identifier list on your own server:
Every product you sell in your app has a unique product identifier.
Your app uses these product identifiers to fetch information about
products from the App Store, such as pricing, and to submit payment
requests when users purchase those products. Your app can either read
its list of product identifiers from a file in its app bundle or fetch
them from your server.
If your app has a fixed list of products, such as an in-app purchase
to remove ads or enable functionality, embed the list in the app
bundle. If the list of product identifiers can change without your app
needing to be updated, such as a game that supports additional levels
or characters, have your app fetch the list from your server.
There’s no runtime mechanism to fetch a list of all products
configured in iTunes Connect for a particular app. You’re responsible
for managing your app’s list of products and providing that
information to your app. If you need to manage a large number of
products, consider using the bulk XML upload/download feature in
iTunes Connect.
Apple Developer In-App Purchasing Guide
I think your limit on items is something massive like 10,000 or so.
Pre-create a big number of items, add some code to check your website to see what your highest chart number is and make sure the users can only buy charts that you have.
The app downloads the chart names and corresponding product id from your server and then you're just buying a product.
Apple doesn't care if the actual product is already in the app and unlocked by the purchase, downloaded from their server or provided from your website.
Whether you have these purchased directly via IAP or through some kind of in-app "currency" you could simplify the amount of work you'd need to do in the future by using a naming system which would guarantee a unique map name for each item you want to sell. For example:
NSString *myMapName = [NSString stringWithFormat:#"%#%#%#%#", app_identifier, map_type, top_left_corner_location, scale];
This way if your server passes that information for a new map, there's a programmatic way to know what the IAP identifier should be— just make it the value of the string myMapName.
In the case where you use currency (which sounds easier than the alternative option, and is what lots of big apps out there seem to be doing) you just need to make a hash with some data in your map so that people can't guess the code you're storing in their keychain/plist and magically get all your maps without paying :)
In the case where you actually have individual IAPs for each map, sadly you do have to make an IAP for every possible map once. (But you can hire some kid to do that part for minimum wage, right? It's just data entry) They can be basic shells, though, with the actual info provided via your server as described above, once it's verified that the map has actually been purchased.
Hope this helps!