Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”

🔥 author

Author: Shuai times

About the author: CSDN blog expert, welcome to like, favorites, comments

Fan benefits: the public account “Shuaitimes” a share of Android system technology, related knowledge, interview questions database, technical assistance, dry goods, information, high-paying positions, tutorial place.

🔥 integrate with Google Pay

This article describes how to integrate the Google Play Billing Library into your application, without further ado, the code.

1. Add Google Play Clearing library dependencies

Add the following line to the “dependencies” section of build.gradle files for your application:

dependencies {
    ...
    implementation 'com. Android. Billingclient: billing: 4.0.0'
}
Copy the code

2. Initialize BillingClient

To create BillingClient, use newBuilder(). To receive a return about the purchase transaction, you must also call setListener() and pass a reference to PurchasesUpdatedListener. Open an active BillingClient connection at once to avoid multiple PurchasesUpdatedListener callbacks for one event.

private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
    @Override
    public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
        // Updates purchased from the Billing library are processed here, and the battery is processed}};private BillingClient billingClient = BillingClient.newBuilder(activity)
        .setListener(purchasesUpdatedListener)
        .enablePendingPurchases()
        .build();
Copy the code

3. Connect to Google Play

After creating BillingClient, we need to connect to Google Play.

mBillingClient.startConnection(new BillingClientStateListener() {
    @SuppressLint("WrongConstant")
    @Override
    public void onBillingSetupFinished(BillingResult billingResult) {
        // Successful link
        MLog.e("Setup finished. Response code: " + billingResult.getResponseCode());
        if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
            mIsServiceConnected = true;
            if(executeOnSuccess ! =null) { executeOnSuccess.run(); }}else {
             // The link failed
        }
        mBillingClientResponseCode = billingResult.getResponseCode();
    }

    @Override
    public void onBillingServiceDisconnected(a) {
        // The link failed
        mIsServiceConnected = false; }});Copy the code

Note: implement your own startConnection, covering the onBillingServiceDisconnected () method. When BillingClient executes any method, be sure to maintain the connection.

4. Query the detailed information of in-app products

Call querySkuDetailsAsync() to query the in-app item, passing an instance, SkuDetailsParams which specifies a list of product IDS (SkuList) and a SkuType. This SkuType can be a skutype. INAPP one-time product or a skutype. SUBS subscription fee (such as a monthly card).

Note: To query product details, your application must have a specified product ID.

Processing the results of the asynchronous operation, but also must specify an implementation of the SkuDetailsResponseListener interface.

List<String> list = new ArrayList<>();
list.add(SKU_GAS);
public void querySkuDetailsAsync(@SkuType final String itemType, final List<String> skuList,
                                 final SkuDetailsResponseListener listener) {
    Runnable queryRequest = new Runnable() {
        @Override
        public void run(a) {
            // Query the purchase async
            MLog.e("BillingManager:Query the purchase async:" + itemType);
            SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
            params.setSkusList(skuList).setType(itemType);
            mBillingClient.querySkuDetailsAsync(params.build(),
                    new SkuDetailsResponseListener() {
                        @Override
                        public void onSkuDetailsResponse(BillingResult billingResult, List
       
         skuDetailsList)
        {
                            skuDetailsList
                            MLog.e("BillingManager:onSkuDetailsResponse:"+ billingResult.getResponseCode()); listener.onSkuDetailsResponse(billingResult, skuDetailsList); }}); }}; executeServiceRequest(queryRequest); }Copy the code

Note: Some Android devices may have older Versions of Google Play Store apps that don’t support certain product types like subscriptions. Before your app starts the purchase process, you can call isFeatureSupported() to determine whether the device supports the item you’re selling.

5. Start the purchase process

The application initiates the purchase request, calling the launchBillingFlow() method.

//skuDetails is the product details queried above
public void initiatePurchaseFlow(final SkuDetails skuDetails) {
    Runnable purchaseFlowRequest = new Runnable() {
        @Override
        public void run(a) {
            MLog.e(TAG, "Launching in-app purchase flow. Replace old SKU? "+ skuDetails.getTitle()); BillingFlowParams purchaseParams = BillingFlowParams.newBuilder(). setSkuDetails(skuDetails) .build(); mBillingClient.launchBillingFlow(mActivity, purchaseParams); }}; executeServiceRequest(purchaseFlowRequest); }Copy the code

After a successful call to launchBillingFlow(), the Google Play purchase screen is displayed. The diagram below:

If the purchase is successful, a Google Play success screen is generated. The diagram below:

You must implement onPurchasesUpdated() to process the possible response code. Google Play calls onPurchasesUpdated() to deliver the result of the purchase operation to the Listener that implements the PurchasesUpdatedListener interface. The following example shows how to replace onPurchasesUpdated() :

