1. Code
  2. iOS SDK

iPhone SDK: In-App Purchases

Read Time:15 minsLanguages:

This iPhone SDK tutorial is the first in a multipart series on selling products and services "in-app" with the Store Kit framework. Expect to learn the benefits and limitations of using the In App Purchase feature, the steps necessary to register paid "in-app" content with Apple Inc., how to setup a simple store front, and the difference between the Built-In Product Model and the Server Product Model for content distribution and order fulfillment.

1. Prequalify Your Content

One of the most powerful features released with the iPhone SDK 3 is the ability to process "in app" purchases. Because the App Store handles payment authorization and processing on your behalf, this feature makes selling virtual goods or services significantly easier as developers are able to focus on creating and selling great content instead of more traditional e-commerce tasks like encrypting and storing credit card numbers or processing credit card batches. Using the in-app purchase feature will also streamline the checkout process for users as they simply need to enter their Apple username and password to authorize the transaction with their iTunes account.

Of course, these benefits come with a price tag: Apple will retain 30% of the sale, as they do on all direct App Store purchases. Choosing to utilize the App Store as your payment gateway will also require that you comply with the following business rules established by Apple:

  • No physical or real-world services allowed.
    Sorry, but groceries, t-shirts, and car washes can't currently be sold as an in-app purchase.
  • Virtual currency is not allowed.
    Apple will not currently allow the creation of a virtual economy with a direct intermediate currency.
  • Items or services purchased within your application must be accessed and used inside your application.
    Similar to the restriction on selling real-world goods, this prevents developers from selling things like coupons or offers redeemable outside of the app.
  • No defamation, hate speech, pornography or gambling.
  • Apple has published the following list of approved categories:
  • Content
    Includes digital books, magazines, photos, artwork, game levels, game characters, and other digital content that can be delivered within your application.
  • Functionality
    Products unlock or expand features you've already delivered in your application. For example, you could ship a game with multiple smaller games that could be purchased by the user.
  • Services
    Allow your application to charge users for one-time services, such as voice transcription. Each time the service is used is a separate purchase.
  • Subscriptions
    Provide access to content or services on an extended basis. For example, your application might offer monthly access to financial information or to an online game portal. You should define a reasonable renewal frequency to avoid bothering users with unwelcome reminders. Be aware that you are responsible for both tracking subscription expirations and renewal billing; the App Store does not monitor subscription duration and does not offer an automatic billing mechanism.

2. Create a new Xcode project and Import the Store Kit Framework

The Store Kit Framework provides the power and functionality that you will use to develop your in-app purchases. While the framework itself does not actually authorize your user's payments, it does act as a bridge between your application and Apple, allowing you to easily send and receive messages from the iTunes App Store.

Take a look at the following illustration from Apple Inc. to better understand this concept:

In App Purchase Request/Response Cycle

Open Xcode and create a new iPhone project, selecting "View Based Application" as the default application type. Name the application "InAppDemo" or insert a more creative title of your choosing.

In App Purchase Creating a new project in Xcode.In App Purchase Creating a new project in Xcode.In App Purchase Creating a new project in Xcode.

Right click the "Frameworks" folder in the Groups & Files pane, and select Add -> Existing Frameworks. Find StoreKit.framework and click "Add."

In App Purchases Adding the Store Kit Framework.In App Purchases Adding the Store Kit Framework.In App Purchases Adding the Store Kit Framework.

To use the framework in our project, we will need to add it to our project's view controller class. Expand the "Classes" folder and click on InAppDemoViewController.h.

Just beneath the "import UIKit" command, add this line:

Your application should now be able to take advantage of the Store Kit Framework functionality.

3. Register Premium Content With Apple Inc.

Each virtual product or service that you wish to sell in-app must be registered with Apple and assigned a unique product identifier. Surprisingly, these identifiers are generated in iTunesConnect, not in the Developer Program Portal.

For new applications, this presents the classic "chicken-or-egg" problem. In order to build your in-app purchase project, you need to generate product identifiers, but because product identifiers can only be created via iTunesConnect, your application must have already been submitted for publication.

The solution to this dilemma is to walk through the process of submitting your application for review by Apple, but select the "upload application binary later" checkbox when you come to the "Upload" tab. This will place your application in the "Waiting for Upload" state, which is what you want in order to avoid a formal review of your application while you are still integrating and configuring your in-app purchases.

Login to your iPhone developer account and navigate to the iPhone Provisioning Portal to begin the process of submitting a test application. If you aren't already a member of the iPhone Developer Program, you will need to sign up here.

After logging into the Provisioning Portal, select the "App IDs" tab. Click "New App ID."

