Android GooglePay集成

  • 流程
    1.跟你們的后臺拿到商品ID
    2.連接到GooglePay服務(wù)
    3.查詢這個商品ID得到商品詳情
    4.根據(jù)商品詳情打開GooglePay購買頁面

  • 前言
    1.請使用海外版的手機(jī)或者你可以刷一個國際版MIUI司草,否則即使你的手機(jī)安裝了Google服務(wù)也無法購買
    2.科學(xué)上網(wǎng)
    3.你的App必須已經(jīng)在Google Play應(yīng)用市場上架成功(https://play.google.com/apps/publish)
    4.當(dāng)你把下面的代碼集成好之后 需要先把這個APP發(fā)布到測試艰垂,并添加測試人員的賬號,然后給鏈接邀請他們進(jìn)入測試 并下載測試包埋虹。否則你會無法購買
    image.png

    5.有疑問請聯(lián)系我的郵箱我每天上班的時候會看一下742831652@qq.com


  • AndroidManifest.xml
<!-- Google Play 內(nèi)購權(quán)限 -->
<uses-permission android:name="com.android.vending.BILLING" />
<uses-permission android:name="com.farsitel.bazaar.permission.PAY_THROUGH_BAZAAR" />
  • build.gradle
dependencies {
    //GooglePay
    implementation 'com.android.billingclient:billing:3.0.0'
}
  • 開始支付
/**
 * 開始支付
 * 
 * @param activity
 * @param skuId    商品ID
 */
GooglePayUtil.getInstance().start(Activity activity, String skuId);

GooglePayUtil.java

import android.app.Activity;
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.BillingFlowParams;
import com.android.billingclient.api.BillingResult;
import com.android.billingclient.api.ConsumeParams;
import com.android.billingclient.api.ConsumeResponseListener;
import com.android.billingclient.api.Purchase;
import com.android.billingclient.api.PurchasesUpdatedListener;
import com.android.billingclient.api.SkuDetails;
import com.android.billingclient.api.SkuDetailsParams;
import com.android.billingclient.api.SkuDetailsResponseListener;

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

public class GooglePayUtil implements PurchasesUpdatedListener {

    private String TAG = "GooglePayUtil";
    private static GooglePayUtil instance;

    //獲取實例
    public static synchronized GooglePayUtil getInstance() {
        if (instance == null) {
            instance = new GooglePayUtil();
        }
        return instance;
    }

    private Activity activity;
    private BillingClient billingClient;

    /**
     * 開始支付
     *
     * @param activity
     * @param skuId    商品ID
     */
    public void start(Activity activity, String skuId) {
        this.activity = activity;
        if (billingClient == null) {
            billingClient = BillingClient.newBuilder(activity).setListener(this).enablePendingPurchases().build();
        }
        if (billingClient.isReady()) {
            checkSku(skuId);
        } else {
            connectGooglePay(skuId);
        }
    }


    //連接到GooglePay
    private void connectGooglePay(String skuId) {
        //請求連接到GooglePay
        billingClient.startConnection(new BillingClientStateListener() {
            @Override
            public void onBillingSetupFinished(@NonNull BillingResult billingResult) {
                int code = billingResult.getResponseCode();
                if (code != BillingClient.BillingResponseCode.OK) {
                    String msg = billingResult.getDebugMessage();
                    Log.e(TAG, "連接到GooglePay失敗    code = " + code + "    msg = " + msg);
                    onFail();
                    return;
                }
                Log.e(TAG, "連接到GooglePay成功");
                checkSku(skuId);
            }

            //連接失敗
            @Override
            public void onBillingServiceDisconnected() {
                Log.e(TAG, "連接到GooglePay失敗猜憎,請重試");
            }
        });
    }

    //查詢商品
    private void checkSku(String id) {
        List<String> skuList = new ArrayList<>();
        skuList.add(id);
        SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder()
                .setSkusList(skuList)
                .setType(BillingClient.SkuType.INAPP);
        billingClient.querySkuDetailsAsync(params.build(), new SkuDetailsResponseListener() {
            @Override
            public void onSkuDetailsResponse(@NonNull BillingResult billingResult, @Nullable List<SkuDetails> list) {
                int code = billingResult.getResponseCode();
                if (code != BillingClient.BillingResponseCode.OK || list == null || list.isEmpty()) {
                    String msg = billingResult.getDebugMessage();
                    Log.e(TAG, "查詢商品失敗    code = " + code + "    msg = " + msg);
                    onFail();
                    return;
                }
                Log.e(TAG, "查詢商品成功");
                buyIt(list.get(0));
            }
        });
    }

    //購買
    private void buyIt(SkuDetails skuDetails) {
        BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
                .setSkuDetails(skuDetails)
                .build();
        BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);
        int code = billingResult.getResponseCode();
        if (code != BillingClient.BillingResponseCode.OK) {
            String msg = billingResult.getDebugMessage();
            Log.e(TAG, "購買商品失敗    code = " + code + "    msg = " + msg);
            onFail();
            return;
        }
        Log.e(TAG, "購買商品" + skuDetails.toString());
    }

    @Override
    public void onPurchasesUpdated(@NonNull BillingResult billingResult, @Nullable List<Purchase> list) {
        int code = billingResult.getResponseCode();
        String msg = billingResult.getDebugMessage();
        Log.e(TAG, "onPurchasesUpdated:code = " + code + "    msg = " + msg);
        if (list != null) {
            for (Purchase purchase : list) {
                Log.e(TAG, "onPurchasesUpdated:" + purchase.toString());
            }
        }
        if (code == BillingClient.BillingResponseCode.OK && list != null) {
            Log.e(TAG, "支付成功");
            onSuccess(list);
        } else if (code == BillingClient.BillingResponseCode.USER_CANCELED) {
            Log.e(TAG, "支付取消");
            onFail();
        } else {
            Log.e(TAG, "支付失敗:code = " + code + "    msg = " + msg);
            onFail();
        }
    }

    //消耗商品   使得商品可以重復(fù)購買
    private void consume(List<Purchase> list) {
        if (list == null || list.isEmpty() || billingClient == null) {
            return;
        }
        for (Purchase purchase : list) {
            billingClient.consumeAsync(ConsumeParams.newBuilder().setPurchaseToken(purchase.getPurchaseToken()).build(), new ConsumeResponseListener() {
                @Override
                public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
                    Log.e(TAG, "onConsumeResponse    code = " + billingResult.getResponseCode() + " ,  msg = " + billingResult.getDebugMessage() + " , purchaseToken = " + purchaseToken);
                }
            });
        }
    }

    private void onFail() {
        //自己寫關(guān)于支付失敗后的操作
    }

    private void onSuccess(List<Purchase> list) {
        //自己寫關(guān)于支付成功后的操作
    }
}

  • 支付成功JSON數(shù)據(jù)示例
{
  "orderId": "GPA.3326-0188-4891-58028",
  "packageName": "com.xxx.xxx",//你APP的包名
  "productId": "1235",//你的SkuId
  "purchaseTime": 1613978031669,
  "purchaseState": 0,
  "purchaseToken": "kcjjnpeomlglnbnodpfdocdm.AO-J1OwrW_apUdDL6icLsqUlvp8JH-CD8ID35fCF1WtPnDvRUnS-AbkW_eNiwAoVFoYEnrho1txWinDibganiZRv8cSspkXXXQ",
  "acknowledged": false
}

  • 1.GooglePay默認(rèn)只能購買一次搔课,如果你需要重復(fù)購買一個商品 請調(diào)用consume方法
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末胰柑,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌柬讨,老刑警劉巖崩瓤,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異踩官,居然都是意外死亡却桶,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門蔗牡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來颖系,“玉大人,你說我怎么就攤上這事辩越∴叶螅” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵黔攒,是天一觀的道長趁啸。 經(jīng)常有香客問我,道長督惰,這世上最難降的妖魔是什么不傅? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮姑丑,結(jié)果婚禮上蛤签,老公的妹妹穿的比我還像新娘。我一直安慰自己栅哀,他們只是感情好震肮,可當(dāng)我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著留拾,像睡著了一般戳晌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上痴柔,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天沦偎,我揣著相機(jī)與錄音,去河邊找鬼咳蔚。 笑死豪嚎,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的谈火。 我是一名探鬼主播侈询,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼糯耍!你這毒婦竟也來了扔字?” 一聲冷哼從身側(cè)響起囊嘉,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎革为,沒想到半個月后扭粱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡震檩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年琢蛤,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片恳蹲。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡虐块,死狀恐怖俩滥,靈堂內(nèi)的尸體忽然破棺而出嘉蕾,到底是詐尸還是另有隱情,我是刑警寧澤霜旧,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布错忱,位于F島的核電站,受9級特大地震影響挂据,放射性物質(zhì)發(fā)生泄漏以清。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一崎逃、第九天 我趴在偏房一處隱蔽的房頂上張望掷倔。 院中可真熱鬧,春花似錦个绍、人聲如沸勒葱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽凛虽。三九已至,卻和暖如春广恢,著一層夾襖步出監(jiān)牢的瞬間元暴,已是汗流浹背夏漱。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人连茧。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像郊艘,于是被迫代替她去往敵國和親款票。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容