PAYATHON 2026

如何确认正在使用 Google Play in-app billing version 3?

技术老齐

结论

Google Play Console 中出现 managed、unmanaged 和 subscription,并不能说明应用使用的是 In-app Billing v2 还是 v3。控制台需要兼容采用不同计费版本的应用,所以旧的 unmanaged 类型可能仍会显示。

判断版本要看应用调用计费服务时传入的 apiVersion。如果调用 isBillingSupported()、getBuyIntent()、getPurchases() 和 consumePurchase() 时,第一个参数传入的是 3,且 Google Play 返回成功,应用使用的就是 In-app Billing API v3。

如何确认

先检查应用绑定的服务是否为 v3 使用的 IInAppBillingService:

Intent serviceIntent = new Intent(
        "com.android.vending.billing.InAppBillingService.BIND"
);
serviceIntent.setPackage("com.android.vending");

bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE);

连接成功后,检查 API v3 是否受支持:

private static final int BILLING_API_VERSION = 3;
private static final String ITEM_TYPE_INAPP = "inapp";
private static final String ITEM_TYPE_SUBS = "subs";

int response = billingService.isBillingSupported(
        BILLING_API_VERSION,
        getPackageName(),
        ITEM_TYPE_INAPP
);

if (response == 0) {
    // RESULT_OK:当前设备上的 Google Play 支持 v3 一次性商品
} else {
    // v3 不可用,记录并处理具体响应码
}

订阅需要另外检查:

int response = billingService.isBillingSupported(
        3,
        getPackageName(),
        "subs"
);

response == 0 表示该商品类型支持请求的 API 版本。服务绑定成功本身不能证明 v3 可用。

接下来检查所有实际的计费调用,确认第一个参数始终为 3:

Bundle buyIntentBundle = billingService.getBuyIntent(
        3,
        getPackageName(),
        sku,
        "inapp",
        developerPayload
);

如果部分调用仍传入 2,这些调用使用的仍是 v2。计费版本并不是在 Console 中为整个应用统一切换的。

验证消耗后能否再次购买

对于可以重复购买的商品,需要在 Google Play Console 中将其定义为 managed。购买成功并验证结果后,从订单中取得 purchaseToken,再调用 v3 的 consumePurchase():

int response = billingService.consumePurchase(
        3,
        getPackageName(),
        purchaseToken
);

if (response == 0) {
    // 消耗成功,商品可以再次购买
}

可以按以下流程测试:

  1. 用户购买一个 managed 商品。
  2. 应用验证购买数据和签名。
  3. 应用向用户发放商品。
  4. 使用这笔购买的 purchaseToken 调用 consumePurchase(3, ...)。
  5. 收到成功响应后,再次查询购买记录。
  6. 使用测试账号重新购买同一个 SKU。

如果消耗成功后还能再次购买同一 SKU,就说明 v3 的消费模型已经正常工作。如果没有执行消费,managed 商品仍会被视为已拥有,再次购买通常会返回 ITEM_ALREADY_OWNED。

Console 中的 unmanaged 为什么仍然存在

商品类型是后台的商品配置,API 版本则是应用与 Google Play Billing Service 之间的调用协议,两者不是同一个概念。

控制台显示 unmanaged,通常只是为了兼容旧应用或旧商品,不代表当前 APK 使用了 v2。使用 v3 时不需要选择 unmanaged。一次性消耗品和永久解锁商品都可以设为 managed,两者的区别在于应用是否消费这笔购买。

  • 金币、道具、次数包:购买后调用 consumePurchase()。
  • 去广告、永久功能解锁:保留已购买状态,不要消费。
  • 周期性服务:使用 subscription。

注意事项

不要只根据购买页面能否打开来判断版本,因为不同版本的购买界面对用户来说可能几乎一样。还需要确认:

  • 使用的是 IInAppBillingService v3 接口。
  • 所有计费调用的 apiVersion 都是 3。
  • isBillingSupported(3, packageName, type) 返回成功。
  • 消耗操作调用的是 consumePurchase(3, packageName, purchaseToken)。
  • 使用许可测试账号完成购买、消费、再次购买的完整测试。

不要在发放商品前直接消费购买。生产环境中,应先验证购买签名或通过可信服务器确认订单,然后发放商品并执行消费,否则可能造成商品未发放、重复发放或接受伪造购买等问题。

本文讨论的是历史上的 In-app Billing API v3,该接口目前已经过时。新项目或正在更新且仍需上架的应用,应改用 Google Play 当前支持的 Google Play Billing Library,并按照现行版本要求处理购买确认和消费。

备注:内容仅供参考。