App going to sea — an all-round view of Google settlement system


Image source:…


In recent years, China’s mobile applications have enjoyed a good momentum of going to sea. For those involvedTrading businessGoogle in app payment is an essential payment channel for sea apps. Different from the relatively perfect mobile payment system in China, even if the official documents basically describe how to access Google App payment, many problems will still be encountered in the process of access. This paper will introduce the key process and core technical points of the transaction, as well as the problems needing attention.

Access process

Noun interpretation

First, explain three pairs of concepts to help understand the logic of Google payment.

Disposable goods vs subscription goods

Disposable goodsIt is a commodity obtained through a single purchase. Disposable goods are divided intoConsumer goodsandNon expendable goods, as the name suggests, consumer goods are goods that can be consumed, such as gold coins or virtual currencies provided by app. Users can buy them repeatedly. Non expendable goods are permanent benefits that can be obtained through one-time purchase, such as paid upgrade content.

Subscription productsIt refers to goods that will be purchased regularly, such as member services, and the subscription will be automatically renewed until cancelled.

The discussion in this paper is limited toConsumer goods, other types of goods are not involved.

Consume vs Acknowledge

Both consume and acknowledge have the meaning of confirmation after payment, but they are not exactly the same.

AcknowledgeIt is a confirmation operation in a practical sense. The order will not be refunded if the acknowledge is carried out. The acknowledge can be used byClient API acknowledge())It can also be executed byGoogle server API acknowledge ()Done. Google will automatically refund paid but unconfirmed orders after three days.

ConsumeIt is an operation specifically for consumer goods. Consumption not only includes the meaning of confirmation, but also enables goods to be purchased repeatedly. Consumption can be regarded as including an acknowledge operation. Consumption can only be used byClient API consumeasync()It cannot be completed through the server API.

Business server vs Google server

In this article, the operation of the server will be mentioned many times, usingBusiness serverandGoogle serverTo distinguish and avoid confusion. Business server refers to the server of APP business logic. In this article, Google server refers to the payment server in Google application, which is provided by Google.

Overview of transaction process

From the perspective of business, a transaction process can be roughly represented by the following figure:

App going to sea -- an all-round view of Google settlement system

However, in the process of actual transaction, it is full of uncertain factors, such as unstable network environment, misoperation and so on. Due to the sensitivity of trading business, users can neither pay more, nor pay less or pay wrongly. Therefore, it is necessary to comprehensively consider various possible situations, and fully consider and deal with the factors that may lead to abnormal order and payment status. From the perspective of technology, the complete transaction process is as follows:

App going to sea -- an all-round view of Google settlement system

Detailed explanation of key transaction processes

Create order

Creating an order refers to creating an order for the business server. After the order is created, the business order ID and the corresponding Google commodity ID will be transferred to the subsequent steps. The business server will manage and maintain its own goods and orders, which are different from Google’s goods and orders, and the relationship between them needs to be established and maintained.

Establish connection

Before Google payment, you need to establish a connection with Google play. The bridge is billingclient. Billingclient is an important tool provided by Google play billing library, and payment related operations are related to it. If the connection is disconnected due to network and other reasons, you must reconnect to continue the subsequent operation.

Query goods

For a product, it needs to be created in the background of Google in advance. Commodity query is to query the commodity information configured in the background of Google, confirm that the commodity information is correct, obtain the commodity details, and provide necessary data for initiating payment.

Initiate payment

Payment is initiated through the API of billingclientlaunchBillingFlow()Call Google’s payment interface, and the corresponding service order of Google payment is created. Business server orders and Google server orders need to be associated. The normal way is for the client to inform the business server of the corresponding Google order ID when subsequently initiating order verification. In reality, the client may not receive the payment results for some reasons. In the scenario of real-time notification of callback to the business server by Google developers, sufficient information is also needed to be associated. Here, the business server ID is passed in through confusion. The purpose is to enable the business server to associate Google orders with business server orders by virtue of confusion ID to complete subsequent confirmation and performance.

acknowledgement of order

