iOS internal purchase: automatic renewal subscription summary

Posted by Chappers on Sun, 26 Sep 2021 08:06:35 +0200

There are four types of internal purchase: consumer goods, non consumer goods, non renewal subscription and automatic renewal subscription. As the name suggests, the most difficult is the implementation of automatic renewal subscription. After opening automatic renewal subscription, the processing of subscription members will encounter the following problems: the expiration of automatic subscription, the processing of automatic subscription, the processing of automatic subscription cancellation, After canceling, you can start automatic subscription processing in the App Store. I hope that through this article, I can provide complete ideas to those in need, and hope readers can discuss growth together.

1. Preparation for automatic Subscription Renewal

Early preparation is nothing more than the option of building internal purchase in the App Store. There are many articles on this part of the Internet. I directly recommend reading this article   Buy the latest version of iOS (buried pit) - simple book   Complete preliminary preparation and some common sense knowledge. Of course, I also directly integrate IAPHelper in the project   Carry out API integration for internal purchase.

2. Automatic renewal server verification

The main references are as follows:

The above part solves the function of internal purchase of consumer goods.
But this article is an automatic subscription: so you need to add a parameter: password: secret key, but the official document says that the secret key is only used for automatic renewal
We ask the background to add a verification. If Apple verification returns 21004 (the shared key provided by 21004 is inconsistent with the shared key of the account), add the password field to verify. It can succeed.   Secret key   Created in the corresponding APP


Verified: after the automatic renewal subscription is purchased, the password field must be brought when verifying the internal purchase (even for consumer goods).

3. Automatic renewal server verification problem

2 mainly refers to the successful internal purchase of the mobile phone, and then send the receipt to the server for verification. Then did you think of many problems to be solved?
3.1 processing of subscription status

  1. Apple provides server-to-server notification processing:
    Enable server notifications for auto renew Subscriptions: Reference
  2. Of course, check out Apple's documentation: a programming guide for in app purchases 
  3. Status update notification
    The following introduction can be seen in the middle of the second website:
    A   statusUpdateNotification is a server to server notification service used to automatically renew subscriptions. Notifications specify the subscription status when notifications are sent.
    To get the latest information when processing events, your app should verify the latest receipt through the App Store. It is recommended that you use the status update notification service and receipt verification to verify and service the user's current subscription status. For information on receipt verification, see the "receipt verification programming guide".
    To receive status update notifications, configure the subscription status URL for your app in App Store Connect. The app store will send JSON objects to your server through HTTP POST to obtain the key subscription events listed in table 6-3. Your server is responsible for parsing, interpreting and responding to all status update notification posts.
    However, there are only five states: INITIAL_BUY,CANCEL,RENEWAL,INTERACTIVE_RENEWAL,DID_CHANGE_RENEWAL_PREF. The notification that the user automatically subscribes without operation is missing??!
  4. User has no action to automatically subscribe to notifications

 If you read the description of the RENEWAL event, you will note - "Automatic renewal was successful for an expired subscription. Check Subscription Expiration Date to determine the next renewal date and time." In general, iTunes will attempt to charge the user account a day before an auto-renewing subscription is scheduled to expire. If the renewal is successful, there is no server-to server notification because the auto-renewing subscription did not enter into an expired state. However, in the few cases that iTunes is unable to renew the subscription (generally there was a connection problem with the credit card server) and the auto-renewing subscription is not renewed before the expiration_date passes, the auto-renewing subscription is technically considered "expired". However, iTunes will still continue to attempt to renew the subscription. It iTunes is successful, then the "RENEWAL" event is sent. for this reason, the advice is presented - "Check Subscription Expiration Date to determine the next renewal date and time."

The main treatments are as follows:
If you read the description of the RENEWAL event, you will notice - "the automatic RENEWAL of expired subscriptions succeeded. Check the subscription expiration date to determine the next RENEWAL date and time." typically, iTunes attempts to charge the user account the day before the scheduled automatic RENEWAL subscription expires. If the RENEWAL is successful, there is no server to server notification because the automatic RENEWAL subscription does not enter the expired state. However, in a few cases, iTunes cannot renew the subscription (usually there is a connection problem with the credit card server) and is in expiration_date automatically renews a subscription through an automatic RENEWAL subscription that has not been renewed before. Technically, an automatic RENEWAL subscription is considered "expired". However, iTunes will continue to try to renew its subscription. ITunes succeeds, and then sends a "RENEWAL" event. For this reason, a suggestion was made - "check the subscription expiration date to determine the next RENEWAL date and time".

To verify that the auto renew subscription in app purchase is up-to-date, verify appstorereceive using the verifyreceive server. Hypothesis in_ If there is an auto renew subscription item in the app array, view latest_receipt_info record and look for expires that are later than the current date_ One of the subscription records of date is not set with cancellation_date field. Note: the unique identification of the refunded order is: it has a cancellation_date field.
reference resources:

be careful

in_app and latest_receipt_info
During the test, it is found that the values of these two fields are almost the same, but there are several points to note:
(1) Automatically renew the subscription type. After expiration, another purchase record will be generated, which will appear in last_receipt_info, but not in in_ In app
(2) Trial can be configured for automatic renewal subscription type. Trial records can only be used in latest_receipt_info, is_ trial_ The period field is true
(3) Consumptive purchase records may not appear in latest_receipt_info, so you need to check in_app to ensure that the verification is correct

User unsubscribe

