One, foreword

If your App has the IAP function, then you may encounter the user feedback that Apple recharge successfully, but the service does not arrive, the user will generally provide such apple receipt:

In the Apple receipt provided by the user in the feedback, there is an ORDER ID in the field, which is called Invoice ORDER ID by Apple. After analyzing the receipt we developers obtained from the App, there is no ORDER ID field!! Therefore, we cannot locate and contact the invoice provided by this user and the order number of our background, so we cannot provide the user with the normal reissue service, and the developer is also very helpless!

This year, Apple finally came up with a solution. Is not very happy! Click “like”

As we all know, the most important source of revenue for mobile games is the Purchase of virtual goods, while iOS requires the use of Apple’s in-app Purchase through the App Store. Function. 37 mobile games is an independent subsidiary of Sanqi Interactive Entertainment. As the top mobile game publishing platform in China, it has operated more than 2,000 games in total. Therefore, the importance of IAP for 37 mobile games is self-evident!

WWDC 2020: What’s New with in-app Purchase – WWDC 2020: What’s new with in-app Purchase – WWDC 2020

1. Can apple background check the details of the refunded order?

A: Not yet. (expect it next year at WWDC2021?)Copy the code

Can consumable, non-consumable, and non-renewal subscriptions be refunded in a sandbox environment?

A: Not yet. (What about the future? Wait for updates....)Copy the code

This year’s WWDC21 conference began, xiaobian first time to pay attention to IAP related Sessions, great! This year’s IAP features are more open and transparent. Two questions you had last year have been resolved this year! Here are apple’s three steps to IAP this year:

  1. Meet StoreKit 2 – WWDC 2021
  2. Manage in-app purchases on your server – WWDC 2021
  3. Support customers and handle refunds – WWDC 2021

Since the above three sessions are closely related to each other in terms of content, the xiaobian will mix and interpret the three steps in this paper, which is mainly divided into three parts:

  1. StoreKit 2: Updates and changes to the App API, including in-app change subscriptions, refunds, etc.
  2. Server to Server: communication between Apple servers and developer servers, including Apple notifications, developers’ active requests to Apple servers, new verification receipt procedures, etc.
  3. Sandbox Test: Updates related to the Sandbox Test environment, and some events to watch out for.

Second, the StoreKit 2

Major updates to StoreKit 2

  • A new set of features based on Swift language
  • Update receipts and transactions (data format and field changes)
  • More subscription type interfaces
  • Same StoreKit framework

2.1. StoreKit 2 for Swift only

StoreKit 2 for Swift Only! That’s right! Swift only! StoreKit 2 takes advantage of the latest features in Swift, including new language interfaces such as Swift concurrency, to make it easy to access product information, merchandise products, process transactions, and manage access to content and subscriptions within the App. Also, StoreKit 2 only supports iOS 15+.

Those of you who are still maintaining your Objective-C code are crying in the bathroom! There are no new features, so now is the perfect time to start learning Swift. Without it, you won’t be able to do iOS development happily

2.1.1,What is the relationship between StoreKit v2 and v1?

What do we developers have to choose? Apple’s selection document provides an answer:

  • In-App Purchase: A Swift-based API that provides Validation of Apple Signature transactions in JSON Web Signature (JWS) format, available starting with iOS 15, macOS 12, tvOS 15, and watchOS 8.
  • Original API for In-app Purchase: An API for providing transaction information using App Store receipts, available from iOS 3, macOS 10.7, tvOS 9, and watchOS 6.2.

Apple now defines Original StoreKit V1 as Original API for in-app Purchase and StoreKit V2 as in-app Purchase. (Note: Currently, the full IAP purchase process can be implemented with both v1 and V2 versions. The difference is that V2 must be developed using Swift and offers more powerful APIs.)

2.1.2,When do you need to use StoreKit V1 now?

It makes sense that StoreKit V2 is currently a redesign implementation, so some of the IAP apis offered by V1 are not yet available in V2, so v1 needs to be used.

If your application relies on any of the following features, you may need to use the original in-app purchase API:

  1. Provides support for VPP (Volume Purchase Program). See Device Management for more information.
  2. Provide app pre-orders. For more information, see Applying reservations.
  3. Change your App from a charged App to a free App and vice versa.
  4. Use the V1 API for existing and legacy apps.

