iPhone • 40:34
With iPhone 3.0 SDK you can request payment for subscriptions, additional game levels, or other content from within your applications. This session covers the entire purchase life cycle for in-app payments, including use of the new Store Kit APIs, the product submission process, proper product presentation, purchase authentication, and transaction validation.
Speaker: Payam Mirrashidi
Unlisted on Apple Developer site
Downloads from Apple
Transcript
This transcript has potential transcription errors. We are working on an improved version.
My name is Payam Mirrashidi and I'm an engineer on the iTunes store. Today I'm going to talk about an exciting new API that allows you to do purchases in your applications, In App Purchase on iPhone. Let's start with an overview. I'm going to start by telling you what In App Purchase is and what it isn't, what you need to do to implement In App Purchases in your applications, and finally I'm going to have a small section on some financial details that you're going to be interested in. So let's get started.
What is In App Purchase? Store Kit framework is an In App payment engine for doing purchases in your applications. So you need iPhone OS 3.0. It's for paid apps only and it allows you to do, it allows you expanded functionality in your shipping applications. You can extend features that you ship with the applications, that you compiled in, and sell those features to your customers. Or you can extend your application by accessing features, content, services, stored up in the cloud. Store Kit presents your user, your customers with the same App Store experience that they experienced for purchasing your application.
It confirms their identity, collects payment, sends them the same iTunes store receipt that they've already received when they bought your app. For you, you'll see the transactions in your iTunes Connect reports. We'll talk about that later. So what are you going to sell? Store Kit doesn't define a business model for you. In fact, it supports a large number of business models out of the box.
You can sell content, you can sell functionality, you've got a couple game levels in your app that you shipped but you're going to charge for those. You can sell access to services. You can also sell access to subscriptions. So let's go through each of these and talk about what that means. Well there are some rules for using Store Kit in an app purchase. Digital items only are supported. You can't sell physical goods or services.
In addition, everything that you sell using the Store Kit API whether it's content or services, subscriptions, all of those goods must be delivered to the app from which it was purchased. In addition, you're required to provide whatever you sold to all of a customer's devices. So a given account, they have 3 devices, what you sell must be available on all 3. Let's go though some examples.
Digital books, those are supported, but real books are not. Real books cannot be delivered to the app from which they were purchased. If you've got a poker game and someone runs out of chips and they want to keep playing, you can sell some poker chips. But what you can't do, is if you have a blackjack game, you can't transfer those In App Purchases between apps. In App Purchases must be delivered to the app from which they were purchased.
So you can have some functionality that you ship with your app and you're going to sell the customer that functionality to open it up for them, that's okay. But any kind of intermediate currency for trading for virtual goods, it's not supported. It's not passed in functionality. The example I just gave is you've got a game, and let's say you've got 10 levels that you've built. When a customer buys your app, they get access to 8 and you're going to charge a small fee for those additional 2.
That's fine, maybe some bonus content. You can imagine in a document, an app where to use it out of the box, you don't really need the ability to save, but you want to charge a customer to add that functionality. That's supported. You can imagine a flight management application where it can handle a single itinerary out of the box when someone downloads your application, but you want to charge for managing additional itineraries, more of a pro feature. That's supported.
Some service examples. You've got your iPhone, take a picture of a business card, have it sent up to the cloud, send it back down, OCR with a V-Card. That's something that, that is a digital good that can be delivered to your application. Same thing with voice transcription. You've got an audio file, we send it up to the cloud, you get a transcript back. That's a supported feature. Same with voice over IP.
Telephone service. But plumbing repairs, courier delivery, web services, design, those are not supported. Those are not digital goods that can be delivered to your app. Stop by subscriptions real quick. The subscriptions cause a little bit of extra work on your part because Store Kit doesn't define a business model for you. Store Kit doesn't have a notion of a duration. It doesn't do renewal billing. These are features you'll have to implement yourself if you want to support subscriptions in your app.
You can, but you can support a monthly periodical, daily comic strip or access to financial data. These are all features that you can sell, they are services that you can sell using Store Kit. Now for a good user experience you want to make sure your renewal billing cycle is something where you're not nagging the user constantly. So that's something you have to decide. Store Kit doesn't impose that on you. Some examples of what isn't going to be supported is, you know, your local video store membership or gym renewal.
How are items delivered? Well built-in items are those items that you built into your app, maybe there's some information on a key list, maybe there's some code for an extra level, you know in that multiple itinerary example. You ship with that. And when an In App Purchase goes through, you unlock that feature. There's nothing else that needs to be done.
All of the code, all of the content, you ship with your app, you uploaded it to iTunes Connect. There's also server-delivered items for remote services. These are items, content, streaming services, media, that you didn't ship with your app. These are remotely delivered. This is also supported. In fact, some applications may support a combination of both. It's up to you, Store Kit doesn't impose a business model on you. It's up to you to define what you're going to sell, how you're going to sell it.
All right let's talk about code. How are you going to do this? Well there are three steps to implementing In App Purchase using Store Kit. The first thing you've got to do is figure out what you're going to sell. Once you've figure that out, you define your metadata of your products, and you upload it to iTunes Connect. Then you've got to write some code.
We'll go through that in great detail. And finally, we give you an environment called Sandbox to test it in. We'll talk about that as well. So let's get started. Defining the metadata for the products that you want to sell. The first thing you've got to do is create an item list.
What are you going to sell? Well everything you're going to sell needs to have a name, it's got to be localizable, it needs to have a description, it needs to have a price tier. Price tier is the same price tiers you're already using for your applications. You already know what this is. 99 cents and so on.
And finally, you need to pick a Product ID. Product ID is the unique identifier for each product you wish to sell. In this example, we've used reverse DNS to make sure it's easy to make it unique across all the products. So once you've got your product list, you need to upload this to iTunes Connect. Go to Manage Your Applications, you should find you app, click on Manage In App Purchases and Create New.
Let's get started with what you need to enter. Reference Name. Reference Name is the name that you give the product internally within your organization. Most people will have this be in their own language. So a French developer will probably be in French, Japanese developer will have it in Japanese.
This is never exposed to the user. Your customer will never see this either on a receipt, in their purchase history, or in your application. This is your name for the product. And there's Product ID. Product ID is a sequence of U2F8 letters and numbers that uniquely identifies the product.
It's important that when you create a new product, that you pick a good name, and that's why we recommended a reverse DNS example before, because once you enter it in here, you can't change it. So pick your Product ID wisely. Then you've got to pick the Type. Let's talk about that real quick. There are 3 types of In App Purchases. Consumables, Non-Consumables, and Subscriptions. Let's talk about these and what they mean. Non-Consumables, that's the default.
Non-consumables are products with built-in support in Store Kit. When a customer buys a Non-consumable one device, they're automatically, with no additional work by you, going to be able to re-download it on another device. The same way that today when a customer buys your app on one device and they put their credentials on another, you know, an iPod Touch, they get it for free on the other one. If you mark your items as Non-consumable, that comes for free. There's no additional work for you.
Consumables are those devices, which can be used up. You can imagine a game where you'd get ammunition and you can run out. And when you run out, maybe want to get a little boost, you can charge your customer a little more for a boost. So in that example, if you go to another device with the same App Store username and password and you log in, in that example you really shouldn't get it again.
You pay for it once, you consume it, and you move on. So consumables can be purchased multiple times. And furthermore, it's not required that a consumable item be made available across multiple devices. You may choose to do so because maybe a consumable is something that's a period of time.
Store Kit doesn't define that and the rules around consumables let you determine how to, how the customer consumes that product. Finally, there's Subscriptions. They have all the same rules around how Store Kit interacts with them, except that they're required to be shared with all, across all devices for a given customer. What that means is if I buy a subscription to Real Time Stock Quotes and I have a phone and an iPod Touch, I should be able to access them on both devices.
Once you pick the type, you pick the Price Tier and this is, same Price Tiers you guys are already familiar with by creating apps in iTunes Connect. Now the Cleared for Sale flag is interesting because this is one where you can't change it later and what it means is, whether this item is cleared for sale. When you first create a product you don't have to mark this, you can come back later when you're ready to deliver your, that product to your customers.
In fact, you can imagine a case where you ship your app, you don't clear it for sale, and then after a period of time, let's say a month or two, you can come back and check this. And suddenly you've extended your application, the product shows up and you don't have to push new code. Localizations is something that the product supports, it's a list of languages, and to localize two things as I mentioned earlier, to localize a name or a product and the description. Now this isn't required, but you've got to have at least one localization.
Name and the description. Finally, you need to upload a screenshot of an image that represents what your In App Purchase is. And with that, you click Save Changes and you're done. If you ever want to come back and edit that information, maybe to Clear for Sale flag, come back and click on the name. So that's how you define the metadata and upload it to iTunes Connect. That's the first step. Now let's write some code. Building a purchase workflow into your application.
There are 10 steps to doing that. It sounds like a lot but we've broken them down for you and actually, it's pretty simple to add this API. I would say deceptively simple to add this API its port Store Kit in your application. First thing you've got to do is, you know, validate access to the App Store. It's the parental controls on it. Load your catalog, fetch the details localized for the customer and their locale, present the items, you've got to build the store, ask for payment.
Payment comes back, did it go through? Validate the transaction, that's an important step, we'll talk about that as we go through this. If everything's fine, the payment went through, the transaction was valid, you unlock the feature, give the access to your customer. Remember the purchase, which is come back the next time they launch your app, they have access to it, and finally support restore. Let's go through each of these in detail. It's a long list, but there's not much you have to do for each one.
Validate App Store Access. iPhone OS 3.0 supports parental controls for a number of features and the App Store is one of them. You've got kids like me who buy any app with a pretty icon, you'll probably turn this off on your phone. And here, Installing Apps, this, not only does it control installing apps, but it also controls App Store Purchase.
In addition, you're company's configuration profile may have prevented you from buying apps and it also would've prevented you from doing In App Purchases. But it's really easy to figure out whether that is. Is it PaymentQueue class and you call Can't Make Payments, has a boolean, yeah the App Store is accessible or no it isn't.
I would actually call the steps 0 because without this, you can't, without a positive response from this, you can't do In App Purchase. So once you've got that out of the way, you need your catalog. For built-in features, for features that you've shipped with your app, you've probably got a key list somewhere that defines your catalog.
For remote features, chances are you've got, you've got to go talk to a server somewhere with a database of the products and download that information. If you do that, you probably want to store it, sock the key list away somewhere so you don't have to repeatedly do that.
Once you've done that, it's time to integrate the Store Kit and talk to the App Store. The first thing you need to do is fetch the details that are relevant for your customer, in their language, in their price, with their storefront. Over 70 countries supported by the App Store, you want to make sure that the prices you offer, you present to your customers, are relevant to them. How you do that is you create a set that contains all of the Product IDs that you wish to sell.
And from that, you create a ProductsRequest object initialized with that set. Now something I should note is that most of the interaction you'll have with the App Store is asynchronous which means we make, you'll make a lot of use of delegates and observers. Like in this example, which is I've got a ProductsRequestDelegate. When I make a request for a set of products, at some point in the future, Store Kit is going to call back and let me know what the response was. So once I've built up my ProductsRequest object, I got my delegate, I say Sstart.
That's, Store Kit is now going to communicate with the App Store, the App Store is going to look up those products, integrates with iTunes Connect, look up your, what you've uploaded, it's going to respond back. And then you're going to get a notification on your observer, excuse me, on your delegate. You're going to get the didReceiveResponse message. What does that contain? Well, it's got two fields, two properties that are going to interest you. First, one is products.
This is the list of items you requested and are available in the App Store right now, in your customer's current locale. invalidProductIdentifiers are the list of the Product IDs that we couldn't look up. The App Store, you know, went to the database, couldn't find it. Now why could that be? Well you may have forgotten to enter in iTunes Connect. Maybe you mistyped the Product ID either in your code, or in iTunes Connect. Could be that you forgot to mark it Cleared for Sale.
You launched your app and not available. Or, and it's important to note that the App Store is a distributed worldwide application. When you make a change in iTunes Connect, it does take some time for that information to replicate across all the servers. So give it some time, when you make a change, when you go mark Cleared for Sale, give it some time.
It doesn't take that long, but it's not instantaneous. So with the products list, these are the products that were available, right now in your customer's locale, you can get the localized title for your product, the description and the price. If you remember back at the beginning when we created the product, we had the name, description, and the tier.
This translates directly into this API call. So with that, you can present the items for selection. This is code that you have to write. Store Kit doesn't provide a store user interface for you. Store Kit doesn't define how you're going to present it for your user, whether it's going to be within the app, stand-alone store somewhere in your app, in the Preferences, that's a decision up to you.
Store Kit doesn't impose a business model on you. So once you built your store and you've presented the item for selection, the customer's going to, you know, click it, make a purchase. It's time to request payment. Request payment's pretty simple too. You create a payment object with either the product that they selected, that was back from the PproductsResponse object from the previous slide, or you can create a payment object straight from the Product ID. Either will work.
Now you have a Payment object. With that Payment object, you get a reference to the PaymentQueue, and added TransactionObserver. Once again, TransactionObserver here is going to give you a call back when the communication, Store Kit communication with the App Store succeeds. And then you call addPayment with that payment. You call PaymentQueue, you add a payment to the queue. What the PaymentQueue's going to do, is going to take a copy of your payment object and create a payment transaction. That payment transaction represents what you're trying to sell to the customer.
Store Kit then communicates with the App Store and presents a dialogue to the user. The customer then decides, is going to get to decide synchronously, interactively, do they want to make this purchase? Or do they decline this purchase? That's a dialogue that they get right there. Now if they haven't logged in, they're going to have to present their user credentials right then, their App Store user credentials. Once they make a decision, control is passed right back to your application and your TransactionObserver's updatedTransactions method is going to be called.
So how does that work? For each transaction in the queue, you're going to go through and you can look at the state of all those transactions. The first one's Purchasing. You can imagine a situation where a customer's on a train, they're playing with your app, they click by, they're excited, and they go into a tunnel.
So you added the payment to the PaymentQueue, but now Store Kit can't go connect to the App Store. Those transactions are going be state Purchasing. There could be a lot of different reasons why a transaction is state Purchasing and all this means, is that it's currently in progress, it's not completed.
At some point, it will get completed. Another state is Purchased. Purchased means that the customer, when presented with a dialogue, they agreed, they entered their credentials affirmatively, and payment on the App Store was collected. State Restored, this is how you're going to be able to implement giving access to all of a customer's purchases across all of their devices.
State Restored means when the customer was presented with the dialogue to agree to the purchase, they entered their credentials, when they went to the App Store the App Store decided that was a non-consumable, that the customer had purchased previously and so is not going to charge the user for that purchase. That transaction to the user was free. And lastly is state Failed which is the customer either declined their purchase, or they didn't enter their credentials in right.
When you get a response, a Purchased or Restored, that's when you unlock the feature that you're selling to your customer. Purchased or Restored. In both of those cases, the App Store has collected payment if necessary, if it was a brand new purchase, and your customer has an expectation of receiving something. It could be a feature you unlocked, it could be some content you're downloading, it could be access to a server, access to server content.
Now it's very important for you to validate these purchases. Just because Store Kit responded hey this worked, how do you know for sure that this is a transaction from the App Store? Well transactions contain a transactionReceipt. It's a cryptographic signed chunk of data that contains some information that's going to be interesting to you. It's signed by Apple, it's going to contain the Product ID of what the customer bought, it's going to contain your unique ID for your application, it's going to contain when the transaction happened, a unique transaction identifier.
And most importantly, you can take this transaction receipt, send it to Apple via a web service, and have Apple validate by the App Store, the App Store validates it, this is a transaction that originated in the App Store, it's a record in the database for that transaction. Let's go through that in detail. So I've got my app, I requested payment from the App Store, payment went through and I got a transactionReceipt.
What do I do with it? Well, what I'm going to do is post it to my server, because I trust my server. A server's in my co lo, it's under my direct control. So I'm going to take that transaction receipt, post it to my server, and then my server is going to post it to the App Store.
My server, your server, may choose to store that transaction receipt in a database somewhere at some kind of logging it or audit facility. Here's the URL for the service to verify receipt, buy.itunes.apple.com/verifyReceipt, it's a really simple service. It's just a JavaScript object notation post content. So you create adjacent object with a receipt-data field, and put in there the transaction receipt data that you received back from the Store Kit transaction observer transaction object. You take that, you post it to your server, and have your server post it to the App Store.
The App Store now is going to take that transaction receipt, it's going to verify the signature, it's going to go to the database, make sure that this is an authentic transaction, make sure that payment was required, it showed up, and it's going to respond back with verified. Well, status 0 means verified. Any other status means it wasn't verified.
Now your server, which you trust, can store away that this is a transaction that legitimately occurred on the App Store. And your server can come back to your app and say hey, this transaction's good. Go and unlock the feature, go and unlock the product, go and unlock the service that the customer just bought.
Let's talk about unlocking purchases real quick because your customers may quit at any time. Your customers may be on a train and they got their App Store purchase, they got the finished transaction, everything happened, but that they went in a tunnel and suddenly the transaction, you know, they don't have access to the internet anymore.
So what happens then? Well the PaymentQueue is persistent and not only that, transactions within the PaymentQueue are persistent. This means that it's really up to you to determine the policy about when to remove things from the PaymentQueue. You should only do it when you've confirmed access to the product, or service, or subscription that your customer just purchased.
If you have to go up to the cloud and say hey this purchase happened, you know, maybe its part of your transaction receipt process, store that this customer now has access to this subscription. You need to do that before removing the transaction from the queue. You remove transactions from the queue by calling the finishTransaction API with the transaction.
This is critical because this means that any kind of network issues, battery issues, the battery ran out and you couldn't go remove the transaction, all of this is dealt with because of this persistent nature of these queues. But you need to confirm access before removing the transactions from the queue not after. So once you've made the transaction, you know, you've got to remember the purchase. The next time the user, your customer launches your app, they shouldn't have to pay for it again so, you know, put a boolean in a key list somewhere.
Support Item Restore. Well, as I mentioned previously, you must make your customer's purchases available on all of their devices for their account. Just like apps today, where a customer buys it on one device and they go to another device, they're not going to get charged. In App Purchases are going to work the same way. If they wipe their phone, they re-download your app for free, they must have access to the products they purchased from you.
How's that going to work? If we've got an iPhone over here and I buy an app, today the App Store makes it easy and all I've got to do is get the App over on my iPod Touch. I can go buy it, and re-download for free. Items need to behave the same way. An item bought over here on the iPhone, needs to be made available over here on the iPod Touch. Same for Restores. When you restore a device, when a customer restores a device they must have access to your application, to your product.
So how's that going to work? Well, you could just depend on the Restored state which is customer, if they buy the same product twice, they're not going to be charged a second time. You could just depend on that. But you can do better, you can create a much better user experience with Store Kit.
Store Kit allows you to have, create functionality where you can provide user interface for your customer, which is give me everything I bought on one button. The API for that, it's on PaymentQueue, and its restoreCompletedTransactions. restoreCompletedTransactions is going to communicate with the App Store and Store Kit is going to have available, in that device's transaction queue, all of the transactions that the user has purchased on that account.
This is why it's so easy for you to provide products across the line of devices. If the user has 3 devices, they just go click the Restore Purchases button on all 3 of those devices. If I have access to a subscription, I just go click on that and it should show up. Pretty simple. Of course, once you call a restoreCompletedTransactions on the PaymentQueue, you're going to get back transactions in the StateRestored. This means that the customer was not charged for those products.
So those are the 10 steps for integrating with Store Kit. There wasn't a lot of code there. It's deceptively simple. It is easy to integrate with the App Store and integrate into your application. You've got a couple classes, a couple delegate methods, Store Kit takes care of the rest. Store Kit isn't imposing a business model on you. The reason this code is so short is because all the logic, all the business model is code that you have to write in your application. Now you built your app, it's time to test.
How do you do that? Well, we've got the Sandbox. Sandbox is for testing In App Purchase only and it's got a few restrictions. One of them is you can only use it from a device. It's important to note that Sandbox isn't a mode on your phone, there isn't some button hidden away in some preference somewhere that says turn on Sandbox.
The way Sandbox is enabled is to transfer an application onto a device via Xcode. Only applications that were transferred to a device by Xcode can access the Sandbox. If you have an application downloaded from the App Store, that cannot access the Sandbox. Invoices aren't sent from the Sandbox either. Sandbox is there for you to test your Store Kit API implementation.
And you need a separate Apple ID to test in the Sandbox. Your production account that you're using to make your own app purchases or your tester's production account, that's not going to work in the Sandbox. And furthermore, just like, in the real App Store, accounts are tied to a specific country.
You need to create an account for each country you want to test in. Now you'll want to do that if you're localizing into a number of languages to see what the currencies are like, that you set things up right, see what the names are right, is it fitting into your app.
So you'll want to create an account for each country you want to test. And a Sandbox account can't be used to test any other Store feature. Sandbox is there to text Store Kit API in your application. Furthermore if I make a stronger statement, which is your application installed by Xcode.
Now since these accounts are required and there's a unique email address per account, the reason we need a unique email address. Well the reason we need an email address is, if you forget the password to your account, we need a way to send it to you. And accounts need a unique email address, we recommend using + It turns out a lot of mail servers ignore everything between the + and the @ sign for determining which inbox to deliver the mail to. Mine does. So if I want to create a test account to test in the USA versus creating a test account in the UK, I would do [email protected] or [email protected]. When I create these accounts, email sent to [email protected] will be sent to [email protected].
Then we can have one inbox receiving all of the messages. Now here is the most important thing, if there's one thing you walk away from the presentation today, it should be this point right here. Before you start testing in the Sandbox, go to the Settings application, click on Store, and Sign Out. Let me repeat that.
Before you start testing your application in the Sandbox, go to the Settings application, click on Store, and click on Sign Out. The reason for this is, as I mentioned there is no mode for Sandbox, there isn't a checkbox or anything in Settings. So if you logged in and you launch your app with your production account logged in to your device, Store Kit is just going to use that account.
You're not going to get a chance to enter a different account's credentials. Now if you're not logged in and you launch your application, Store Kit will pop up, the authentication dialogue and you'll get an opportunity to enter your Sandbox credentials. So I'm going to repeat that one more time.
Before you start testing, Sign Out, and then launch your app to test. Creating users is pretty simple, you go to iTunes Connect, Manage Users, In App Purchase Test User, Create New. You've got to enter this information, as I mentioned, the information, the security information below is mainly there, it's only there so we can send you a password if you forget it. Click Save.
So that's how to test in the Sandbox. That's it. Pretty simple huh? Store Kit is a deceptively simple API to integrate with. Testing, writing the code, all those things, you're going to be able to sell products in your store pretty quickly when you integrate with Store Kit. Let's talk about financials real quickly. And it's quickly because well, there's not much to say. The rules are the same as applications.
You already know all the rules. You get 70%, payment schedule is the same, royalties are the same, reports are all the same. Well, they're not all the same, we actually did add some fields. The vendor ID fields contains the Product ID, remember that unique product identifier that we said all the way back in iTunes Connect? The vendor ID field contains the Product ID.