IAP(In-App Purchase) Programming Notes

iOS Dev Lib Reference


At a Glance

States of the purchase process

iTunes Connect Configurations

  • Configure IAP products.
  • Test IAP products.
  • Submit IAP products for review.
  • Manage the IAP products available in the app.
  • iOS dev lib reference

Retrieving Product Information

displaying store UI

  • Get a list of product identifiers.
    • Product ids can be retrieved through network or app bundle.
    • Product ids are configured in iTunes Connect, and formed like: “com.example.level1”, “com.example.rocket_car”.
  • Retrieving product information.
    • Create a instance of SKProductsRequest and initialize it with a list of product ids.
    • The SKProductsRequest should be kept with a strong reference in case of instant deallocation.
    • Results – both valid and invalid ones – are called back to the delegate.
    • Valid products are encapsulated as a list of SKProduct objects, from which we can get the titles/descriptions/prices.
  • Presenting the app’s store ui.
    • Users can be restricted to access the store payment. Call canMakePayments class method (SKPaymentQueue) before displaying the store ui or an error message.
    • Users should be informed exactly what they are going to buy.
    • Display prices clearly, using the locale and currency returned by the App Store.
    • A product’s price formatting example:
      NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
      [numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
      [numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
      [numberFormatter setLocale:product.priceLocale];
      NSString *formattedPrice = [numberFormatter stringFromNumber:product.price];
  • Suggested testing steps: iOS Dev Lib Ref

Requesting Payment


  • Creating a payment request.

      SKProduct *product = <# Product returned by a products request #>;
      SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:product];
      payment.quantity = 2;
  • applicationUsername of the SKMutablePayment object can be populated with a one-way hash of the user’s app account name for further authorization.

  • Submitting a payment request.

      [[SKpaymentQueue defaultQueue] addPayment:payment];

Delivering Products

delivering products

  • Waiting for the App Store to process transations.
    • Central role: transaction queue
    • Payment requests are added to the transaction queue.
    • When the transation’s state changes, Store Kit calls the app’s transaction queue observer.
    • The observer must conform to the SKPaymentTransactionObserver protocol.
    • Register the observer at launch time, and make sure that the observer is ready to handle a transaction at any time.

        - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
            /* ... */
            [[SKPaymentQueue defaultQueue] addTransactionObserver:observer];
    • If your app fails to mark a transaction as finished, Store Kit calls the observer every time your app is launched until the transaction is properly finished.
    • Store Kit call the paymentQueue:updatedTransactions: method when the status of a transaction changes.
    • The transaction status tells you what action your app needs to perform:

      Status Action to take in your app
      SKPaymentTransactionStatePurchasing Update your UI to reflect the in-progress status, and wait to be called again.
      SKPaymentTransactionStateDeferred Update your UI to reflect the deferred status, and wait to be called again.
      SKPaymentTransactionStateFailed Use the value of the error property to present a message to the user. For a list of error constants, see SKErrorDomain in StoreKit Constants Reference.
      SKPaymentTransactionStatePurchased Provide the purchased functionality.
      SKPaymentTransactionStateRestored Restore the previously purchased functionality.
    • Responding to transaction statuses:

        - (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));
    • Implement paymentQueue:removedTransactions: method to remove the corresponding items from app’s UI.
    • Implement paymentQueueRestoreCompletedTransactionsFinished: or paymentQueue:restoreCompletedTransactionsFailedWithError: method to reflect the restoring result.
  • Finishing the transaction

Preparing for App Review

iOS Dev Lib Ref