Xiaobian notes:

  • Bulk purchasing is for the use of devices deployed in batches. For example, the school has ipads for learning and can purchase apps in bulk.
  • The receipt receipt field preorder_date is used to determine if the user is in a subscription status, and v2 IAP has deprecated the receipt field. Flag: If you have time later, I will write a separate article about app booking. (Click “like” if you think it’s good)
  • If you want to check your purchase history in the App Store, you need to check it in receipt.

2.2, Powerful New APIs

StoreKit 2 provides the above updated classes (methods) for easy access to the IAP interface, which can be understood as an enhanced version, which will be explained in more detail below.

  • Products: Information about the in-app purchase items configured in App Store Connect
  • ◆ Update optional parameters for the purchased item interface, which can be bound with user IDS
  • Transaction Info: Updates the content format of Transaction information
  • Transaction History: Provides an interface for querying Transaction history
  • Subscription Status: Provides an interface for querying the status of subscribed items

The Product class adds the type of item:

public static var consumable: Product.ProductType
public static var nonConsumable: Product.ProductType
public static var nonRenewable: Product.ProductType
public static var autoRenewable: Product.ProductType
Copy the code

It also extends subscription type information. Items of the subscription type include isEligibleForIntroOffer, which determines whether the user is eligible to subscribe at a discounted price. With StoreKit 2, we’ll be able to make it much easier to determine if a customer is eligible for your promotional offer. I’m not going to expand on the complexity of subscription types here, and most of you probably don’t have much exposure to them, but you can see automatic renewal subscriptions for more details.

In addition, StoreKit 2 is forward compatible with the original Product, adding a wrapper type called BackingValue to achieve this, the data type used to communicate with the App Store. See the document: BackingValue

In addition to the original request item information, the Purchase opthons parameter is added.

In addition to the purchase data and promotional offers, the most important is the new field: App Account Token!

  • Developer creationApp account token
  • The user account associated with the App
  • App account tokenuseUUIDformat
  • Stored permanently in Transcation orders

The App Account token allows developers to bind the user’s ID to Transcation, that is, map apple’s transaction order data to the user’s information, which can prevent the problem of recharge and order drop

Example code:

let uuid = Product.PurchaseOption.appAccountToken(UUID.init(uuidString: "uid")!)

//Begin a purchase.
let result = try await product.purchase(options: [uuid])
Copy the code

UuidString is the interface UUID() defined by Apple. UuidString is obtained in the format of 4713AE2D-11a5-40EA-B836-CBCD1EC96a76. If the user ID and developer order number need to be associated, the developer needs to automatically map, or server side generated return, etc.

Signed Transaction Information:

  • One object for each transaction
  • Signed transaction information, data format using JWS (JSON Web Signature)
  • Read data using the native interface

Insert Manage In-app purchases on your server and you will see why JWS data format is used.

  • 1, enhance security
  • 2. Easier to decode
  • 3, no need to connect to the Apple server verification, developers can be a local single check!

JSON Web Token (JWT) is a specification that allows us to use JWT to pass secure and reliable information between two organizations. JWT is not equal to JWS (JSON Web Signature). JWS is just an implementation of JWT. In addition to JWS, JWE(JSON Web Encryption) is also an implementation of JWT. Detailed view of JWS (RFC 7515) The main purpose of THE JWS is to ensure that data is not modified during transmission and verify data integrity. However, because only Base64 is used to encode the message content, there is no guarantee that the data will not be leaked. Therefore, it is not suitable for transmitting sensitive data. reference

Transaction INFO in JWS format

Base64() + "." + Base64(payload) + "." + sign( Base64(header) + "." + Base64(payload) )
Copy the code

The header and payload are encrypted using the secret key according to the ALG encryption method declared in the header to generate a signature. Then reverse the construction process and decode out the three parts of JWT:

  1. Header
  2. PayLoad
  3. Signature (signature)

The documentation and procedures for validation are available in the App Store Server API, which I won’t expand here.