After purchasing a subscription, you have to pay in full. You can only get a refund by contacting Apple customer service. For example, if the user accidentally buys the wrong product, the customer service center can cancel the transaction and refund. Users cannot change in the middle of the subscription cycle. Be careful not to pay for the remaining subscriptions.
To confirm whether a transaction has been cancelled, look up the Cancellation Date field in the receipt. If the field has a date, no matter what the expiration date of the subscription is, the transaction has been cancelled - canceling the transaction is the same as not buying.
Depending on the product type, you can only check the current active transactions. You may need to check all past transactions. For example, a magazine application needs to check all past transactions to determine which journals users have accessed.

Attached is the ticket for automatic subscription:

string(42) ""
string(16) "{"status":21007}"
string(46) ""
string(9266) "{"status":0, "environment":"Sandbox", 
"receipt":{"receipt_type":"ProductionSandbox", "adam_id":0, "app_item_id":0, "bundle_id":"", "application_version":"244", "download_id":0, "version_external_identifier":0, "receipt_creation_date":"2018-07-18 07:55:17 Etc/GMT", "receipt_creation_date_ms":"1531900517000", "receipt_creation_date_pst":"2018-07-18 00:55:17 America/Los_Angeles", "request_date":"2018-07-18 07:55:46 Etc/GMT", "request_date_ms":"1531900546430", "request_date_pst":"2018-07-18 00:55:46 America/Los_Angeles", "original_purchase_date":"2013-08-01 07:00:00 Etc/GMT", "original_purchase_date_ms":"1375340400000", "original_purchase_date_pst":"2013-08-01 00:00:00 America/Los_Angeles", "original_application_version":"1.0", 
{"quantity":"1", "product_id":"com.mbalib.ios.wiki_r", "transaction_id":"1000000419163890", "original_transaction_id":"1000000419163890", "purchase_date":"2018-07-18 07:55:15 Etc/GMT", "purchase_date_ms":"1531900515000", "purchase_date_pst":"2018-07-18 00:55:15 America/Los_Angeles", "original_purchase_date":"2018-07-18 07:55:17 Etc/GMT", "original_purchase_date_ms":"1531900517000", "original_purchase_date_pst":"2018-07-18 00:55:17 America/Los_Angeles", "expires_date":"2018-07-18 08:55:15 Etc/GMT", "expires_date_ms":"1531904115000", "expires_date_pst":"2018-07-18 01:55:15 America/Los_Angeles", "web_order_line_item_id":"1000000039541410", "is_trial_period":"true", "is_in_intro_offer_period":"false"}]}, 
{"quantity":"1", "product_id":"com.mbalib.ios.wiki_r", "transaction_id":"1000000419163890", "original_transaction_id":"1000000419163890", "purchase_date":"2018-07-18 07:55:15 Etc/GMT", "purchase_date_ms":"1531900515000", "purchase_date_pst":"2018-07-18 00:55:15 America/Los_Angeles", "original_purchase_date":"2018-07-18 07:55:17 Etc/GMT", "original_purchase_date_ms":"1531900517000", "original_purchase_date_pst":"2018-07-18 00:55:17 America/Los_Angeles", "expires_date":"2018-07-18 08:55:15 Etc/GMT", "expires_date_ms":"1531904115000", "expires_date_pst":"2018-07-18 01:55:15 America/Los_Angeles", "web_order_line_item_id":"1000000039541410", "is_trial_period":"true", "is_in_intro_offer_period":"false"}], 
{"auto_renew_product_id":"com.mbalib.ios.wiki_r", "original_transaction_id":"1000000419163890", "product_id":"com.mbalib.ios.wiki_r", "auto_renew_status":"1"}]}"

Add auto subscription free trial:


Official documents

If the user subscribes to the same automatic subscription group again, if the user has automatically subscribed and bought, the free trial logo will be hidden. There will be no free trial due to internal purchase payment.
First purchase is_ trial_ period = true; is_ in_ intro_ offer_ Whether the period is in the probation period; expires_date-purchase_date is a free cycle

Auto subscribe to expires_ Apple will automatically subscribe to date, and then the App will start - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions

Add listening when APP starts:
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
    for (SKPaymentTransaction *transaction in transactions)
        switch (transaction.transactionState)
            case SKPaymentTransactionStatePurchasing: // 0
            case SKPaymentTransactionStatePurchased: // 1
                 //Subscription special handling
                      //If the order is automatically renewed, the originalTransaction will have content 
                      //Ordinary purchase, and automatic subscription for the first time
            case SKPaymentTransactionStateFailed: // 2
                [self failTracker:transaction];
            case SKPaymentTransactionStateRestored: // 3
                [self restoreTransaction:transaction];


    [latest_receipt_info] => Array
            [0] => Array
                    [quantity] => 1
                    [product_id] => com....
                    [transaction_id] => 1000000498609863
                    [original_transaction_id] => 1000000498609863
                    [purchase_date] => 2019-01-30 09:12:46 Etc/GMT
                    [purchase_date_ms] => 1548839566000
                    [purchase_date_pst] => 2019-01-30 01:12:46 America/Los_Angeles
                    [original_purchase_date] => 2019-01-30 09:12:47 Etc/GMT
                    [original_purchase_date_ms] => 1548839567000
                    [original_purchase_date_pst] => 2019-01-30 01:12:47 America/Los_Angeles
                    [expires_date] => 2019-01-30 09:15:46 Etc/GMT
                    [expires_date_ms] => 1548839746000
                    [expires_date_pst] => 2019-01-30 01:15:46 America/Los_Angeles
                    [web_order_line_item_id] => 1000000042488789
                    [is_trial_period] => true
                    [is_in_intro_offer_period] => false


Let users manage subscriptions
No coding is required to implement the subscription management UI. The application can open the following URL

reference resources:

  1. IAP (in app purchase) - short book
  2. iOS internal purchase Programming Guide - brief book

Record: WeChat and Alipay pay - look at mine, use mine is enough. WeChat and Alipay pay - look at mine.

Topics: iOS