After receiving the callback of successful payment, the client actively calls the service provided by billingclientconsumeAsync()Method to ensure that the order has been confirmed, is not refunded, and can be purchased again. For unconfirmed orders, Google will automatically refund after three days. In addition, you need to actively initiate order inspection to the business server.

order fulfillment

According to the process, the client initiates the verification of the order. After the server confirms that the order is valid and correct, it needs to perform the contract. In business, it is usually manifested in the issuance of gold coins, the increase of balance, etc. The server must ensure the of this operationIdempotency, perform once and only once, which is the premise of the order compensation mechanism.

Order compensation

A payment process may be interrupted. What needs to be paid attention to is that the user has completed the payment but has not received the rights and interests. This process is easy to cause customer complaints and needs to be approvedOrder compensationAs a cover.

Order compensation is divided into two scenarios. One is that the business server receives the pub / sub message through the real-time developer notification provided by Google and learns that the order payment status has changed. At this time, check the status of the order. If it is not in the performance status, it will perform the performance to protect the rights and interests of users, and call the server acknowledge API to confirm the order to ensure that there is no asset loss caused by automatic refund.

Another scenario is that the client actively initiates the order compensation mechanism to obtain the paid but unconfirmed orders at the right time for subsequent consumption and performance. Active compensation can be made at multiple times, such as starting the app and entering the recharge purchase page, which can be determined according to the business scenario. At the same time, it will also improve the logic of the first scenario. In the first scenario, the service end knowledge is completed and the rights and interests are distributed, but the commodity cannot be purchased again. At this time, the client completes the consumption, so that the commodity can be purchased repeatedly, forming a closed loop of the overall logic.

Technical realization

App going to sea -- an all-round view of Google settlement system

An important feature of transaction process is event driven. Technically, it needs to decide the next operation in a large number of callback methods. In a process oriented manner, the code will be nested with layers of callbacks. Such code logic is not clear enough and difficult to understand. Countless callbacks will lead to complex exception handling and difficult troubleshooting. In order to solve this problem, the whole transaction process can be regarded as a pipeline, and each step can be abstracted into sub modules.

The callback directly provided by Google play billing library cannot form a pipeline, and a layer of conversion is required. The callbackflow provided by kotlin coroutine is a flow builder that can convert callback based APIs into flows.

Logical encapsulation

App going to sea -- an all-round view of Google settlement system

The whole transaction process is divided into several sub modules in the layer, so that the sub modules can be connected and reused. Each sub module has specific input and output. The output of the previous sub module is the input of the next sub module. For example, the output of the query commodity sub module is the commodity detail information, and the commodity detail is displayed on the input panel as the input of initiating payment. Moreover, each sub module needs to ensure its own logical cohesion. It only cares about the work to be completed in the current process, not the next process.

We wrap the separated sub modules into callbackflow. After the operation is successful, send data outside the process to the subsequent flow through the offer method. If an error occurs, close() or cancel() the current flow can be terminated. The granularity of splitting is determined by operation and callback. The principle is that the module function is single and cohesive. In addition, the instance of billingclient needs to be used in the whole operation process, and the instance will be passed when entering.