A full Demo is shown in the video, which I won’t expand here. Dmeo can be automatically downloaded to view.

Three new Transcation related apis are provided:

  1. A: All transactions
  2. Latest transactions: The Latest purchase transaction order. (Divided into subscription items and all types except subscription items)
  3. Current Entitlements: Indicates that the Current user has the purchase permission. (All subscription and non-consumable items)
@available(iOS 15.0.macOS 12.0.tvOS 15.0.watchOS 8.0.*)
extension Product {

    /// The most recent transaction for the product, or `nil` if the user has never purchased this product.
    public var latestTransaction: VerificationResult<Transaction>? { get async }

    /// The transaction that entitles the user to this product, or `nil` if the user is not currently entitled to
    /// this product.
    public var currentEntitlement: VerificationResult<Transaction>? { get async}}Copy the code

It’s a very powerful interface:

@available(iOS 15.0.macOS 12.0.tvOS 15.0.watchOS 8.0.*)
extension Transaction {

    /// A sequence of every transaction for this user and app.
    public static var all: Transaction.TransactionSequence { get }

    /// Returns all transactions for products the user is currently entitled to
    ///
    /// i.e. all currently-subscribed transactions, and all purchased (and not refunded) non-consumables
    public static var currentEntitlements: Transaction.TransactionSequence { get }

    /// Get the transaction that entitles the user to a product.
    /// - Parameter productID: Identifies the product to check entitlements for.
    /// - Returns: A transaction if the user is entitled to the product, or `nil` if they are not.
    public static func currentEntitlement(for productID: String) async -> VerificationResult<Transaction>?

    /// The user's latest transaction for a product.
    /// - Parameter productID: Identifies the product to check entitlements for.
    /// - Returns: A verified transaction, or `nil` if the user has never purchased this product.
    public static func latest(for productID: String) async -> VerificationResult<Transaction>?
}
Copy the code

Current entitlements this is currently, convenient developers directly through the interface/can read the Current user available subscription items and non-consumable items, developers do not do hard coding write dead productID request Apple query, direct an interface fix! Especially for individual developers, it is very convenient to determine, do not need to build a server.

Query the trading orders of the same user on different devices. Suppose the user buys A trading order on device A, then the purchased trading order can be found on device B in real time. Apple engineers say the system generally refreshes automatically, and there is no need to use the sync interface if necessary.

Typically, the first time an App is opened, developers will be able to retrieve purchases in real time in the background using StoreKit 2’s interface. For non-consumable items, when the user is on a new device, it may be necessary to provide the user with a UI entry to recover the purchase record. For the subscription type, such as a monthly card of a video website, although it is logged into an Apple account, when buying it, it is bound to the user of the video network, not bound to the Apple account. Therefore, the subscription type may not be restored directly.

All transactions can be used in all StoreKit interfaces; StoreKit V1 purchase records are also available through the v2 interface. Purchases made using V2 are available on a uniform receipt.

The status of a subscription type item, such as getting the latest transaction, getting the status of an updated subscription, getting the information about an updated subscription, etc.

To get the update subscription information, you can get the update status, item ID, and if expired, you can know the reason for the expiration. (For example, the user cancels, the subscription fails, the subscription expires normally, etc.) , all the data obtained is JWS format validation.

And finally, signature verification, as mentioned above, is not expanded here.

Apple engineers recommend that the bundle ID be used for validation, so it is recommended to write a hard code and not read the info.plist configuration file. Then verify whether the payload is tampered with in a regular format.

StoreKit V2 provides an API to validate the JWS format, which developers can call directly without having to resolve.

StoreKit V2 concludes with powerful new IAP interface, new JWS transaction information format, transaction details and history interface, additional subscription type information. In short, awesome ~

2.3、Manage subscriptions API

How can subscribers manage their subscription inside my app?

How do subscribers manage their subscriptions within my app?

A new API is provided to display the user’s current subscription interface directly in the developer App without having to jump to the App Store.

The interface is as above. After the call, the interface opened is as follows:

You can unsubscribe from the developer App, upgrade or downgrade subscription levels, etc.

2.4、Request refund API

How can customers request a refund inside my app?

