メインコンテンツまでスキップ

从旧版 AppCoins SDK 迁移到新版 Aptoide SDK

概述

本次迁移将旧版 AppCoins Billing SDKio.catappult:android-appcoins-billing)替换为最新的 Aptoide Billing SDKcom.aptoide:android-aptoide-billing)。新版 SDK 带来了现代化的 API、更简洁的结构、对 Android 功能更好的兼容性,并与行业计费标准更紧密地保持一致。以下步骤涵盖了替换依赖项、采用 AptoideBillingClient 以及更新购买和商品查询。

迁移步骤摘要

成功完成迁移的主要步骤如下:

  1. 更新 SDK 依赖项
    在 Gradle 文件中将 AppCoins SDK 依赖项替换为新版 Aptoide SDK。

  2. 重构 Billing Client 初始化
    使用新的构建器模式将 AppcoinsBillingClient 替换为 AptoideBillingClient

  3. 更新购买监听器
    更新 PurchasesUpdatedListener,使其处理 BillingResult 而非用于 ResponseCode 的整数。

  4. 更新购买查询逻辑
    queryPurchases(SkuType) 替换为 queryPurchasesAsync(QueryPurchasesParams)

  5. 迁移商品查询逻辑
    querySkuDetailsAsync 替换为 queryProductDetailsAsync,使用 QueryProductDetailsParams 定义要搜索的商品类型,并接收 ProductDetails 而非 SkuDetails

  6. 更新购买流程
    将基于 SKU 的直接购买替换为使用 ProductDetailsParamsBillingFlowParams

  7. 重构消耗逻辑
    将旧的 consumeAsync(token) 方法替换为使用 ConsumeParams 的新方法。


1. 更新 SDK 依赖项

AppCoins SDK:

implementation("io.catappult:android-appcoins-billing:0.9.+")

Aptoide SDK:

implementation("com.aptoide:android-aptoide-billing:1.+")

更新你的 build.gradle 并同步项目。
项目同步完成后,按照下面的示例,通过将 appcoins 替换为 aptoide,将旧版 AppCoins Billing SDK 的所有导入更新为新版 Aptoide Billing SDK。

旧版导入:

import com.appcoins.sdk.billing.Purchase

新版导入:

import com.aptoide.sdk.billing.Purchase

2. 重构 Billing Client 初始化

旧版初始化:

val cab = CatapultBillingAppCoinsFactory.BuildAppcoinsBilling(context, publicKey, listener)  
cab.startConnection(appCoinsBillingStateListener)
CatappultAppcoinsBilling cab = CatapultBillingAppCoinsFactory.BuildAppcoinsBilling(context, publicKey, listener)  
cab.startConnection(appCoinsBillingStateListener)

新版初始化:

val billingClient = AptoideBillingClient.newBuilder(context)  
.setListener(purchasesUpdatedListener)
.setPublicKey(publicKey)
.build()

billingClient.startConnection(aptoideBillingClientStateListener)
AptoideBillingClient billingClient = AptoideBillingClient.newBuilder(context)
.setListener(purchasesUpdatedListener)
.setPublicKey(publicKey)
.build();

billingClient.startConnection(aptoideBillingClientStateListener);

所需更改:

  • AppcoinsBillingClient 替换为 AptoideBillingClient
  • AppCoinsBillingStateListener 替换为 AptoideBillingClientStateListener
  • 对于响应代码,使用 BillingResult 而非原始整数

3. 更新购买监听器

旧版:

val purchasesUpdatedListener = PurchasesUpdatedListener { responseCode, purchases ->
if (responseCode == ResponseCode.OK.value) {
for (purchase in purchases) {
// Apply here your Purchase result logic
}
}
}
PurchasesUpdatedListener purchasesUpdatedListener = (responseCode, purchases) -> {
if (responseCode == ResponseCode.OK.getValue()) {
for (Purchase purchase : purchases) {
// Apply here your Purchase result logic
}
}
};

新版:

val purchasesUpdatedListener = PurchasesUpdatedListener { billingResult, purchases ->
if (billingResult.responseCode == BillingResponseCode.OK) {
for (purchase in purchases) {
// Apply here your Purchase result logic
}
}
}
PurchasesUpdatedListener purchasesUpdatedListener = (billingResult, purchases) -> {
if (billingResult.getResponseCode() == BillingResponseCode.OK) {
for (Purchase purchase : purchases) {
// Apply here your Purchase result logic
}
}
};

要点:

  • 响应代码现在来自 billingResult.responseCode
  • 提取令牌以及处理交付/消耗的逻辑保持不变

4. 更新购买查询逻辑

旧版:

val purchasesResult = cab.queryPurchases(SkuType.inapp)
PurchasesResult purchasesResult = cab.queryPurchases(SkuType.inapp)

