GooglePay 谷歌支付內(nèi)購(gòu)接入小結(jié)

近段時(shí)間在做安卓的海外項(xiàng)目,項(xiàng)目中需要使用Google Play支付,小編把Google支付的相關(guān)代碼整理下
文檔地址:
1.準(zhǔn)備文檔:https://developer.android.com/google/play/billing/getting-ready
2.集成文檔:https://developer.android.com/google/play/billing/integrate

一、前期準(zhǔn)備

設(shè)置 Google Play 開發(fā)者帳號(hào)

如需在 Google Play 上發(fā)布您的應(yīng)用和游戲,請(qǐng)使用 Google Play 管理中心。您還可以使用 Google Play 管理中心管理與結(jié)算相關(guān)的商品和設(shè)置。
如需訪問 Google Play 管理中心,您需要設(shè)置 Google Play 開發(fā)者帳號(hào)
如需在 Google Play 上銷售付費(fèi)應(yīng)用和應(yīng)用內(nèi)購(gòu)商品,您還必須在 Google 付款中心設(shè)置付款資料,然后將該付款資料與您的 Google Play 開發(fā)者帳號(hào)相關(guān)聯(lián)。如需了解如何將您的付款資料與帳號(hào)相關(guān)聯(lián),或者了解如何檢查您是否已有關(guān)聯(lián)的帳號(hào)和付款資料,請(qǐng)參閱將 Google Play 開發(fā)者帳號(hào)與您的付款資料相關(guān)聯(lián)。

創(chuàng)建商品
商品創(chuàng)建.png
添加測(cè)試賬號(hào)
添加測(cè)試賬號(hào).png

二、集成

implementation 'com.android.billingclient:billing:5.0.0'

三、代碼整理

GoogleBillingManager :處理支付的啟動(dòng)連接,關(guān)閉連接等操作
GoogleBillHelper:處理查詢、購(gòu)買、消耗等操作
GoogleBillingListener:自定義的監(jiān)聽:消耗,購(gòu)買,查詢的監(jiān)聽,(可自定義。不使用

下面附上相關(guān)代碼

GoogleBillingManager.java
import android.content.Context;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.billingclient.api.BillingClient;
import com.android.billingclient.api.BillingClientStateListener;
import com.android.billingclient.api.BillingResult;
import com.android.billingclient.api.Purchase;
import com.android.billingclient.api.PurchasesUpdatedListener;

import java.util.List;

/**
 * @author by ddy
 * Date: 2022/5/23 16:19
 * Desc:Google 支付管理
 */
public class GoogleBillingManager {
    private static GoogleBillingManager instance;
    private BillingClient billingClient;
    private GoogleBillingListener billingListener;

    private GoogleBillingManager() {
    }

    public static GoogleBillingManager getInstance() {
        if (instance == null) {
            synchronized (GoogleBillingManager.class) {
                if (instance == null) {
                    instance = new GoogleBillingManager();
                }
            }
        }
        return instance;
    }

    /**
     * 創(chuàng)建支付客戶端
     */
    public void createClient(Context context) {
        if (null == context) {
            return;
        }
        billingClient = BillingClient.newBuilder(context.getApplicationContext())
                .enablePendingPurchases()
                .setListener(new PurchasesUpdatedListener() {
                    @Override
                    public void onPurchasesUpdated(@NonNull BillingResult billingResult, @Nullable List<Purchase> purchases) {
                        if (null != billingListener) {
                            billingListener.onPurchasesUpdated(billingResult, purchases);
                        }
                    }
                })
                .build();
        //啟動(dòng)支付連接
        startConn();
    }

    public BillingClient getBillingClient() {
        return billingClient;
    }
     /**
     * 添加監(jiān)聽事件
     */
    public void setBillingListener(GoogleBillingListener billingListener) {
        this.billingListener = billingListener;
    }

    /**
     * 是否準(zhǔn)備好了
     *
     * @return
     */
    public boolean isReady() {
        return !(null == billingClient || !billingClient.isReady());
    }

    /**
     * 啟動(dòng)連接
     */
    private void startConn() {
        if (isReady()) {
            return;
        }

        billingClient.startConnection(new BillingClientStateListener() {
            @Override
            public void onBillingSetupFinished(BillingResult billingResult) {
                if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                    Log.e("TAG", "連接成功,可以開始操作了~~~");
                }
            }

            @Override
            public void onBillingServiceDisconnected() {
                //連接失敗。 可以嘗試調(diào)用 startConnection 重新建立連接
                Log.e("TAG", "連接失敗");
            }
        });

    }

    /**
     * 結(jié)束連接
     */
    public void endConn() {
        if (null != billingClient) {
            billingClient.endConnection();
        }
    }
}
GoogleBillHelper .java
package googleBilling;

import android.app.Activity;
import android.util.Log;