How can a customer apply for a refund in my app?

Provide a new Request Refund API to allow users to apply for a refund directly from the developer’s App.

When a user requests a refund, the App will receive a notification, and the Apple server will also notify the developer server (more on that below). The refund test is now available in a sandbox environment.

The interface is as above. After the call, the interface opened is as follows:

User refund process interface (this is the interface of the system), so may be very convenient for users, for developers, may need to consider?

Server to Server

Next, let’s talk about an update to apple’s server API.

As you can see, apple servers, user devices, and developer servers interact more and more with each other. As Apple iterates and opens up, the three are now in a cycle

Build the developer’s server:

  1. Receive status change notifications for in-app purchases
  2. The internal purchase status is tracked through the interface
  3. Verify access at any time (i.e., whether the purchase was valid, such as a refund)
  4. Manage order status
  5. Track the refund

Next, it will be said from the above aspects:

3.1、Validate status with receipts

Receipt verification method:

  1. Verify the receipt in the user device App
  2. On the developer server via Apple/verifyReceiptInterface validation receipt

The contents of your old receipts are shown above.

The new JWS format transaction format content is shown above. Compare your receipts to see what changes have occurred:

The old format has GMT (Greenwich mean time), PST (Pacific standard time), Unix timestamp (Unix timestamp), the new format, only retains the Unix timestamp, and the field has been updated.

The in-app purchase type is also returned.

This is the UUID of the user information for the relationship mentioned above. Here Apple uses the appAccountToken field.

This is the user’s refund time and refund reason field. Change from cancellation_date to revocationData.

Finally, the type of promotion offers.

Verification of signature information, not to mention here, has been mentioned above.

3.2 Check status with APIs

Use APIs to check status

Two new interfaces are provided:

  1. Subscribe to the item status query API
  2. Internal Purchase history order query API
Gets the status of all subscriptions of the user

Let’s start with the subscription status query API. The only required argument is originalTransactionId, which is so familiar that I won’t expand it. Get All Subscription Statuses

The data format of interface request and return is shown above.

LastTransactions is the status of the last subscription, 1 is valid, 2 is expired, 3 is retried, 4 is grace period (this is set by the developer, for example, how long you can extend a subscription if it fails to expire). , 5 is already revoked.

The JWS decoded content of signedTransactionId is the data content of a single update subscription type.

Get the history order of the trade

Get a user’s transaction history, including all of their in-app purchases in your App. The originalTransactionId is the originalTransactionId of the user’s transaction. I’m not going to expand this because it’s easy to see. Get Transaction History

Note that the returned data has one field, hasMore, that is true, indicating that the updated historical order has been updated. The default is 20. Developers currently have no control over this number.

Verify the App Store Server API

App Store Server Interface Standards:

  • JWT certification
  • JWS Transaction content format
  • Json request and response
  • Identifies the parameter based on originalTransactionId

All App Store Server API interfaces must use JWT authentication. For verification rules and procedures, see the documentation: Generating Tokens for API Requests

For an example of Creating private Keys in apple’s background, see the documentation: Creating API Keys to Use With the App Store Server API

Check out the documentation: Generating Tokens for API Requests

So, if you need to use the App Store Server API to query the status of a subscription item or a user’s historical order, here are the key points:

  • Independent status and history functions
  • You only need to provide the originalTransactionId
  • Gets the transaction with the verified signature and stores the necessary fields (e.goriginalTransactionId)
  • Instead of storing the complete transaction data for the verified signature (that is, the verified JWS content), just save the originalTransactionId field.A field to go the world! Give us a thumbs up ~)

3.3、Track status with notifications

Track status through notifications!

Apple server notification updates, Apple says good, developers can accept the notification, update status is timely? No developer to ask! All right, you’re right

Apple server notifys v2 of the update, so I won’t expand it here. There seems to be nothing to say, similar to the previous article.

The main changes are the types of notifications, some of which have been removed, and some of which have been added.

The main reason for the change is that apple’s automatic subscription types have become more complex, so some fields don’t make much sense anymore. In addition, Apple’s new family sharing feature allows the main account to authorize or revoke the authorization of the family subaccount. REVOKE: REVOKE: REVOKE: REVOKE: REVOKE: REVOKE: REVOKE: REVOKE: REVOKE: REVOKE: REVOKE: REVOKE: REVOKE: REVOKE

