Google paly支付

2,481 阅读8分钟

现在google play 支付由原来的AIDL支持方式改成google play结算库支付,AIDL支付方式已弃用。

google paly:developer.android.com/google/play…

AIDL:developer.android.com/google/play…

本文章主要介绍google play结算库支付

首先

  1. 手机支持google服务
  2. 手机安装google paly商店
  3. 拥有google开发者账号
  4. 设置定价模板(用于支付的商品)


等所有把google信息都创建好后,开始准备代码。

代码

  • 添加依赖
implementation 'com.android.billingclient:billing:2.0.3'
  • 添加权限
<uses-permission android:name="com.android.vending.BILLING" />

  • 代码
一、连接到 Google Play

您必须先建立与 Google Play 的连接,然后才能发送 Google Play 结算服务请求,建立连接的具体操作步骤如下:

  1. 调用 newBuilder() 以创建 BillingClient 实例。您还必须调用 setListener(),并传入对 PurchasesUpdatedListener 的引用,以接收通过您的应用以及 Google Play 商店发起的购买交易的更新。

  2. 建立与 Google Play 的连接。该设置过程是异步的执行,因此您必须实现 BillingClientStateListener,以在客户端设置完成并准备好发送进一步请求时收到回调。

  3. 替换 onBillingServiceDisconnected() 回调方法并实现您自己的重试政策,以便在客户端丢失连接时处理 Google Play 连接丢失的问题。例如,如果 Google Play 商店服务正在后台更新,那么 BillingClient 可能会失去连接。在发送进一步的请求之前,BillingClient 必须先调用 startConnection() 方法以重启连接。

以下代码示例演示了如何启动连接并测试它是否已可供使用:

private BillingClient billingClient;

billingClient = BillingClient.newBuilder(activity).setListener(this).build();
billingClient.startConnection(new BillingClientStateListener() {    
    @Override    
    public void onBillingSetupFinished(BillingResult billingResult) {
        if (billingResult.getResponseCode() == BillingResponse.OK) {
            // The BillingClient is ready. You can query purchases here.        
        }    
    }    
    @Override    
    public void onBillingServiceDisconnected() {
        // Try to restart the connection on the next request to        
        // Google Play by calling the startConnection() method.    
        }
    });

二、查询应用内商品详情

您在配置应用内商品时创建的唯一商品 ID 将用于向 Google Play 异步查询应用内商品详情。要向 Google Play 查询应用内商品的详情,请调用 querySkuDetailsAsync()。调用此方法时,请传入指定商品 ID 字符串列表和 SkuTypeSkuDetailsParams 实例。该 SkuType 可以是 SkuType.INAPP(针对一次性商品或奖励产品),也可以是 SkuType.SUBS(针对订阅)。

注意:为了查询商品详情,应用需要使用您在 Google Play 管理中心内配置商品时定义的商品 ID。要了解详情,请参阅添加一次性商品专用功能添加奖励产品专用功能添加订阅专用功能

为了处理该异步操作的结果,您还必须指定实现 SkuDetailsResponseListener 接口的监听器。然后,您就可以替换 onSkuDetailsResponse(),该方法会在查询完成时通知监听器。

您的应用应维护它自己的商品 ID 列表,方法是将该列表与您的 APK 捆绑在一起,或者从您自己的安全后端服务器查询。

调用 getResponseCode() 可检索响应代码。如果请求成功,则响应代码为 BillingResponse.OK。要查看 Google Play 可能发送的其他响应代码的列表,请参阅 BillingClient.BillingResponse

如果发生错误,您可以使用 getDebugMessage() 来查看相关的错误消息。

Google Play 结算库会将查询结果存储在 SkuDetails 对象的 List 中。您随后可以在该列表中的每个 SkuDetails对象上调用各种方法,以查看应用内商品的相关信息,如其价格或说明。要查看可用的商品详情,请参阅 SkuDetails类中的方法列表。

以下示例显示了如何使用先前代码段返回的 SkuDetails 对象来检索应用内商品的价格:

如以下示例代码所示:

List<String> skuList = new ArrayList<> ();
skuList.add("premium_upgrade");
skuList.add("gas");
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
params.setSkusList(skuList).setType(SkuType.INAPP);
billingClient.querySkuDetailsAsync(params.build(),new SkuDetailsResponseListener() {
    @Override        
    public void onSkuDetailsResponse(BillingResult billingResult,List<SkuDetails> skuDetailsList) {
        // Process the result. 
        if (billingResult.getResponseCode() == BillingResponse.OK && skuDetailsList != null) {   for (SkuDetails skuDetails : skuDetailsList) {
               String sku = skuDetails.getSku();
               String price = skuDetails.getPrice();
           if ("premium_upgrade".equals(sku)) {
                premiumUpgradePrice = price;       
                } else if ("gas".equals(sku)) {
                   gasPrice = price;       
                }   
            }}               }    
   });

启用应用内商品的购买

有些 Android 手机安装的 Google Play 商店应用可能是旧版的,不支持订阅等商品类型。因此,在应用进入结算流程之前,请调用 isFeatureSupported() 以检查设备是否支持您要销售的商品。要查看商品类型列表,请参阅 BillingClient.FeatureType

要从应用发起购买请求,请从界面线程调用 launchBillingFlow() 方法。传入对 BillingFlowParams 对象的引用,该对象中包含完成购买交易所需的相关数据,如商品的商品 ID (skuId) 和商品类型(SkuType.INAPP - 针对一次性商品或奖励产品,或者 SkuType.SUBS - 针对订阅)。要获取 BillingFlowParams 实例,请使用 BillingFlowParams.Builder 类:

// Retrieve a value for "skuDetails" by calling querySkuDetailsAsync().
BillingFlowParams flowParams = BillingFlowParams.newBuilder()
        .setSkuDetails(skuDetails)        
        .build();
int responseCode = billingClient.launchBillingFlow(flowParams);

获取支付结果

launchBillingFlow() 方法会返回 BillingClient.BillingResponse 中列出的几个响应代码之一。Google Play 会调用 onPurchasesUpdated() 方法,将购买操作的结果传递给实现 PurchasesUpdatedListener 接口的监听器。您可以使用 setListener() 方法指定监听器,如前面连接到 Google Play 部分中所述。

您必须实现 onPurchasesUpdated() 方法来处理可能的响应代码。以下代码段显示了如何替换 onPurchasesUpdated() 方法:

public class XXXXX  extends Activity implements PurchasesUpdatedListener{

@Overridevoid onPurchasesUpdated(BillingResult billingResult,
        List<Purchase> purchases){
    if (billingResult.getResponseCode() == BillingResponse.OK && purchases != null) {
        for (Purchase purchase : purchases) {
            handlePurchase(purchase);//支付成功需要在goole进行消耗        
        }    
    } else if (billingResult.getResponseCode() == BillingResponse.USER_CANCELED) {
        // Handle an error caused by a user cancelling the purchase flow.    
    } else {        
        // Handle any other error codes.    
    }}
}

确认购买交易(在google进行消耗)

如果您使用的是 Google Play 结算库版本 2.0 或更高版本,则必须在三天内确认所有购买交易。如果没能正确确认,将导致系统对相应购买交易按退款处理。

Google Play 支持从您的应用内部(应用内)或您的应用外部(应用外)购买商品。为了确保无论用户在哪里购买您的商品,Google Play 都能提供一致的购买体验,您必须在授予用户权利后尽快确认通过 Google Play 结算库收到的所有处于 SUCCESS 状态的购买交易。如果您在三天内未确认购买交易,则用户会自动收到退款,并且 Google Play 会撤消该购买交易。对于待处理的交易,该三天期限不包含购买交易处于 PENDING 状态的时间,而是从购买交易改为 SUCCESS 状态时起算。