import com.android.billingclient.api.BillingClient;
import com.android.billingclient.api.BillingFlowParams;
import com.android.billingclient.api.ConsumeParams;
import com.android.billingclient.api.ConsumeResponseListener;
import com.android.billingclient.api.ProductDetails;
import com.android.billingclient.api.Purchase;
import com.android.billingclient.api.QueryProductDetailsParams;

import java.util.ArrayList;
import java.util.List;

/**
 * @author by ddy
 * Date: 2022/5/23 17:03
 * Desc:支付的具體操作
 * 1.查詢
 * 2.購(gòu)買
 * 3.消費(fèi)
 */
public class GoogleBillHelper {
    public static final String TAG = GoogleBillHelper.class.getSimpleName();
    /**
     * 查詢商品詳情
     *
     * @param billingListener : 接口監(jiān)聽
     * @param productIds      :商品id 。對(duì)應(yīng)Google 后臺(tái)的
     * @param productType     :取值
     *                        BillingClient.ProductType.INAPP(一次性商品)
     *                        BillingClient.ProductType.SUBS(訂閱)
     */
    public void onQuerySkuDetailsAsync(GoogleBillingListener billingListener, String productType, String... productIds) {
        if (null == productIds || productIds.length == 0
                || !GoogleBillingManager.getInstance().isReady()
        ) {
            return;
        }
        List<QueryProductDetailsParams.Product> skuList = new ArrayList<>();
        for (String productId : productIds) {
            QueryProductDetailsParams.Product product = QueryProductDetailsParams
                    .Product.newBuilder()
                    .setProductId(productId)
                    .setProductType(productType)
                    .build();
            //添加對(duì)應(yīng)的 產(chǎn)品id 去查詢?cè)斍?            skuList.add(product);
        }

        QueryProductDetailsParams params = QueryProductDetailsParams
                .newBuilder()
                .setProductList(skuList)
                .build();

        GoogleBillingManager.getInstance().getBillingClient().queryProductDetailsAsync(params, (billingResult, list) -> {
            if (BillingClient.BillingResponseCode.OK == billingResult.getResponseCode()) {
                if (null != billingListener) {
                    billingListener.onProductDetailsSus(list);
                }
            } else {
                Log.e("TAG", "code : " + billingResult.getResponseCode() + " message : " + billingResult.getDebugMessage());
            }
        });
    }

    /**
     * 打開支付面板
     *
     * @param billingListener
     * @param activity
     * @param details
     */
    public void onOpenGooglePlay(GoogleBillingListener billingListener, Activity activity, ProductDetails details) {
        if (null == details) {
            return;
        }
        List<BillingFlowParams.ProductDetailsParams> params = new ArrayList<>();
        //添加購(gòu)買數(shù)據(jù)
        BillingFlowParams.ProductDetailsParams productDetailsParams = BillingFlowParams.ProductDetailsParams
                .newBuilder()
                .setProductDetails(details)
                .build();
        params.add(productDetailsParams);

        BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
                .setProductDetailsParamsList(params)
                .build();
        //響應(yīng)code 碼
        int responseCode = GoogleBillingManager.getInstance().getBillingClient().launchBillingFlow(activity, billingFlowParams).getResponseCode();
        //成功換起
        if (BillingClient.BillingResponseCode.OK == responseCode) {
            //添加購(gòu)買監(jiān)聽
            GoogleBillingManager.getInstance().setBillingListener(billingListener);
        }
    }
    /**
     * 消費(fèi)商品
     * 對(duì)于購(gòu)買類型的商品需要手動(dòng)調(diào)用一次消費(fèi)方法 (目的:用戶可以再次購(gòu)買此商品)
     *
     * @param billingListener
     * @param purchase
     */
    public void onConsumeAsync(GoogleBillingListener billingListener, Purchase purchase) {
        if (!GoogleBillingManager.getInstance().isReady()) {
            return;
        }
        ConsumeParams consumeParams =
                ConsumeParams.newBuilder()
                        .setPurchaseToken(purchase.getPurchaseToken())
                        .build();

        ConsumeResponseListener listener = (billingResult, purchaseToken) -> {
            if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                if (null != billingListener) {
                    billingListener.onConsumeSus(purchaseToken);
                } else {
                    Log.e(TAG, "消費(fèi)失敗 code : " + billingResult.getResponseCode() + " message : " + billingResult.getDebugMessage());
                }
            }
        };
        GoogleBillingManager.getInstance().getBillingClient().consumeAsync(consumeParams, listener);
    }
}

GoogleBillingListener.java
package googleBilling;

import com.android.billingclient.api.BillingResult;
import com.android.billingclient.api.ProductDetails;
import com.android.billingclient.api.Purchase;

import java.util.List;

/**
 * @author by ddy
 * Date: 2022/5/23 17:12
 * Desc:監(jiān)聽
 */