Of course, there are so many changes, Apple can not change the original interface directly ah! So there are v1 and V2 ports, which developers can set, which will be mentioned later, but I’ll skip those.

In addition, under the subscription type, there are subtypes. That’s understandable. For example, SUBSCRIBED subscriptions, which can be either the state of the first subscription or the state of a new subscription, are subscriptions.

And then you expand the notification primary type, and you have those subtypes. Here’s what I’m going to do, I’m not going to expand it, but I’m going to show you the pictures:

Finally, there are a lot of states around subscriptions, so the complexity of notifications for subscriptions is self-evident!

In summary, App Store Server Notifications V2 provides over 20 notification types! Subtypes provide more refined notification types!

App Store Server Notifications V2: App Store Server Notifications V2: App Store Server Notifications V2: App Store Server Notifications V2

3.4、New purchase flow

New purchase process processing

Finally, let’s summarize the changes and updates to the developer server with the new query interface on the server.

For initial SUBSCRIBED purchases, the change in the process is that once the developer App and the developer server complete the subscription process, The Apple server also sends a notification SUBSCRIBED + INITAL_BUY. Then the developer server can keep track of the subscription status through inApps/ V1 / SUBSCRIPTIONS without waiting for notification from Apple servers. Avoid developers in a passive situation, better real-time access.

Subscription updates, which is when the developer server keeps track of the status of subscriptions through the inApps/ V1 / Subscriptions interface. Isn’t that cool? Give me a thumbs up

Subscription type bill grace period and billing retry, same way, Apple server will notify the developer server DID_FAIL_TO_RENEW, DID_RECOVER, The developer server checks the status of subscriptions through inApps/ V1 / Subscriptions, and then manipulates and restricts users within the App in real time.

First consumable purchase, same thing. If so, developers can verify the order with receipt or StoreKit V2’s new Signed Transactiond.

And the user refund, also appeared a new era! In addition to being refunded on the Apple server, developers can now proactively check all of the user’s transaction orders through the inApps/ V1 / History interface to confirm that the order status is refunded (canceled).

For subscription type refunds, the developer server keeps track of the current status of the subscriptions through the inApps/ V1 / Subscriptions interface.

Migrating to JWS transactions

Migrate to JWS format transaction validation

Apple has deprecated receIP receipt validation for StoreKit V2’s new interface, so how can developers migrate to the new JWS format validation? So, Here’s apple’s solution:

If you need to be compatible with StoreKit V1, you can also use receipt receipt to verify the receipt through the Apple interface /verifyReceipt. The receipt contains the originalTransactionId, so, Developers can use the inApps/ V1 / History interface to keep abreast of the status of transactions.

Subscription types are checked through the inApps/v1/ SUBSCRIPTIONS interface.

3.6 the Manage family sharing

Manage family sharing

Apple currently supports family sharing for non-consumable and auto-subscribed items. In addition, Apple returns a field, inAppOwnershipType, indicating whether the current user is the primary user to purchase the item.

Family sharing has been updated with new notifications, adding 4 types of notifications.

Customer Support & Handle refunds

Finally come to the last section! It’s also important for customer service support and the handling of refund requests.

In the past, when users had problems with in-app purchases, they had to solve them by themselves, and it was through phone calls, emails, Apple supported apps, websites, forums, etc., which was very unfriendly to users!

The general user encounters the problem of the love field have those?

4.1, How do I identify the in-app purchase made by this customer?

How do you identify in-app purchases made by this customer?

This is the issue mentioned in the preface that when users receive apple’s receipt, the invoice does not match the developer’s order! There are new apis to address this:

This new interface allows the ORDER ID on the invoice provided by the user to check the corresponding transaction information.

Xiaobo note: at present 2021-06-17, I have not seen this interface in the Apple interface document, it is not clear that it has not been updated, not to say that it is in development….

Then, the whole process is like this: the user complains, provides the order ID, queries the status, and provides the order replenishment or support services for the user.

