In App Purchase

In-App Purchase

IAP 阶段

In-App Purchase Stage

Create And Configure Products in iTunes Connect

Products are reviewed when you submit your app as part of the app review process. Before users can buy a product, it must be approved by the reviewer and you must mark it as “cleared for sale” in iTunes Connect.

Product Types

  • Consumable products
  • Non-consumable products
  • Auto-renewable subscriptions
  • Non-renewable subscriptions
Product type Non-consumable Consumable
Users can buy Once Multiple times
Appears in the receipt Always Once
Synced across devices By the system Not synced
Restored By the system Not restored
Subscription type Auto-renewable Non-renewing
Users can buy Multiple times Multiple times
Appears in the receipt Always Always
Synced across devices By the system By your app
Restored By the system By your app

Non-renewing subscriptions differ from auto-renewable subscriptions in a few key ways. These differences give your app the flexibility to implement the correct behavior for your needs, as follows:

  1. Your app is responsible for calculating the time period that the subscription is active and determining what content needs to be made available to the user.

  2. Your app is responsible for detecting that a subscription is approaching its expiration date and prompting the user to renew the subscription by purchasing the product again.

  3. Your app is responsible for making subscriptions available across all the user’s devices after they’re purchased and for letting users restore past purchases. For example, most subscriptions are provided by a server; your server would need some mechanism to identify users and associate subscription purchases with the user who purchased them.

App Interacts with the App Store to Sell Products


Getting a List of Product Identifiers

Retrieving Product Information

// Custom method
- (void)validateProductIdentifiers:(NSArray *)productIdentifiers
SKProductsRequest *productsRequest = [[SKProductsRequest alloc]
initWithProductIdentifiers:[NSSet setWithArray:productIdentifiers]];

// Keep a strong reference to the request.
self.request = productsRequest;
productsRequest.delegate = self;
[productsRequest start];

// SKProductsRequestDelegate protocol method
- (void)productsRequest:(SKProductsRequest *)request
didReceiveResponse:(SKProductsResponse *)response
self.products = response.products;

for (NSString *invalidIdentifier in response.invalidProductIdentifiers) {
// Handle any invalid product identifiers.

[self displayStoreUI]; // Custom method

Requesting Payment


Creating a Payment Request

SKProduct *product = <# Product returned by a products request #>;
SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:product];
payment.quantity = 2;

Submitting a Payment Request

[[SKPaymentQueue defaultQueue] addPayment:payment];

For every payment request your app submits, it gets back a corresponding transaction that it must process.

Delivering Products


Register a transaction queue observer when your app is launched. Make sure that the observer is ready to handle a transaction at any time, not just after you add a transaction to the queue.

- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
/* ... */
[[SKPaymentQueue defaultQueue] addTransactionObserver:observer];

Implement the Protocol on your observer

- (void)paymentQueue:(SKPaymentQueue *)queue
updatedTransactions:(NSArray *)transactions
for (SKPaymentTransaction *transaction in transactions) {
switch (transaction.transactionState) {
// Call the appropriate custom method for the transaction state.
case SKPaymentTransactionStatePurchasing:
[self showTransactionAsInProgress:transaction deferred:NO];
case SKPaymentTransactionStateDeferred:
[self showTransactionAsInProgress:transaction deferred:YES];
case SKPaymentTransactionStateFailed:
[self failedTransaction:transaction];
case SKPaymentTransactionStatePurchased:
[self completeTransaction:transaction];
case SKPaymentTransactionStateRestored:
[self restoreTransaction:transaction];
// For debugging
NSLog(@"Unexpected transaction state %@", @(transaction.transactionState));

Subscriptions Require Additional Application Logic

Author: Chen
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.