public interface GoogleBillingListener {
    /**
     * 購(gòu)買監(jiān)聽
     *
     * @param result
     * @param purchases
     */
    default void onPurchasesUpdated(BillingResult result, List<Purchase> purchases) {

    }

    /**
     * 查詢商品詳情成功
     *
     * @param list
     */
    default void onProductDetailsSus(List<ProductDetails> list) {

    }

    /**
     * 商品消費(fèi)成功
     *
     * @param purchaseToken
     */
    default void onConsumeSus(String purchaseToken) {

    }
}

三、支付流程步驟

1.與Google Play建立支付連接
2.查詢購(gòu)買商品詳情數(shù)據(jù)
3.喚起支付面板
4.支付結(jié)果回調(diào)
5.消費(fèi)商品(對(duì)于購(gòu)買類商品在購(gòu)買完,需將其消費(fèi)掉)

四、Demo示例

import android.os.Bundle;
import android.util.Log;
import android.view.View;

import androidx.appcompat.app.AppCompatActivity;

import com.android.billingclient.api.BillingClient;
import com.android.billingclient.api.BillingResult;
import com.android.billingclient.api.ProductDetails;
import com.android.billingclient.api.Purchase;

import java.util.List;

import googleBilling.GoogleBillHelper;
import googleBilling.GoogleBillingListener;
import googleBilling.GoogleBillingManager;

public class MainActivity extends AppCompatActivity {
    private GoogleBillHelper billProxy = new GoogleBillHelper();
    private GoogleBillingListenerImpl billingListenerImpl = new GoogleBillingListenerImpl();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //建立連接
        GoogleBillingManager.getInstance().createClient(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //結(jié)束連接
        GoogleBillingManager.getInstance().endConn();
    }

    /**
     * 點(diǎn)擊購(gòu)買
     * 換起Google 支付面前 ,需要查詢是否有對(duì)應(yīng)的APP商品
     * @param view
     */
    public void onClickGooglePlay(View view) {
        billProxy
            .onQuerySkuDetailsAsync(
             billingListenerImpl,
             BillingClient.ProductType.INAPP,
             "谷歌后臺(tái)的商品id名字");
    }
    
    //事件監(jiān)聽
    private class GoogleBillingListenerImpl implements GoogleBillingListener {
        /**
         * 產(chǎn)品查詢成功
         *
         * @param list
         */
        @Override
        public void onProductDetailsSus(List<ProductDetails> list) {
            GoogleBillingListener.super.onProductDetailsSus(list);
            if (null == list || list.size() <= 0) {
                Log.e("TAG", "沒有查詢到相關(guān)產(chǎn)品~~~~");
                return;
            }
            //查詢方法中只傳了一個(gè)商品,所以直接取第一個(gè)了
            //根據(jù)實(shí)際情況處理~
            billProxy.onOpenGooglePlay(this, MainActivity.this, list.get(0));
        }

        /**
         * 購(gòu)買監(jiān)聽
         *
         * @param result
         * @param purchases
         */
        @Override
        public void onPurchasesUpdated(BillingResult result, List<Purchase> purchases) {
            GoogleBillingListener.super.onPurchasesUpdated(result, purchases);
            if (null == purchases || purchases.size() == 0) {
                return;
            }
          //循環(huán)調(diào)用消耗
            for (Purchase purchase : purchases) {
                billProxy.onConsumeAsync(this, purchase);
            }
        }

        /**
         * 消費(fèi)監(jiān)聽
         * @param purchaseToken
         */
        @Override
        public void onConsumeSus(String purchaseToken) {
            GoogleBillingListener.super.onConsumeSus(purchaseToken);
            Log.e("TAG","消費(fèi)結(jié)束,處理自己的業(yè)務(wù)邏輯~~~");
            //去與后臺(tái)驗(yàn)證。處理APP的頁(yè)面邏輯, 比如充值后發(fā)放金幣啥的~~~
        }
    }
}

五、注意事項(xiàng)

1.引用庫(kù)5.0.0 與 3.0.3 版本差異:

5.x在使用查詢方法時(shí),onQuerySkuDetailsAsync所傳的產(chǎn)品id可以是Google Play >后臺(tái)不一致,查詢不到不會(huì)返回該商品的詳情數(shù)據(jù),而3.0.3查詢是所傳的產(chǎn)品>Google Play 必須存在

待續(xù)。。。。

五、總結(jié)

1.在Google Play 控制臺(tái)創(chuàng)建應(yīng)用、應(yīng)用內(nèi)商品。
2.發(fā)布應(yīng)用到內(nèi)測(cè)版或者正式版。
3.在Google Play 控制臺(tái)添加測(cè)試賬號(hào),用這個(gè)賬號(hào)來測(cè)試支付。

到此,支付的基本操作已分享。自己動(dòng)手試一試吧!
如果你覺得該文章對(duì)你有用,動(dòng)動(dòng)你的小手指,舉手之勞,贊有余香!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容