The format of the data is the same, so I’m not going to expand it.

Finally, the developer server should remember to save the corresponding user order ID and do the mapping?

4.2, How do I lookup this customer’s past refunds?

How do I find past refunds for this customer?

Similarly, Apple provides an interface to query all in-app purchase orders, but it’s impossible for developers to check them once and then determine which ones are refund orders. So, Apple offers another interface:

The same is true for this interface, which allows you to look up all of the user’s refund record orders through any of the user’s originalTransactionId.

Xiaobo note: at present 2021-06-17, I have not seen this interface in the Apple interface document, it is not clear that it has not been updated, not to say that it is in development….

The return format is the same.

User refunds have a separate refundDate field. If there is a content date, it is a refund.

4.3、How do I compensate subscribers for a service issue?

How do I compensate subscribers for service problems?

The main problem is that if the developer server is down and the user cannot use the App service, the developer can compensate the user, so the developer can provide an in-app purchase counter code (for all types of in-app purchase), which is generated in the apple background. And then let the users in the App Store for exchange, also can be in the App through presentCodeRedemptionSheet () interface calls, pop-up system conversion interface:

The user can get compensation by decoding the code.

Xiaobian note: For the game, this is not suitable for the code, because the game has user account, game service, character account, etc., the content of the exchange, cannot be automatically assigned to a certain account or a certain role. In addition, domestic seems to have no such compensation habit?

4.4, How do I appease customers for outages or canceled events?

How do I appease clients for interrupted or cancelled events?

If a developer wants to appease users and then compensate them for some of the benefits of a server shutdown or event cancellation, Apple has provided a new interface:

What this interface does: Twice a year, developers have the opportunity to add 90 days of free compensation to in-app subscriptions. In other words, apps with automatic subscription can be actively compensated (extended for free) by the developer on the server for up to 90 days.

Xiaobo note: at present 2021-06-17, I have not seen this interface in the Apple interface document, it is not clear that it has not been updated, not to say that it is in development….

You need to give the extension days on the interface, as well as the reason code.

If the developer’s service is interrupted or down, and users cannot use the service, the developer shall take the initiative to compensate users. The flow chart is very clear, so I won’t parse it here.

The developer took the initiative to cancel the event and reimbursed the user.

4.5, Refund the notifications

A refund notice

Finally, there’s the refund notification process, which Apple introduced last year at WWDC20:

So, are there any good best practices now?

  • Find the strategies that work best for you: for example, deducting gold, canceling service orders
  • Consider the impact on game design
  • Use marketing and promotional tools
  • Provide clear information through communication channels (such as push, email, or bulletin)

Apple has gone deep into the refund notification process by making it possible for a developer to receive a refund notice at any time within 48 hours.

When deciding whether to grant a Refund, Apple has a “Refund Decisioning system,” based on the user’s information, device information, purchase history, and Refund history.

And now! Apple has added a new decision factor: Developer signals. What is this? That is, when the user applies for a refund, the developer can give some of the user’s information to Apple to assist the decision system to make a decision.

