从 Google Play 结算库版本 7 或 8 迁移到版本 9

本文档介绍了如何从 Google Play 结算库 (PBL) 7 或 8 迁移到 PBL 9,以及如何与新功能集成。

如需查看版本 9.0.0 的完整变更列表,请参阅版本 说明

概览

PBL 9 改进了现有 API,并移除了之前已废弃的 API。此版本的库还通过新的子响应代码引入了更丰富的错误上下文。

PBL 升级的向后兼容性

如需迁移到 PBL 9,您需要更新或移除应用中的一些现有 API 引用,如版本说明中所述,以及本迁移指南的后续内容 中所述。

从 PBL 7 或 8 升级到 PBL 9

如需从 PBL 7 或 8 升级到 PBL 9,请执行以下步骤:

  1. 在应用的 build.gradle 文件中更新 Play 结算库依赖项版本。

    dependencies {
      def billing_version = "9.0.0"
      implementation "com.android.billingclient:billing:$billing_version"
    }
    

    如果您使用的是 Kotlin,Google Play 结算库 KTX 模块包含了 Kotlin 扩展和协程支持,可让您在使用 Google Play 结算库时编写惯用的 Kotlin 代码。如需将这些扩展程序包含在项目中,请将以下依赖项添加到应用的 build.gradle 文件中,如下所示:

    dependencies {
      val billing_version = "9.0.0"
      implementation("com.android.billingclient:billing-ktx:$billing_version")
    }
    
  2. (仅适用于从 PBL 7 升级到 PBL 9)。更新 queryProductDetailsAsync 方法的实现。

    ProductDetailsResponseListener.onProductDetailsResponse 方法的签名发生了变化,这 需要您更改应用中的 queryProductDetailsAsync 实现。如需了解详情,请参阅 显示可供购买的商品

  3. 处理已移除的 API。

    下表列出了已移除的 API 以及您必须在应用中使用的相应替代 API。

    从以下版本升级

    PBL 9 不再支持下表中列出的 API。 如果您的实现使用了任何这些已移除的 API, 请参阅该表以了解其相应的替代 API。

    已移除的先前已废弃的 API 要使用的替代 API
    queryPurchaseHistoryAsync API 请参阅查询购买交易记录。如果您之前使用 queryPurchaseHistoryAsync 来确定免费试订资格,现在应使用 ProductDetails.getSubscriptionOfferDetails() 来确定用户有资格享受哪些优惠。
    BillingClient.SkuType BillingClient.ProductType。INAPP 和 SUBS 商品类型常量在功能上与已废弃的 SKU 类型常量类似。
    SkuDetails ProductDetails。这是支持一次性商品的新数据模型。
    SkuDetailsParams QueryProductDetailsParamsqueryProductDetailsAsync 搭配使用。
    SkuDetailsResponseListener ProductDetailsResponseListenerqueryProductDetailsAsync 搭配使用。
    QueryPurchaseHistoryParams
    • 对于有效或待处理的购买交易,请使用 queryPurchasesAsync
    • 在后端服务器上跟踪已消耗的购买交易。
    • 对于已取消或无效的购买交易,请使用服务器端 Voided Purchases API
    getSkuDetailsList 和 setSkuDetailsList 使用 BillingFlowParams.Builder.setProductDetailsParamsList
    querySkuDetailsAsync queryProductDetailsAsync
    enablePendingPurchases()(不带参数的 API) enablePendingPurchases(PendingPurchasesParams params)
    请注意,已废弃的 enablePendingPurchases() 在功能上等同于 enablePendingPurchases(PendingPurchasesParams.newBuilder().enableOneTimeProducts().build()).
    queryPurchasesAsync(String skuType, PurchasesResponseListener listener) queryPurchasesAsync

    从以下版本升级

    下表列出了 PBL 9 中已移除的 API,以及您必须在应用中使用的相应替代 API。

    已移除的先前已废弃的 API 要使用的替代 API
    BillingClient.SkuType BillingClient.ProductType。INAPP 和 SUBS 商品类型常量在功能上与已废弃的 SKU 类型常量类似。
    SkuDetails ProductDetails。这是支持一次性商品的新数据模型。
    SkuDetailsParams QueryProductDetailsParamsqueryProductDetailsAsync 搭配使用。
    SkuDetailsResponseListener ProductDetailsResponseListenerqueryProductDetailsAsync 搭配使用。
    QueryPurchaseHistoryParams
    • 对于有效或待处理的购买交易,请使用 queryProductDetailsAsync
    • 在后端服务器上跟踪已消耗的购买交易。
    • 对于已取消或无效的购买交易,请使用服务器端 Voided Purchases API
    getSkuDetailsList 和 setSkuDetailsList 使用 BillingFlowParams.Builder.setProductDetailsParamsList

  4. (推荐)启用自动服务重新连接。

    如果在服务断开连接时发出 API 调用,Play 结算库可以尝试自动重新建立服务连接。如需了解详情, 请参阅启用自动服务重新连接

  5. 处理新的子响应代码。

    launchBillingFlow() 返回的 BillingResult 现在将 包含一个子响应代码字段。此字段仅在某些情况下填充,以提供更具体的原因。子响应字段可以具有以下值:

    • PAYMENT_DECLINED_DUE_TO_INSUFFICIENT_FUNDS - 当用户的 资金少于其尝试购买的商品的价格时返回。
    • USER_INELIGIBLE - 当用户不符合订阅优惠的配置 资格要求时返回。
    • NO_APPLICABLE_SUB_RESPONSE_CODE - 默认值,当没有 其他子响应代码适用时返回。

    迁移步骤:更新您的 PurchasesUpdatedListener 或等效的结果处理,以识别并响应这些特定的子响应 代码,从而提供更好的用户体验。例如,提示修复付款方式或显示特定错误消息。

  6. 了解错误代码重新分类。

    对于 Play 商店应用被系统屏蔽的情况(例如,在 OEM 自定义的儿童模式下),PBL 的响应代码已从 ERROR 更改为 BILLING_UNAVAILABLE

    迁移步骤:确保您的错误处理逻辑适应此 更改,并且在这些 特定场景中不依赖于接收通用错误。

  7. 处理 DeveloperProvidedBillingDetails.getLinkUri() 可为 null 的情况。

    如果您将 DeveloperProvidedBillingDetails 用作外部支付集成的一部分,则 getLinkUri() 现在为 @Nullable

    迁移步骤:如需安全地处理此更改,请确保您的 集成代码在解析 或启动浏览器 intent 之前处理来自 DeveloperProvidedBillingDetails.getLinkUri() 方法的 null 和空字符串 ("") 值。例如:

    Kotlin

    val linkUri = details.getLinkUri()
    if (!linkUri.isNullOrEmpty()) {
      val intent = Intent(Intent.ACTION_VIEW, Uri.parse(linkUri))
      context.startActivity(intent)
    }
    

    Java

    String linkUri = details.getLinkUri();
    if (!android.text.TextUtils.isEmpty(linkUri)) {
      Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(linkUri));
      context.startActivity(intent);
    }
    
  8. 可选更改。