@Override
void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
    if(billingResult.getResponseCode() == BillingResponseCode.OK && purchases ! =null) {
        for(Purchase purchase : purchases) { handlePurchase(purchase); }}else if (billingResult.getResponseCode() == BillingResponseCode.USER_CANCELED) {
        // Handle an error caused by a user cancelling the purchase flow.
    } else {
        // Handle any other error codes.}}Copy the code

If an item is successfully purchased, a purchase token is also generated, which is a unique identifier that represents the item ID of the user and the in-app item purchased.

The user also receives an email containing the transaction receipt, which contains either the order ID or the unique ID of the transaction (example: GP.9999-3333-6666-88888). If a player drops an order, gets a refund, etc., you can use the order ID in the Google Play Admin center to check the order status or give the player a refund.

6, confirm the purchase transaction (consumption is the real completion of the order)

If you are using Google Play Clearing Library version 2.0 or higher, note: if you do not confirm your purchase within three days, users will automatically receive a refund and Google Play will cancel the purchase.

The operations are as follows:

if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
    for(Purchase purchase : purchases) { handlePurchase(purchase); }}@Override
public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchaseList) {
    if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
        for(Purchase purchase : purchases) { handlePurchase(purchase); }}}void handlePurchase(Purchase purchase) {
    // Purchase retrieved from BillingClient#queryPurchasesAsync or your PurchasesUpdatedListener.Purchase purchase = ... ;// Verify the purchase.
    // Ensure entitlement was not already granted for this purchaseToken.
    // Grant entitlement to the user.

    ConsumeParams consumeParams =
        ConsumeParams.newBuilder()
            .setPurchaseToken(purchase.getPurchaseToken())
            .build();

    ConsumeResponseListener listener = new ConsumeResponseListener() {
        @Override
        public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
            if (billingResult.getResponseCode() == BillingResponseCode.OK) {
                // Handle the success of the consume operation.}}}; billingClient.consumeAsync(consumeParams, listener); }Copy the code

Note: Since the consumption request occasionally fails, my processing is to call the background interface and send the item to the user only after the consumption succeeds.

The following example shows how to use the Google Play clearing library to confirm purchase transactions:

BillingClient client = ... AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener = ... void handlePurchase(Purchase purchase) { if (purchase.getPurchaseState() == PurchaseState.PURCHASED) { if (! purchase.isAcknowledged()) { AcknowledgePurchaseParams acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder() .setPurchaseToken(purchase.getPurchaseToken()) .build(); client.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener); }}}Copy the code

7. Extract trading information

Listening to purchase transaction returns using PurchasesUpdatedListener is not enough to ensure that your application will process all purchase transactions. Sometimes your app may not know about some of the purchases that the user is making. There are several situations in which your application may not track or be unaware of a purchase transaction:

  • A network issue occurred during the purchase process: A user successfully purchased an item and received a Confirmation message from Google, but their device lost its network connection before being notified of the purchase transaction through PurchasesUpdate Listener.
  • Multiple devices: A user buys an item on one device and then expects to see that item when switching devices.
  • Processing purchase transactions made outside of your app: Some purchase transactions, such as promotional exchanges, may be made outside of your app.

In order to handle these situations, please ensure that your application in onResume () and the onCreate () method call BillingClient. QueryPurchasesAsync (), to ensure that all purchases are processed successfully, such as described in processing purchase transactions.

8. Process pending transactions

Note: Only Google Play Clearing Library 2.0 and higher supports pending transactions. Note: Other payment methods are not available for subscription purchase transactions.

Google Play supports pending transactions, which require one or more additional steps to be performed between the time a user initiates a purchase and the time the payment method of the purchase is processed. Your app may not grant rights to these types of purchase transactions until Google notifies you that the payment has been successfully made through the user’s payment method (this is the legendary card that says you can’t buy this product, but you can buy other SKU products).

Note: Only when the state is PURCHASED can you confirm the purchase transaction. When a purchase transaction is PENDING, you cannot confirm it. The 3-day confirmation period begins when the purchase state transitions from PENDING to PURCHASED.

Details can be found in the Official Google Pay documentation

July 6, 2021, the latest com. Android. Billingclient: billing: 4.0.0

  • ClassyTaxiKotlin – Sample Application for Google Pay access written by Kotlin.
  • ClassyTaxiJava – A Google Pay access sample application written by Java.

🔥 The server requires a P12 file generation method

1. Create a service account

!

2. Create a key and generate a P12 file

(If the account has changed its permission, generate P12 again. Otherwise, the request from the server may be rejected due to permission problems.)