您可以使用以下某种方法来确认购买交易:

  • 对于消耗型商品,请使用客户端 API 中的 consumeAsync()
    ConsumeParams consumeParams = ConsumeParams.newBuilder()
                        .setPurchaseToken(/* token */)
                        .setDeveloperPayload(/* payload */)
                        .build();
        client.consumeAsync(consumeParams, new ConsumeResponseListener() {
            @Override    
        public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
                          }
});
AcknowledgePurchaseParams acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder()
                .setPurchaseToken(/* token */)        
                .setDeveloperPayload(/* payload */)
            .build();
client.acknowledgePurchase(acknowledgePurchaseParams, new AcknowledgePurchaseResponseListener() {
        @Override    
        public void onAcknowledgePurchaseResponse(BillingResult billingResult) {
            
        }
    });
  • 还可以使用服务器 API 中新增的 acknowledge() 方法。
AcknowledgePurchaseParams acknowledgePurchaseParams= AcknowledgePurchaseParams.newBuilder()        
        .setPurchaseToken(purchase.getPurchaseToken())        
        .setDeveloperPayload(purchase.getDeveloperPayload())        
        .build();
mBillingClient.acknowledgePurchase(acknowledgePurchaseParams, new AcknowledgePurchaseResponseListener() {
        @Override    
        public void onAcknowledgePurchaseResponse(BillingResult billingResult) {
            
        }
    });

对于订阅,您必须确认包含新购买令牌的任何购买交易。这意味着,需要确认所有初始购买、计划变更和重新注册,但无需确认后续续订。要确定购买交易是否需要确认,您可以检查购买交易中的确认字段。

Purchase 对象包含 isAcknowledged() 方法,该方法用于指示购买交易是否已得到确认。此外,服务器端 API 包含 Product.purchases.get()Product.subscriptions.get() 的确认布尔值。在确认购买交易之前,请使用这些方法来确定购买交易是否已得到确认。

以下示例显示了如何确认订阅购买交易:

void handlePurchase(Purchase purchase) {    
if (purchase.getPurchaseState() == PurchaseState.PURCHASED) {
        // Grant entitlement to the user.        ...        
        // Acknowledge the purchase if it hasn't already been acknowledged.        
    if (!purchase.isAcknowledged()) {
             //进行调用对应的消耗
        }
    }}

支持待处理的交易

在实现 Google Play 结算服务解决方案时,您必须支持在授予权利之前需要执行其他操作的购买交易。

例如,用户可能会选择使用现金在实体店购买您的应用内商品。这意味着,交易在您的应用外部完成。在这种情况下,只有在用户完成交易后,您才能授予权利。

要启用待处理的购买交易,请在初始化应用时调用 enablePendingPurchases()。请注意,如果您不调用 enablePendingPurchases(),则无法实例化 Google Play 结算库。

使用 Purchase.getPurchaseState() 方法确定购买交易的状态是 PURCHASED 还是 PENDING。请注意,只有在状态为 PURCHASED 时,您才能授予权利。您可以通过执行以下操作来检查状态更改:

  1. 启动应用时,调用 BillingClient.queryPurchases() 以检索与用户关联的非消耗型商品的列表,然后对返回的每个 Purchase 对象调用 getPurchaseState()
  2. 实现 onPurchasesUpdated() 方法以响应对 Purchase 对象进行的更改。

以下示例演示了您可以如何处理待处理的交易:

void handlePurchase(Purchase purchase) {
    if (purchase.getPurchaseState() == PurchaseState.PURCHASED) {
        // Acknowledge purchase and grant the item to the user    
} else if (purchase.getPurchaseState() == PurchaseState.PENDING) {
        // Here you can confirm to the user that they've started the pending
        // purchase, and to complete it, they should follow instructions that
        // are given to them. You can also choose to remind the user in the        
        // future to complete the purchase if you detect that it is still
        // pending.    
}}

关闭google play的长链接

@Overrideprotected void onDestroy() {
    super.onDestroy();
    if (mBillingClient != null) {
        mBillingClient.endConnection();
    }}

以上就是google play支付的全部流程。

一定要注意支付完成后需要在google play的支付回调里进行消耗,如不进行消耗则下次支付不成功。