新版:

val params = QueryPurchasesParams.newBuilder()
.setProductType(ProductType.INAPP)
.build()

billingClient.queryPurchasesAsync(params) { billingResult, purchases ->
// Handle results
}
QueryPurchasesParams params = QueryPurchasesParams.newBuilder()
.setProductType(ProductType.INAPP)
.build();

billingClient.queryPurchasesAsync(params, (billingResult, purchases) -> {
// Handle results
});

5. 迁移商品查询逻辑

旧版:

cab.querySkuDetailsAsync(SkuDetailsParams(...), listener)
cab.querySkuDetailsAsync(new SkuDetailsParams(...), listener)

新版:

val params = QueryProductDetailsParams.newBuilder()
.setProductList(
listOf(
Product.newBuilder()
.setProductId("your_product_id")
.setProductType(ProductType.INAPP)
.build()
)
).build()

billingClient.queryProductDetailsAsync(params) { billingResult, productDetailsResult ->
if (billingResult.responseCode == BillingResponseCode.OK) {
for (product in productDetailsResult.productDetailsList) {
// Use product details here
}
}
}
QueryProductDetailsParams params = QueryProductDetailsParams.newBuilder()
.setProductList(
List.of(
Product.newBuilder()
.setProductId("your_product_id")
.setProductType(ProductType.INAPP)
.build()
)
).build();

billingClient.queryProductDetailsAsync(params, (billingResult, productDetailsResult) -> {
if (billingResult.getResponseCode() == BillingResponseCode.OK) {
for (ProductDetails product : productDetailsResult.getProductDetailsList()) {
// Use product details here
}
}
});

注意事项:

  • SkuDetailsParams 替换为 QueryProductDetailsParams
  • SkuType 替换为 ProductType

6. 更新购买流程

旧版:

val billingFlowParams = BillingFlowParams(...)  
cab.launchBillingFlow(activity, billingFlowParams)
BillingFlowParams billingFlowParams = new BillingFlowParams(...);
cab.launchBillingFlow(activity, billingFlowParams);

新版:

val productDetailsParams = BillingFlowParams.ProductDetailsParams.newBuilder()
.setProductDetails(productDetails)
.build()

val billingFlowParams = BillingFlowParams.newBuilder()
.setProductDetailsParamsList(listOf(productDetailsParams))
.setObfuscatedAccountId(userId)
.setFreeTrial(true)
.build()

billingClient.launchBillingFlow(activity, billingFlowParams)
BillingFlowParams.ProductDetailsParams productParams =
BillingFlowParams.ProductDetailsParams.newBuilder()
.setProductDetails(productDetails)
.build();

BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
.setProductDetailsParamsList(List.of(productParams))
.setObfuscatedAccountId(userId)
.setFreeTrial(true) // Use this to initiate Free Trials
.build();

billingClient.launchBillingFlow(activity, billingFlowParams);

主要更改:

  • 使用 ProductDetails 而非原始 SKU 字符串
  • 添加 setObfuscatedAccountId() 用于用户级别的跟踪
  • setFreeTrial() 处理试用逻辑

7. 重构消耗逻辑

旧版:

cab.consumeAsync(purchase.token, consumeResponseListener)
cab.consumeAsync(purchase.getToken(), consumeResponseListener);

新版:

val consumeParams = ConsumeParams.newBuilder()
.setPurchaseToken(purchase.purchaseToken)
.build()

billingClient.consumeAsync(consumeParams, consumeResponseListener)
ConsumeParams consumeParams = ConsumeParams.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
.build();

billingClient.consumeAsync(consumeParams, consumeResponseListener);

重要:

  • 务必在 48 小时内消耗购买
  • 订阅也应被消耗或确认(通过 Backend API

更改对比表

功能旧版 AppCoins SDK新版 Aptoide SDK
Billing Client 类AppcoinsBillingClientAptoideBillingClient
查询商品querySkuDetailsAsyncqueryProductDetailsAsync
购买流程参数使用 SKU 的 BillingFlowParams使用 ProductDetails 的 BillingFlowParams
计费操作结果作为 ResponseCode 的 Int 值使用包含 BillingResponseCode 和 Debug Message 的 BillingResult
消耗consumeAsync(token)consumeAsync(ConsumeParams)

常见问题

在哪里可以找到完整的 Aptoide Billing SDK 集成文档?

关于新版 Aptoide Billing SDK 集成的完整文档可在此处找到。其中包含了完整且成功集成我们计费系统所需的最重要步骤。


在哪里可以找到旧版 AppCoins Billing SDK 集成文档?

关于旧版 Aptoide Billing SDK 集成的文档可在此处找到。