When a user requests a refund, Apple notifies the developer server (CONSUMPTION_REQUEST) that developers can provide the user’s information (such as whether the gold has been spent, how much the user has refunded and so on) within 12 hours, and apple receives the information. Assist the “Refund Decision system” to decide whether to allow a refund! See detailed documentation: [the Send Consumption Information (developer.apple.com/documentati…).

ConsumptionRequest is available for details of the parameters that need to be provided to Apple

Note: The customerConsented field indicates whether the user agrees to provide the consumption data. Therefore, this user information, is required to allow the user to share only! (Add it to the user agreement?)

There are two new types of refund notice, one is a request for decision information from the developer, and the other is a refund rejection notice! (What can developers do to appease users when they are denied a refund?)

Finally, the whole flow chart is as above!

This interface is testable and, as mentioned above, when a user refund interface and interface are provided in the App, this test will also be notified to the developer server via the Apple server when a refund is initiated. Also added this year is setting up a separate sandbox environment notification URL! (More on that below)

4.6, Support customers and Shared benefits

Customer service support and win-win sharing

Whether it is refund or compensation for in-app purchase, the purpose is for the user!

  • Increase retention
  • Improve customer satisfaction
  • A higher sense of engagement
  • Grade and write reviews actively

  • More transparent information
  • Improved refund process
  • Provide better service results for customers
  • Strengthen communication

Conclusion:

  • Add a custom help interface to the App
  • Review customer support process optimization
  • Set up the server to receive notifications (take action after refund)
  • In response to requests from the App Store for users to request a refund

Fifth, the Sandbox Test

Sandbox test environment

Finally, the sandbox environment is updated! It’s really the last section! Give it a thumbs up

  • Update existing sandbox accounts
  • Subscription status API
  • In-app purchase history API

App Store Server Notifications adds callback URL configuration to sandbox environments! App Store Server Notifications adds callback URL configuration to sandbox environments! App Store Server Notifications adds callback URL configuration to sandbox environments!

This test after convenient ~

App Store Server Notifications URL supports V1 or V2 configuration. Because V2 changes a lot, a new version is added. Will V3 be available next year? -. –

Sandbox test:

  • Keep track of past purchases
  • Change the area where the account resides
  • More options for testing subscription expiration time
  • TestFlight test will fail, etc. [Social society]

Clear purchase history:

Location of the changed account:

Test subscription expiration time more options:

Five, the summary

At last! At last! It’s time to conclude, and there should be applause! Point a ~

At present, according to the Human Interface Guidelines, Apple has designed to provide the refund function for users in the App. According to the current situation, it should not be mandatory for all apps to provide the refund function in the App. So, it is also necessary for developers to think ~ refund and in-app purchase, what is the essence?

In fact, for the average user, the developer will not limit the user refund, normal refund, but there are always unreasonable circumstances, malicious refund, the average game bad debt rate is more than 5%, before Apple provided refund notice to developers last year, even more than 20%. For example, 5% of 100 million is 5 million.

So what should developers think about in-app purchases and refunds?

Apple has some hints:

  • Manage your relationships with existing customers
  • Increase retention
  • Improve customer satisfaction
  • Increase your income

Therefore, do a good job of a product, improve user satisfaction, user satisfaction, whether more willing to use the developer’s services, so that the positive cycle ~

How about a refund feature in the App?

This is a question for all developers to ponder and explore

Welcome to join us in the comments section ~

Welcome to our “37 Mobile Games iOS Technology Operation Team” to learn more about iOS and Apple

Refer to the reference

  • Meet StoreKit 2 – WWDC 2021
  • Manage in-app purchases on your server – WWDC 2021
  • Support customers and handle refunds – WWDC 2021
  • What’s new with in-app purchase – WWDC 2020
  • IOS Handle Refunds — WWDC20 (Session 10661)
  • StoreKit Overview – Apple Developer
  • Choosing a StoreKit API for In-App Purchase | Apple Developer Documentation
  • Device Management | Apple Developer Documentation
  • Offering Your Apps for Pre-Order – App Store – Apple Developer
  • What’s New – App Store – Apple Developer
  • Automatic renewal subscription – App Store – Apple Developer
  • BackingValue | Apple Developer Documentation
  • Implementing Promotional Offers in Your App | Apple Developer Documentation
  • JWS documentation (RFC 7515)
  • Creating API Keys to Use With the App Store Server API | Apple Developer Documentation
  • Generating Tokens for API Requests | Apple Developer Documentation
  • App Store Server API | Apple Developer Documentation
  • Implementing a Store In Your App Using the StoreKit API | Apple Developer Documentation
  • Get All Subscription Statuses | Apple Developer Documentation
  • Get Transaction History | Apple Developer Documentation
  • App Store Server API | Apple Developer Documentation
  • Send Consumption Information | Apple Developer Documentation
  • ConsumptionRequest | Apple Developer Documentation
  • Introduction – In-App Purchase – Human Interface Guidelines – Apple Developer

37 Mobile game iOS technology operation team: Share technology dynamics, practice and thinking! Love, openness, preciseness, responsibility ~

  • If there is infringement, contact will be deleted ~
  • If there is anything wrong, please correct me ~
  • If you have any questions, please join us in the comments section