fun queryPurchasesFlow(client: BillingClient?): Flow<List<Purchase>> =
    callbackFlow {
        ) { p0, p1 ->
            when (p0.responseCode) {
                BillingClient.BillingResponseCode.OK -> {
                    // emit the value to the flow
                else -> {
                    // close the flow

        awaitClose {
            // log & release resources

Pipeline establishment

After completing the encapsulation of a single operation, these flows need to be assembled. Callbackflow provides operators for concatenation and conversion of flows, whereflatMapConcatIs to convert and flatten the upstream elements and return a new flow. Flatmapconcat is applicable to the current scene. An example of concatenation is as follows. After establishing a Google connection, obtain the information of goods, and call the payment panel after verification.

startConnectionFlow(client).flatMapConcat {
    querySkuDetailFlow(client, request)
}.flatMapConcat {
    launchBillingFlow(activity, client, it, request)
}.catch { e ->
    // catch exception
}.collect {

In addition, flow can be flexibly configured to realize different business logic. The order compensation process is different from the normal payment process. The corresponding flow needs to be rearranged. The same process can be reused with the payment logic without redevelopment.

App going to sea -- an all-round view of Google settlement system

Overall design

As a core business component, Google payment is provided to other modules of app, which is characterized by convenient access and simple interface. The architecture of its components is as follows:

App going to sea -- an all-round view of Google settlement system

Product layer: the caller of payment can be different types of cashier, web cashier and native cashier.

Interface layer: the payment component provides a simple external interface, payment initiation and order compensation.

Management: there are data management and connection management under the controller. Data management is to manage the data related to orders and commodities. Connection management is to manage the billing client provided by Google and disconnect the connection at the right time.

Core layer: the core layer contains the core logic of the business, including establishing connections, obtaining goods, etc. It also includes the log and monitoring of the payment module.

Support layer: relying on the existing underlying basic functions of app.

Step pit summary

Get product details is blank

billingClient.querySkuDetailsAsync(params) { p0, p1 ->
    when (p0.responseCode) {
        BillingClient.BillingResponseCode.OK -> {
            // p1 is empty

During the early debugging, the product information obtained by Google SKU ID using queryskudetailsasync() was empty. After troubleshooting, several impact points were found.

  • needRelease internal test version, release an internal test version according to the requirements of Google console without waiting for approval.
  • There is some delay in the creation of goods, there will be a short delay in the initial stage of unsuccessful debugging and payment, that is, the goods cannot be obtained at the moment of creation, and can be obtained successfully after a period of time. This situation did not appear later.
  • Package name and signature do not match, you need to use the package name and signature configured by uploading the playstore. You don’t need to use the same package submitted, but the package name and signature must match.

Unable to buy the item you want

App going to sea -- an all-round view of Google settlement system

There is a prompt that you can’t buy the goods you want. The possible reasons are:

  • Check whether the test user isInternal test userList andLicense testList.
  • Need to log in to the internal test account, clickAccept test invitation link, accept the invitation.

necessary condition

To successfully complete a payment, we need to pay attention to the following points.

  • Testing machineGoogle Services FrameworkInstalled.
  • Google playstore detect IPNon national region。 Depending on the network environment, you can also set the country in Google playstore (not required).
  • Test account has been added to Google background, includingInternal test userAdd andLicense testAdd, both need to be added.
  • Accept the test invitation, find the internal test link and clickAccept the internal test invitation, this step is very important and easy to miss.
  • releaseInternal test version, application release status, no need to wait for approval.
  • Installation package signature and package nameWith the signature submitted to the Google backgroundagreement
  • Google playstoreVersion update


The particularity and importance of trading business is self-evident. Whether it is to protect the revenue of the app, or accurately execute the transaction wishes of users and avoid customer complaints, the transaction business is required to consider and improve various scenarios as much as possible. For developers, they should not only know the whole business process of ordering and payment, but also abstract the business process through technical means, and realize the complex and changeable business scenarios and logical branches into flexible arrangement, so as to improve the maintainability and robustness of the whole system.

Firstly, this paper briefly introduces the transaction process, and then realizes the flexible arrangement of business links with the help of kotlin coroutine’s callbackflow, transforming the nested callback and event notification into a streaming and linear writing method. However, even so, it still can not cover all the abnormalities in the real scene. In addition to the order compensation mechanism, it is also necessary to analyze each case of transaction failure through automatic and intelligent means, build a complete monitoring and alarm mechanism, and constantly summarize and improve, which is where continuous investment is needed in the follow-up.

Limited by space, we can’t give a detailed introduction to each point. Readers are welcome to leave a message for discussion.

Reference link

This article is published by Netease cloud music technology team. It is prohibited to reprint the article in any form without authorization. We recruit all kinds of technical positions all year round. If you are ready to change jobs and happen to like cloud music, join us GRP music-fe(at)corp.netease. com!