IAP Introduction
Store is embedded in the app, and store KIT framework is used in IOS apps to implement in-APP purchase. The store kit connects to the App Store to complete user payment securely in place of the application. Store kit prompts the user to authorize the payment, and then notifies the application that "the user has completed the payment", so that the application can provide what the user has bought. IAP can be used for application enhancement or additional content, for example, in the following scenarios:
- Basic version of the application, purchase additional features
- Book reader application, allowing users to purchase and download new books
- Games, providing new environments (scenarios, levels, levels, etc)
- Online games allow gamers to purchase virtual properties (gold coins, items, equipment, etc)
- Digital magazine or Newsletter Subscription
Products
It can be defined in iTunes connect. IAP supports four types of products:
- Content: includes digital books, magazines, photos, covers, game levels, game roles, and other digital content that can be delivered by applications
- Functionality (function): Unlock or extend the features that the application has delivered. For example, you can purchase multiple games separately.
- Service: allows an application to provide a one-time paid service. Each service must be purchased separately.
- Subscribe: provides users with access to content or services in an extended manner. If the application provides monthly financial report or online portal website access
All products must be registered through iTunes connect in the app store. You must provide a unique product identifier and many other information applications use the store kit to communicate with the app store; after the user purchases the product, the app uses this ID to identify the product and can also be divided into the following types:
- Consumption type. You need to purchase this product each time you need it. A one-time service is usually consumable.
- Non-consumable model, each user only needs to buy once. Once purchased, all devices associated with the user account can be used. Store kit provides built-in support for using non-consumable products on multiple devices
- Automatic regeneration and subscription are delivered to all devices of the user like non-consumable devices. However, the automatic regeneration subscription must specify the subscription duration in iTunes connect. The app store automatically updates the subscription after it expires. If the user chooses not to allow automatic subscription, the subscription will be automatically canceled after expiration, and the user cannot access the product. The application is responsible for verifying whether a subscription is currently valid and obtaining the receipt of the most recent transaction.
- A free subscription is provided in newsstand. Once a user has registered a free subscription, all devices related to the account can access the subscribed content. FREE subscriptions do not expire and can only be provided in applications that enable newsstand.
- If the subscription is not auto-generated, an old mechanism for subscription with limited duration should be created, and auto-generated subscription should be used in place of this mechanism. There are three differences between auto-renewal and subscription:
-
- The subscription protocol is not specified in iTunes connect. The application is responsible for providing this information to users.
- The subscription can be purchased multiple times. The app store does not automatically update the subscription. The application is responsible for implementing subscription updates, checking for expiration, and prompting users to purchase again.
- The application must deliver a non-auto-generated subscription to all devices of the user. Store kit will not be automatically synchronized.
How to deliver purchased IAP featuresApplications need to design and implement delivery mechanisms that provide IAP products to users. There are currently two main types: built-in models and server models. In both models, you must track the list of products provided by the store and deliver them to users. Built-in Model
All the products to be delivered are included in the application. This model is mainly used to unlock applications. You can also use this model to deliver the content already provided in the application bundle. The main advantage of the built-in model is that you can quickly deliver products to users. Most built-in products should be non-consumable applications that can store product identifier in application bundle, to identify the corresponding IAP product. Apple recommends plist to record the product IDs of all built-in features. Content-based applications can use this technology to add new content without modifying the application code. After the user successfully buys the product, the application must unlock this feature and deliver it to the user. The easiest way to unlock the feature is to modify the application parameters. Application parameters are automatically backed up when you back up iOS devices. After you purchase a product, you can recommend that you back up the product. Built-in model:
- The application obtains the product ID list from the bundle.
- The application sends a request to the App Store to obtain products information.
- App Store returns products information
- The application uses this information to display a store to the user.
- The user selects an item from the displayed store
- The application sends a payment request to the app store.
- App Store processes the payment and returns a complete transaction.
- The application reads the transaction information and delivers the purchased content.
Server ModelIn the server model, we provide an independent server to deliver products to iOS applications. Server delivery is suitable for subscription, service, and content, because these products can be delivered by data without modifying the iOS app bundle. Games can also use servers to deliver new game environments (puzzles, levels, or levels ). Store kit no matter how your server interacts with IOS apps, it does not provide a mechanism to identify specific users. You need to provide a user mechanism to identify the users of your iOS app (for example, if you provide the subscription service and need to be associated with the user, you need to implement the user mechanism on your own ). Server Model:
- The application sends a request to the server to obtain the list of all products IDs.
- The server returns the products ID list.
- The application sends a request to the App Store to obtain the products information.
- App Store returns Product Information
- The application uses this information to display a store interface to the user.
- The user selects an item from the store.
- The application sends a payment request to the app store.
- App Store processes the payment and returns the completed transaction.
- The application obtains the receipt data from the transaction and sends it to the server.
- The server records the receipt data and establishes an audit trail (Review Trail)
- The server sends the receipt data to the App Store to verify whether the transaction is valid.
- App Store parses the receipt data, returns the receipt, and the verification result (legal or not)
- The server reads the returned receipt data and determines which user has completed the purchase.
- The server delivers the purchased content to the iOS app
It is best for an application to obtain the products identifier through your server, instead of directly storing it in a plist file. In this way, you can add new products without updating the application. In the server model, the application obtains and sends the transaction-related signature receept to the server. The server then verifies the receipt and decodes it to determine what content needs to be delivered to the application. Non-consumable products can be restored using the built-in functions of store kit, but non-auto-generated subscriptions must be restored by your server. You are responsible for recording non-auto-generated subscription information and restoring it to users. Consumable products can also be recorded on the server, for example, allowing users to obtain service results on multiple devices.
Get product informationWhen an application displays a store to a user, the information obtained from the App Store must be displayed on the page.
Send a request to the App StoreStore kit provides a general mechanism to send requests to the app store. Create and initialize a request object. Specify a delegate to initiate a request. After App Store processes the request, it asynchronously calls delegate to notify the application of the Request result. As shown in:
SkrequestSkrequest is an abstract base class used to send requests to store.
SkrequestdelegateSkrequestdelegate is a protocol that is implemented by the application to process the store success or failure results.
Obtain products informationApplication Usage
Products requestTo obtain the localized product information. The application creates a request that contains a list of products ID strings. After a request is initiated, the products ID is transmitted to the app store. App Store returns the localized products information you registered in iTunes connect. The application uses this information to show that before the store allows users to purchase products, they must first use this product ID to query detailed information from the App Store to ensure that the product ID is legal, in addition, it is commercially available in iTunes connect.
SkproductsrequestThe skproductsrequest object is created using a set of product IDs. These are the product lists you want to display to users.
SkproductsrequestdelegateThe skproductsrequestdelegate protocol must be applied to obtain store response information. After the request is processed successfully, the App Store response information is received asynchronously.
SkproductsresponseThe skproductsresponse object is the returned result. Each valid product ID in the request list has a corresponding skproduct object. It also contains a list of product IDs that cannot be recognized by store. There are many unrecognized causes: Incorrect ID spelling, unsalable tags, and modifications in iTunes connect that have not been transferred to other app store servers.
SkproductThe skproduct object provides detailed localization information for the product you registered in the app store.
Purchase (purchase)When the user is ready to purchase the product, the application requests the App Store to complete the payment. App Store creates a persistent transaction. Even if the user exits and restarts the application, it continues to process the payment transaction. App Store synchronizes the pending transaction list to the application and delivers the updated information to the application when any transaction status changes.
Collect paymentThe application creates a payment object and adds it to the payment queue, as shown in. When the payment is added to the queue, a persistent transaction is created to save it. After the payment process is complete, the transaction will be updated to collect the status information after the payment. The application implements the observer to receive transaction updates. The observer is responsible for providing the purchased content to the user and removing the transaction from the payment queue.
Skpayment
Use a payment object to collect payments. The payment object contains a product ID and an optional purchase quantity. You can queue the same payment object multiple times, and each time it is queued, it will lead to a separate request. You can disable application purchase in "Settings. Before queuing a purchase request, the application must first confirm that the payment can be processed and call the canmakepayments method of the payment queue.
SkpaymentqueueThe payment queue is used to communicate with the app store. When the payment is added to the queue, store kit transmits the request to the app store. Store kit displays a dialog box asking users to authorize payment. The completed transaction is returned to the application's observer for processing.
SkpaymenttransactionWhen each payment is added to a queue, a corresponding transaction is created. Each transaction has some attributes that allow the application to determine the transaction status. After the payment collection is complete, the transaction object also contains detailed information about the successful transactions. Although the application can obtain the list of pending transactions from the payment queue, a more common practice is to wait until the payment queue actively notifies the observer and transmits the updated transaction list.
SkpaymenttransactionobserverAn object of the application implements the skpaymenttransactionobserver protocol and adds the object as the observer of the payment queue. The primary responsibility of the observer is to check completed transactions, deliver successfully purchased products, and then remove these completed transactions from the payment queue. The application should be associated with the observer to the payment queue at startup, instead of waiting for the user to try to purchase. Transaction will not be lost after the application is terminated. The next time the application is started, store kit will continue to process these transactions. Adding an observer during application initialization ensures that all transactions are successfully transferred to the application.
Restore transactionOnce the transaction is processed and removed from the queue, the application will not see it again. However, if the product type supported by the application must be retainable, you must include an interface that allows users to restore these purchases. This interface allows you to add the purchased product to another device, or restore the transaction after the original device is reset. Store kit provides a built-in mechanism for restoring non-consumable transactions, auto-generated subscriptions, free subscriptions, and other product transactions. When the application calls the restorecompletedtransactions method of the payment queue, the payment queue sends a request to the App Store to restore the transaction. App Store generates a new restoration transaction for all previously completed transactions. Restore the originaltransaction attribute of the transaction object to save the original transaction. The app processes the restored transaction, obtains the original transaction from it, and uses the original transaction object to unlock the user's purchased content. In store
When kit restores the previous transaction, it notifies the observer object of the payment queue and calls its paymentqueuerestorecompletedtransactionsfinished: method. If a user tries to purchase a recoverable product (instead of using your Restoration Interface), the application will receive a normal transaction instead of a recoverable transaction. However, you do not need to pay for this product again. The application should treat these transactions as original transactions. Non-auto-generated subscriptions and consumable products are not automatically restored by store kit. However, non-auto-generated subscriptions must be restored. Therefore, when purchasing these products, you must record these transactions on your server, it also provides its own mechanism to restore all devices of these transactions to the user.
Add a store (built-in model) to an application)First, ensure that the project links storekit. Framework. The detailed steps for adding a store to an application are as follows:
1. Define the products to be delivered by the application.
Store kit has some restrictions on products. It does not allow apps to patch themselves or download additional code. Products can be implemented either by using the existing Code of the application or by downloading data files from the remote server. If you need to modify the existing code when adding features to an application, you must publish a new version of the application. 2. register details for each product in iTunes connect. To add a new product to the App Store, you must first register the product in iTunes connect. Each product requires a unique ID string. App Store uses this string to search for product information and process payment requests. The product ID is specific to the iTunes connect account. The method of registration is similar to that of Application Registration. 3. Make sure that the system can process the payment. Users can disable in-APP purchase. Therefore, you must first check whether in-APP purchase is supported. The application can perform this check before displaying the store to the user or before initiating the purchase request. The latter allows the user to view the products that can be purchased, even if the in-APP purchase is currently prohibited. If ([skpaymentqueue canmakepayments]) {... // display store} else {... // warn the user that the in-APP purchase is currently prohibited} 4. obtain the information of products. The app creates a skproductsrequest object and initializes it as a group of product IDs you want to sell. Add a delegate to process the request and return the result. Then, you can initiate this request. The Response Results save all valid products localization information. The application must first obtain the product information before creating a payment request. -(Void) requestproductdata {skproductsrequest * request = [[skproductsrequest alloc] initwithproductidentifiers: [nsset setwithobject: kmyfeatureidentifier]; request. delegate = self; [request start];}-(void) productsrequest :( skproductsrequest *) Request didreceiveresponse :( skproductsresponse *) response {nsarray * myproduct = response. products; // display the information to the store interface [Request autorelease];} 5. add a user interface to display pro Ducts does not provide user interface classes for user store kit. How to display store to users is an application. 6. Register a transaction observer to the payment queue application to instantiate a transaction observer and register it to the payment queue. Mystoreobserver * Observer = [[mystoreobserver alloc] init]; [[skpaymentqueue defaultqueue] addtransactionobserver: Observer]; as mentioned above, it is best to register observer at startup. Before the transaction is completed, the app store still remembers the transactions. Register the observer at startup to ensure that all the results of the previous queued transactions can be received by the application. 7. implement paymentqueue: updatedtransactions in the mystoreobserver object of the application: paymentqueue: updatedtransactions of the observer method: the method will be called when a new transaction is created or updated-(void) paymentqueue :( skpaymentqueue *) queue updatedtransactions :( nsarray *) Transactions {for (skpaymenttransaction * transaction in transactions) {Switch (transaction. transactionstate) {Case skpaymenttransactionstatepurchased: [self completetransaction: transaction]; break; c ASE skpaymenttransactionstatefailed: [self failedtransaction: transaction]; break; Case skpaymenttransactionstaterestored: [self restoretransaction: transaction]; default: Break ;}} 8. after successful purchase, the observer provides the corresponding product-(void) completetransaction: (skpaymenttransaction *) Transaction {// The application needs to implement these two methods: record transactions and provide content [self recordtransaction: transaction]; [self providecontent: transaction. payment. productidentifie R]; // delete a transaction from the payment queue [[skpaymentqueue defaultqueue] finishtransaction: transaction];} a successful transaction contains a transactionidentifier attribute and a transactionreceipt attribute, detailed information about the processed payment is recorded. The application does not need to process the information. Of course you may want to record this information and create an audit trail for the transaction ). If the server is used to deliver the content, the application can send the receipt to the server, and then the server verifies the transaction to the app store. Once you complete the delivery of the product to the user, the application must call finishtransaction: to complete the transaction, and the transaction will be removed from the payment queue. To ensure that products is not lost, the application should deliver the content before calling finishtransaction. 9. process the restored purchase and end the transaction-(void) restoretransaction: (skpaymenttransaction *) Transaction {[self recordtransaction: transaction]; [self providecontent: transaction. originaltransaction. payment. productidentifier]; [[skpaymentqueue defaultqueue] finishtransaction: transaction];} This method is similar to the previous Purchase. A restoration purchase is a new transaction with different transaction IDs and receipts. You can save this information separately and establish review tracking. However, when the transaction is completed, you still need to restore the original transaction, which stores the actual payment object and product ID. 10. Failed to process the purchase, end the transaction-(void) failedtransaction: (skpaymenttransaction *) Transaction {If (transaction. Error. Code! = Skerrorpaymentcancelled) {// an error can be displayed (optional)} [[skpaymentqueue defaultqueue] finishtransaction: transaction];} the user decides not to purchase a transaction because the transaction fails. The application can read the error field of a failed transaction to learn why the transaction failed. For a failed transaction, the only thing the application needs to do is remove it from the queue. If the application displays a dialog box after the transaction fails to tell the user that the transaction has an error, you should avoid this error when the user cancels the transaction. 11. After completing all the above, you can display the user interface. When you select an item in the store, the application creates a payment object and adds it to the payment queue. Skpayment * payment = [skpayment identifier: kmyfeatureidentifier]; [[skpaymentqueue defaultqueue] addpayment: payment]; if the store provides the function of purchasing multiple products at a time, you can create a payment object, specify the quantity attribute skmutablepayment * payment = [skmutablepayment paymentwithproductidentifier: kmyfeatureidentifier]; payment. quantity = 3; [[skpaymentqueue defaultqueue] addpayment: payment]; The above code example is mainly used to build the product model. If your app uses a server to deliver content, you need to design and implement the protocol for communication between the iOS app and the server. Your server also needs to verify receipts before delivering products to the application.
Verify store receiptAfter receiving the accesskey of the Apple Store kit, you should perform an additional receept check to verify the validity of the transaction. If an application relies on an independent server to provide subscriptions, services, and downloadable content, it is very important to verify receipt. The server verifies receipt to ensure that the request sent by the iOS app to the server is valid. The content and format of store receipt are private and may change. The application cannot directly parse the receipt data. Use the mechanism described below to verify the receipt and obtain the information stored in the receipt.
Verify a receipt from the App Store.When the store kit returns an observer of the purchased payment queue, the transactionreceipt attribute of the transaction contains a signed receept, which records all key transaction information. The server can post the receipt to the App Store to verify that the receipt is legal and has not been tampered. Send and receive requests directly to the App Store using JSON dictionary, as defined in RFC 4627. Perform the following steps to verify the receipt: 1. obtain the data from the transactionreceipt attribute of transaction and encode it with base64. create a JSON object with only one key named "receipt-data". Its value is a string created in step 1. The JSON object is as follows: {"receipt-Data": "(actual receipt bytes here)"} 3. use http post request, post this JSON object to App Store, URL: https://buy.itunes.apple.com/verifyReceipt4. the response received from App Store is also a JSON object with two keys: Status and receip. As shown in the following figure: {"status": 0, "receept": {...} if the value of status is 0, it indicates that it is a legal receipt. Otherwise, the receipt is invalid.
Store receiptThe receipt data you sent to the App Store is encoded with the transaction information. When the App Store verifies the receipt, it first decodes the receipt data and returns it in the response. The receipt response is a JSON dictionary that contains all the information of the skpaymenttransaction object in the application. Therefore, the server can query these JSON fields to obtain detailed information about the user's purchase. Apple recommends that the iOS app only send the receipt data to the server, instead of sending the transaction data to the server, and then the server goes to the App Store to verify the receipt. App Store verifies that the receipt data is not tampered. Server from app
It is more secure to obtain transaction information from the store response receipt data, instead of sending transaction information directly to the server by the iOS app. The following table lists the information you can obtain from the response receept. Many keys directly correspond to the attributes of the skpaymenttransaction class. Keys not specified in the table are retained by Apple and cannot be used.
Key |
Description |
Quantity |
The number of purchases, corresponding to the transaction. Payment. Quantity attribute. |
Product_id |
The product ID, which corresponds to the transaction. Payment. productidentifier attribute. |
Transaction_id |
The transaction ID, which corresponds to the transaction. transactionidentifier attribute. |
Purchase_date |
The date and time when the transaction occurred, corresponding to the transaction. transactiondate attribute |
Original_transaction_id |
For restored transactions, this value stores the original transaction ID |
Original_purchase_date |
For restored transactions, this value stores the original transaction date |
App_item_id |
String, which uniquely identifies an iOS app that creates a payment transaction. If your server supports multiple IOS applications, you can use this value to differentiate different applications. The application running in sandbox does not have app_item_id, so this key does not exist. |
Version_external_identifier |
Uniquely identifies any number of your application revision. The Sandbox application does not have this key. |
Bid |
Bundle ID of the iOS app |
Bvrs |
IOS app version |
Test storeDuring development, you need to test the application store to ensure normal operation. However, you cannot pay for it. Therefore, you need to use the sandbox store test provided by Apple. Store kit cannot be used in IOS simulators. Test store must be performed on a real machine.
Sandbox EnvironmentWhen you start an application from xcode, the store kit does not connect to the app store. On the contrary, it will connect to a special sandbox store environment. The Sandbox environment uses the App Store infrastructure, but no actual payment is made. A successful payment is returned in the sandbox environment, as if you actually purchased the payment. The Sandbox environment uses a special iTunes connect account and can only be used to test in-APP purchase. Normal iTunes cannot be used
The CONNECT account is tested in sandbox. You need to create one or more special test accounts in iTunes connect. At least one test account is required for each localization region. For more information, see the iTunes connect developer guide.
Testing in the sandboxTo test the function in sandbox, follow these steps: 1. log out of the current iTunes account on the iOS device. Before testing the application, you must log out of the normal iTunes account. IOS 3.0 contains a store category in the setup program. You can log out of the current account. Remember: Do not log on to your test account in the settings; otherwise, the test account will be invalid. once you exit the normal account, you can run your application in xcode. When you submit the payment in the application, the store kit will prompt you to authorize the transaction. Log On with the test account and agree to pay. No fee deduction will occur at this time, but the fair will be completed normally.
Verify receipts in sandboxYou can also verify the receept in the sandbox. The code for executing the verification is the same as that of the common app store, but the URL of the sandbox environment is different: nsurl * sandboxstoreurl = [[nsurl alloc] initwithstring: @ https://sandbox.itunes.apple.com/verifyReceipt];
Auto-renewable subscriptionIn-APP purchase provides a standardized method for automatic regeneration and subscription. Automatic regeneration subscription has the following features: 1. When configuring automatic regeneration subscription in iTunes connect, you must specify the subscription duration and other options. 2. Auto-renewable subscription will be automatically restored, and the same store kit function will be used like non-consumable products. The original transaction, and each regenerative transaction, will be sent to the application. 3. When the server verifies receipt to the App Store, if the subscription is active and is automatically regenerated by the App Store, the app store returns an updated receipt
Add auto-regeneration subscription to storeFollow these steps to implement auto-renewable subscription: 1. Connect to iTunes connect and create a new "Shared Secret ". Shared Secret is a password, which must be provided by the server when verifying the receipt subscribed by auto-renewable. In this way, an additional layer of security protection is added between the App Store and the App Store. 2. Add and configure a new auto-renewable subscription type in iTunes connect. 3. Modify the server's recesight verification code and add shared secret to the recesight JSON data sent to app store. The verification code of the server must parse the response data of the app store to determine whether the subscription has expired. If the subscription is updated by the user, the app store returns the latest receipt to your server.
Design your iOS client applicationIn most cases, the iOS app supports auto-renewable subscription only with a small modification. In fact, the client application is now easier, because you can use the same code to restore auto-renewable subscriptions, the same way as restoring non-consumable products: when the application subscribes to updates, an independent transaction is received, and the application only needs to verify each receipt separately.
Verify auto-renewable subscribe to receiptIt is almost the same as the previously verified store receipts. Create a JSON object and post it to the app store. The only difference is to add the second domain: Shared Secret, that is, the {"receipt-Data": "(actual receept bytes here) you created in iTunes connect" password ": "(shared secret bytes here)"} The response contains a Status field, indicating whether receipt has passed the verification {"status": 0, "receept ":{...} "latest_receept": "(base-64 encoded receept)" "latest_receipt_info ":{...}} if the user's receipt is valid and active, the Status field is 0, and the receipt field contains the decoded receipt data. If the status received by the server is not 0, the following error code can be used to parse the error.
Status |
Description |
21000 |
App Store cannot read the JSON object you provide |
21002 |
There is a problem with the data in the receipt-data domain. |
21003 |
Receipt cannot pass Verification |
21004 |
The provided shared secret does not match the shared secret in your account. |
21005 |
The receipserver is currently unavailable. |
21006 |
Receipt is valid, but the subscription has expired. When the server receives this status code, the receipt data is still decoded and sent together. |
21007 |
Receipt is a verification service sent to the production system, but is sandbox receept. |
21008 |
Receipt is a validation service that produces receept but is sent to the sandbox environment. |
Note: The status codes here can only be used for auto-renewable subscription. Other types of products cannot use these status codes to determine the receipt data of the JSON object returned by the App Store to your server, in addition to the previous keys, the following keys are added or modified:
Key |
Description |
Expires_date |
The expiration date of the receipt subscription, the number of seconds since GMT. This key is not included in the restoration transaction. |
Original_transaction_id |
The transaction ID at the time of initial purchase. This ID is shared in subsequent subscription updates and restores. |
Original_purchase_date |
The initial purchase date, indicating the subscription start date. |
Purchase_date |
The date on which the transaction payment occurred. For the renewable subscription, this may also be the date of the last subscription update. |
In addition, JSON also contains two additional domains: latest_receept and latest_expired_receipt_info. Both of these are receipt objects. Your server can use these two domains to record recent subscription updates.
Restore auto-renewable subscriptionApp Store creates an independent transaction each time it updates the subscription. When purchasing your app before restoration, store kit will pass all transactions to the app. Therefore, the application needs to combine the purchase date and subscription length of each transaction, and then determine whether the receipt is legal. From: http://blog.csdn.net/kevin_zqw/article/details/6973473