在 Android 上实现 Google Play 订阅支付是一项系统工程。2026 年的支付架构已全面转向"订阅 2.0",即 一个订阅 ID 下包含多个基础方案(Base Plans) 的模式
一、Google Play Console 后台配置
创建订阅产品
-
登录Google Play Console。
-
进入 借助Play变现**> 商品 > 订阅**

3.创建订阅 :设置一个 Product ID(如 pro_membership)。
4.添加基础方案 (Base Plan):
定义计费周期(月、年)。
关键点:设置价格后,务必点击"激活基础方案"。
向后兼容性:在基础方案设置中,勾选"向后兼容",这样旧版 SDK 也能识别。

二、关联 Google Cloud 服务账号 (API 接入)
- 在Google Cloud 控制台创建项目并启用 Google Play Android Developer API。

2.创建服务账号 (Service Account),操作->管理密钥->添加键->键类型Json->创建 ,下载 JSON 密钥文件。

3.创建项目并启用api

4.回到Google Play Console 控制台,点击用户和权限->点击邀请新用户->邮箱填上面Google Cloud创建的邮箱->账号权限要给"查看财务数据"和"管理订单和订阅"权限

三、环境配置与测试准备
1. 许可测试设置 (License Testing)
在 Play Console 的"全局设置"中找到 许可测试,添加你的测试 Gmail 账号。这样你测试时可以使用"测试卡片",不会产生真实扣费。


- 测试版本发布
-
必须发布 :你必须上传一个包含 Billing 权限的 AAB 包到 内部测试轨道 (Internal Testing)。
-
签名一致:本地调试运行的 App 包名和签名必须与测试轨道上的包完全一致。
- 手机必须安装Play store
打开play store-> 点击头像 -> 设置 ->关于->快速点击play store 版本号进入开发者模式->常规->账号和设备偏好设置->国家地区和个人资料选择非中国区
四、代码实现 (使用原生 Billing Library)
目前主流版本为 Google Play Billing Library 8.0+。
1.添加依赖
在build.gradle中添加
Kotlin
dependencies {
def billing_version = "8.3.0"
implementation "com.android.billingclient:billing:$billing_version"
}
- 初始化BillingClient
Kotlin
val billingClient = BillingClient.newBuilder(context)
.setListener { billingResult, purchases ->
// 支付结果回调
}
.enablePendingPurchases()
.build()
billingClient.startConnection(object : BillingClientStateListener {
override fun onBillingSetupFinished(billingResult: BillingResult) {
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
// 连接成功,可以查询商品
}
}
override fun onBillingServiceDisconnected() {
// 尝试重连
}
})
- 查询订阅详情 (Query Product Details)
注意:订阅必须指定 ProductType.SUBS
Kotlin
val productList = listOf(
QueryProductDetailsParams.Product.newBuilder()
.setProductId("your_subscription_id")
.setProductType(BillingClient.ProductType.SUBS)
.build()
)
val params = QueryProductDetailsParams.newBuilder().setProductList(productList).build()
billingClient.queryProductDetailsAsync(params) { billingResult, productDetailsList ->
val responseCode = billingResult.responseCode
val debugMessage = billingResult.debugMessage
when (responseCode) {
BillingClient.BillingResponseCode.OK -> {
val list = result.productDetailsList
if (list.isEmpty()) {
LogUtils.e(
TAG,
"Query OK but list is EMPTY. Check if 'gallery_star' is ACTIVE and has an ACTIVE Base Plan."
)
} else {
mProductDetails = list[0]
_productDetailsList.value = list
LogUtils.d(TAG, "Successfully queried ${list.size} products. ID: ${mProductDetails?.productId}")
}
}
BillingClient.BillingResponseCode.DEVELOPER_ERROR -> {
// Code 12 核心报错
}
else -> {
LogUtils.e(TAG, "Query failed with code $responseCode: $debugMessage")
}
}
- 发起购买流程
Kotlin
val productDetails = productDetailsList[0]
val offerToken = productDetails.subscriptionOfferDetails?.get(0)?.offerToken ?: ""
val productDetailsParamsList = listOf(
BillingFlowParams.ProductDetailsParams.newBuilder()
.setProductDetails(productDetails)
.setOfferToken(offerToken)
.build()
)
val billingFlowParams = BillingFlowParams.newBuilder()
.setProductDetailsParamsList(productDetailsParamsList)
.build()
billingClient.launchBillingFlow(activity, billingFlowParams)

五、常见错误排查
| 错误码 | 含义 | 解决方案 |
|---|---|---|
| Code 3 (BILLING_UNAVAILABLE) | 支付不可用 | 检查是否登录了 Google 账号;梯子是否全局开启;内测邀请是否已点击"接受"。 |
| Code 12 (INTERNAL_ERROR) | 内部错误 | 通常是 Google Play 商店缓存问题。清理商店数据、重启手机、更换纯净 IP 节点。 |
| Code 4 (ITEM_UNAVAILABLE) | 商品未找到 | 检查 Product ID 拼写;确保基础方案已"激活"且勾选了"向后兼容"。 |
注意:
-
网络环境测试时,请确保你的加速器是全局模式,且节点地区与你的测试账号注册地一致。
-
play store地区一定不能是中国区