You will need to enter a common name and a unique bundle identifier. The common name will be used to identify this App ID within the Provisioning Portal and the Bundle Identifier is a unique identifier for your actual application binary. When developing an application that will use in-app purchases, you must use a full Bundle Identifier. No "wild card" IDs are allowed.

In App Purchase Creating a new app id.In App Purchase Creating a new app id.In App Purchase Creating a new app id.

Click submit. You will be taken back to the main App IDs page.

Find your newly created App ID in the list, and then click the "Configure" link to the right of it.

On the "Configure App ID" screen, select the check box next to "Enable In App Purchase" and click the "Done" button:

In App Purchase Creating a new app id. Enabled.In App Purchase Creating a new app id. Enabled.In App Purchase Creating a new app id. Enabled.

You should now have a unique App ID that you can use to begin developing the in-app purchase feature with.

You will now create a test application submission, so leave the program portal and login to your iTunesConnect account at

Once in your account, select the "Manage Applications" option, then select "Add New Application" at the top left of the panel.

Walk through the screens presented for adding a new application, and be sure to select the "add application binary later" checkbox option on the "Upload" tab. In the process, you will likely need to upload a random test image for the 512x512 logo and the Primary Screenshot.

After you have completed your dummy submission, you will be taken back to the iTunesConnect application management landing page. Select the application submission you just created, and then select "Manage In App Purchases."

To add your first item, select "CREATE NEW" from the top left button.

You will now be asked to select the bundle identifier that your in-app purchases will be associated with. Select the unique Bundle Identifier you created earlier in this tutorial and click "Continue." If you are following the tutorial strictly, the bundle identifier to select is "com.mobiletuts.inapppurchasedemo."

Creating new In App Purchase.Creating new In App Purchase.Creating new In App Purchase.

You will now be presented with a set of options for Pricing on the "Create New In App Purchase" screen. As stated in the help tool tips, "Reference Name" is for identifying your purchase offer within iTunesConnect search results and "Product ID" will be used to identify your application in iTunesConnect reports.

Apple encourages you to choose between "Content," "Functionality," "Services," and "Subscriptions" when considering the possible categories for your in-app offerings, but, when it comes to actually submitting them to the store, you are forced to identify your app with one of three completely new types.

As described by Apple Inc., these types are:

  • Consumables:
    Products must be purchased each time the user needs that item. For example, services are commonly implemented as consumable products.
  • Non-consumables:
    Products may only be purchased once by users. Once a non-consumable product is purchased, it is always available on all devices associated with that user's iTunes account. Store Kit providers support to restore non-consumable products on other devices.
  • Subscriptions:
    Share attributes of both consumable and non-consumable products. Like a consumable product, a subscription may be purchased multiple times; this allows you to implement your own renewal mechanism in your application. However, subscriptions must be provided on all devices associated with a user. In App Purchase expects subscriptions to be delivered through an external server that you will provide. You must provide infrastructure to deliver subscriptions to multiple devices.

Select the one that is applicable for your offering type or "Consumable" if following this tutorial strictly. Note that once this type is set, it cannot be changed at a later time, so choose wisely.

Next, we set the offer price, which is done by selecting a price tier rather than directly entering a value. The In App Purchase price tier system is the same as the direct purchase tier system presented when initially uploading your application, but if you want to review your options again, click on the "See Pricing Matrix" text to the right of the drop down.

Go ahead and select "Tier 1" for the price or whichever tier matches your offering. Be sure to check the "Cleared for Sale" box, even though you aren't yet ready to launch your application. This box must be checked in order to debug and test your code.

The "Display Detail" field-set allows you to easily control offering localization. Select the language(s) you would like to list your offering in and add your custom display name and description. A meaningful and specific description is required by Apple for review approval.

Creating new in app purchase form.Creating new in app purchase form.Creating new in app purchase form.

For now, you can skip the Screenshot field set as it is purely a guide for the Apple employee's reviewing your product. Click "Save Changes" to register this offering with Apple. Repeat this process to add additional items for sale "in app."

This tutorial will use the following generic data for our offers, but feel free to be as creative as you'd like in inserting your own:

Product 1 | Consumable | com.mobiletuts.inappdemo.1 | Tier 1
Product 2 | Consumable | com.mobiletuts.inappdemo.2 | Tier 2
Product 3 | Consumable | com.mobiletuts.inappdemo.3 | Tier 3

4. Build Your Store Front

After you have registered your premium items with iTunesConnect, you are ready to begin integrating these offers into your app. For the purpose of this tutorial, we will use a simple UITableView to display our product listing.

Go to the header file for your main application view controller, in this case InAppDemoViewController.h, and modify the code to look like this:

The array productIdentifierList will store the product identifiers we created in Step 3 as strings, while productDetailsList will store the localized product information provided by the App Store and actually displayed to the user.

Now go to the class implementation file, InAppDemoViewController.m, and synthesize the variables you just declared in your header file:

Uncomment the viewDidLoad function, and initialize your data source:

In a real-world application, we would never want to put this purchase loading code in the viewDidLoad method because it will execute in the main thread and lock the application interface briefly while retrieving the data. We use viewDidLoad here only for demonstration purposes.

Starting on line 6, we create a for loop to iterate over the number of items we want to show. Because we use a common naming schema for our product identifiers, we can create multiple items on the fly without needing to type out each identifier by hand. Note that this pattern can be enhanced further with some Internet programming: your product identifier list would ideally be loaded from an external server in order to allow you to dynamically add or remove products without pushing a new binary through the App Store each time.

Starting on line 10, we are introduced to our first Store Kit Framework object, SKProductsRequest. This object is used to send a list of product identifiers to the App Store in order to receive back a list of localized product information and accurate product pricing information. This dynamic localization and product gathering technique allows you much greater flexibility than coding these attributes in by hand.

On line 12 we set the request delegate that the Store Kit Framework will call after receiving a result. Copy and paste the following code to conform to this delegate protocol:

The productsRequest method is called after the list of products has been retrieved from the App Store, and we assign that list of product objects from the App Store to our productDetailsList array for later use. The other two protocol methods function as expected.

Now we move on to setting up the UITableView that will be used to display our product information. Begin by setting up your nib file in Interface Builder. Expand the "Resources" folder in the Groups & Files pane and double click the InAppViewController.xib file to open Interface Builder.

From the Library Pane, drag a UITableView object to the In App Demo View Controller window. Right click the UITableView in the window and connect the dataSource and delegate to File's Owner. Then right click the File's Owner and connect productDisplayTableView with the UITableView object. Save and close the nib.

Go back to your view controller implementation file, InAppDemoViewController.m.

Paste in the following lines to satisfy the UITableViewDelegate and UITableViewDataSource protocol requirements:

Most of this is standard code for displaying text in UITableView cells. Note, however, that we create an instance of SKProduct, thisProduct, to retrieve the product data for the current row, and that we are able to easily retrieve localized product information from the object's data members. Refer to the official Apple SKProduct reference for more information on all the data members available.

You should now be able to compile and run your application, but there is a catch: In App Store purchases can only be tested on an actual device, so you will need to create and install a provisioning profile for this application in order to test the code.

After you have installed your provisioning profile and configured Xcode, build and run the application on your device. A basic table view with product titles is too simplistic for your real world app, but the beauty of the In App Purchase system is that the storefront skin is completely up to you. In future tutorials in this series, a more advanced interface will be created. In the meantime, stretch your creativity and use whatever design you would like to showcase your products!

5. Choose a Distribution Strategy

Before you start authorizing transactions and selling new content to your users, take a moment to think about how that new content will be delivered. The Store Kit framework will allow you to easily authorize a purchase, but you are on your own when it comes to order fulfillment. The Built-In Product Model and the Server Product Model are the two primary design patterns you can choose from to ensure your users get what they pay for.

Built-In Product Model

With the Built-In Product Model, everything a user may purchase is already included in the application when it is first downloaded. This content is locked or hidden from use until after an in-app purchase is made, at which point the offer becomes usable.

The following diagram from Apple Inc. illustrates the Built-In Product Model:

In App Purchase Built in Product Model LifecycleIn App Purchase Built in Product Model LifecycleIn App Purchase Built in Product Model Lifecycle

Server Product Model

In the Server Product Model, content is dynamically pushed to the user's device at the time of purchase from a server under your control. In the Server Product Model, you must add the additional step of verifying that the transaction receipt received from the client device is valid, and you may also need to setup a mechanism for identifying your users to ensure that subscriptions and other non-consumable products can still be accessed from any iPhone OS device the purchasing user owns, and not just from the device they initially purchased the item on (this is a business requirement from Apple). You are also responsible for negotiating the network connection to transfer what may be a considerable amount of text or multimedia data.

One of the primary benefits of the Server Product Model is that it allows you to sell a very large amount of content on-demand while keeping the initial download size of your application small. It is also much faster to create and deliver new premium content to your app because you should not need to push a new application binary through the iTunes Store in order to offer new items for sale.

The following diagram from Apple Inc. illustrates the Server Product Model:

Server Product Model CycleServer Product Model CycleServer Product Model Cycle

As you can see, the Built-In Product Model is the simpler of the two design patterns. It is easier to implement and maintain, but lacks the power of on-demand delivery. The Server Product Model is far more complex, but allows you to create new content with greater flexibility and speed, and also to keep your application size lean by providing large downloads only as needed.

Both the Built-In Product Model and the Server Product Model will be covered in detail in future parts of this series.

Now is a a good time to consider both of these distribution models and determine which is the best fit for your application.

Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.