❤️Android Google 支付集成❤️

4,956 阅读6分钟

小知识,大挑战!本文正在参与「程序员必备小知识」创作活动

🔥 作者

作者:帅次

作者简介:CSDN博客专家,欢迎点赞、收藏、评论

粉丝福利: 公众号「帅次」一个分享Android 体系技术·相关知识·面试题库·技术互助·干货·资讯·高薪职位·教程的地方。

🔥 集成 Google 支付

本文介绍了如何将 Google Play Billing Library集成到你的应用中,话不多说,上代码。

1、添加 Google Play 结算库依赖项

将以下行添加到build.gradle你应用的文件的"依赖项"部分:

dependencies {
    ...
    implementation 'com.android.billingclient:billing:4.0.0'
}

2、初始化 BillingClient

创建 BillingClient,请使用 newBuilder()。为了接收有关购买交易的返回,你还必须调用 setListener(),并传递对 PurchasesUpdatedListener 的引用。一次打开一个活跃的 BillingClient 连接,以避免对某一个事件进行多次 PurchasesUpdatedListener 回调。

private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
    @Override
    public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
        // 在这里处理从 Billing 库更新购买的回,对 purchases 进行处理
    }
};

private BillingClient billingClient = BillingClient.newBuilder(activity)
        .setListener(purchasesUpdatedListener)
        .enablePendingPurchases()
        .build();

3、连接到Google Play

创建 BillingClient 后,咱们就需要与 Google Play 建立连接。

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

    @Override
    public void onBillingServiceDisconnected() {
        //链接失败
        mIsServiceConnected = false;
    }
});

注意:实现自己的 startConnection,覆盖该 onBillingServiceDisconnected() 方法。BillingClient执行任何方法时,请确保维护连接

4、查询应用内商品详细信息

调用querySkuDetailsAsync()方法查询应用内商品,传递一个实例,SkuDetailsParams 该实例指定产品ID列表(SkuList) 和一个 SkuType。该SkuType可以是SkuType.INAPP一次性产品或SkuType.SUBS订阅费(月卡之类的)。

注意:要查询产品详细信息,你的应用必须配制好的产品ID。

image.png   处理异步操作的结果,还必须指定一个实现该 SkuDetailsResponseListener 接口。

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() {
            // 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<SkuDetails> skuDetailsList) {
                            skuDetailsList
                            MLog.e("BillingManager:onSkuDetailsResponse:" + billingResult.getResponseCode());
                            listener.onSkuDetailsResponse(billingResult, skuDetailsList);
                            
                        }
                    });
        }
    };
    executeServiceRequest(queryRequest);
}

注意:有些 Android 设备安装的可能是旧版 Google Play 商店应用,不支持订阅等某些商品类型。在你的应用进入启动购买流程之前,可以调用 isFeatureSupported() 以确定设备是否支持你要销售的商品。

5、启动购买流程

应用发起购买请求,调用 launchBillingFlow() 方法。

//skuDetails 就是上面查询到的商品详情
public void initiatePurchaseFlow(final SkuDetails skuDetails) {
    Runnable purchaseFlowRequest = new Runnable() {
        @Override
        public void run() {
            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);
}

成功调用 launchBillingFlow() 后,系统会显示 Google Play 购买屏幕。如下图:

image.png

如果成功购买商品,系统会产生一个Google Play成功屏幕。如下图:

image.png

你必须实现 onPurchasesUpdated() 来处理可能的响应代码。Google Play 会调用 onPurchasesUpdated(),以将购买操作的结果传送给实现 PurchasesUpdatedListener接口的Listener。以下示例展示了如何替换 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.
    }
}

如果成功购买商品,系统还会生成购买令牌,它是一个唯一标识符,表示用户及其所购应用内商品的商品 ID。

用户还会收到包含交易收据的电子邮件,其中包含订单 ID 或交易的唯一 ID(例:GPA.9999-3333-6666-88888)。如果有玩家掉单,退款之类的,你可以在 Google Play 管理中心内使用订单 ID 来查询订单情况或给玩家退款。

image.png

6、确认购买交易(消费掉才算真正的完结该订单)

如果你使用的是Google Play结算库2.0版或更高版本,注意:你在三天内未确认购买,用户将自动收到退款,Google Play 会撤消购买

如下操作:

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);
}

注意:由于消耗请求偶尔会失败,所以我的处理是消耗成功才调用后台接口,给用户发物品

以下示例展示了如何使用 Google Play 结算库来确认购买交易:

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);
        }
    }
}

7、提取交易信息

使用 PurchasesUpdatedListener 监听购买交易返回不足以确保你的应用会处理所有购买交易。有时你的应用可能不知道用户进行的部分购买交易。在下面这几种情况下,您的应用可能会跟踪不到或不知道购买交易:

  • 在购买过程中出现网络问题:用户成功购买了商品并收到了 Google 的确认消息,但他们的设备在通过 PurchasesUpdatedListener 收到购买交易的通知之前失去了网络连接。
  • 多台设备:用户在一台设备上购买了一件商品,然后在切换设备时期望看到该商品。
  • 处理在您的应用外进行的购买交易:某些购买交易(如促销活动兑换)可能会在您的应用外进行。

为了处理这些情况,请确保你的应用在 onResume() 和 onCreate() 方法中调用 BillingClient.queryPurchasesAsync(),以确保所有购买交易都得到成功处理,如处理购买交易中所述。

8、处理待处理的交易

注意:只有 Google Play 结算库 2.0 及更高版本支持待处理的交易。
注意:其他付款方式不可用于订阅购买交易。

Google Play 支持待处理的交易,即从用户发起购买交易到购买交易的付款方式得到处理期间需要执行一个或多个额外步骤的交易。在 Google 通知你已通过用户的付款方式成功扣款之前,你的应用不得授予对这些类型的购买交易的权利(这就是传说中的卡单,提示无法购买此产品,但是可以买其他SKU产品)。

注意:只有在状态为 PURCHASED 时,你才能确认购买交易。当购买交易处于 PENDING 状态时,你不能确认。当购买状态从PENDING转换为PURCHASED时,3 天的确认期限才会开始。

详情可通过:Google Pay官方文档 查阅

2021年7月6日修正,最新com.android.billingclient:billing:4.0.0

🔥 服务端需要P12文件生成方法

1、创建服务账号

!

2、创建密钥、生成P12文件

(如果账号修改了权限请重新生成P12,否则可能因为权限问题拒绝服务端的请求)

🔥 相关推荐

Google 支付遇到的问题

aab上传Google Play

Google 登录接入

集成 Facebook 登录

集成 Facebook 分享