更新记录
1.0.0(2026-08-19)
- 首次发布,支持 uni-app Vue 3 与 uni-app x Android 项目。
- 支持商品查询、购买、订单恢复、订单确认和商品消耗。
- 基于 Google Play Billing Library 9.1.0,要求 Android 6.0+、HBuilderX 5.24+。
平台兼容性
uni-app(5.24)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| × | √ | × | × | √ | × | √ | × | × |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × | - | × | × |
uni-app x(5.24)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| × | × | √ | × | × | × |
Google Play 应用内购
基于 Google Play Billing Library 9.1.0 的 Android 应用内购与订阅 UTS 插件,支持 uni-app Vue 3 和 uni-app x。
- 插件版本:1.0.0
- Android 最低版本:Android 6.0(API 23)
- HBuilderX 兼容基线:5.24 及以上版本
本插件封装的是 Google Play Billing,不是 Google Pay Wallet,不适用于线下 支付、银行卡或 NFC 支付。
支持范围
| 项目 | 支持情况 |
|---|---|
| uni-app Vue 3 App Android | 支持 |
| uni-app x App Android | 支持 |
| uni-app Vue 2 / nvue | 不支持 |
| iOS / HarmonyOS | 不支持,调用时返回 9011002 |
| Web / 小程序 / 快应用 | 不支持 |
使用前准备
在测试真实购买前,需要先完成 Google Play Console 配置:
- 在 Google Play Console 创建应用,应用包名必须与 Android 项目的包名一致。
- 创建并启用应用内商品或订阅,记录商品 ID。
- 上传使用正式签名的 APK 或 AAB 到内部测试或封闭测试轨道。
- 将测试 Google 账号加入许可测试人员,并在手机 Google Play 中登录同一账号。
- 通过 Google Play 测试链接安装应用,再进行购买测试。
侧载安装的调试包可以验证 BillingClient 创建、连接和查询接口,但通常不能完成 真实购买。商品查询为空时,应优先检查商品状态、测试账号、包名、签名和安装来源。
官方测试说明: https://developer.android.com/google/play/billing/test
安装与运行
- 从 DCloud 插件市场将
hans-google-pay导入项目。 - Android 调试时生成并使用包含本插件的自定义基座。标准基座不包含 Google Play Billing 原生依赖。
- 正式发布时重新云打包 APK 或 AAB,确保本插件被编译进安装包。
插件会自动合并 com.android.vending.BILLING 权限,不需要向用户申请运行时
权限。
导入与类型
uni-app x 页面建议使用 lang="uts",并从插件根目录同时导入 API 与公开类型:
import {
newBuilder,
startConnection,
endConnection,
isReady,
queryProductDetailsAsync,
launchBillingFlow,
queryPurchasesAsync,
acknowledgePurchase,
consumeAsync,
BillingJsonOptions,
BillingNewBuilderOptions,
BillingStartConnectionOptions,
} from '@/uni_modules/hans-google-pay'
不要直接导入 utssdk/interface.uts。标准 uni-app Vue 3 页面使用 JavaScript 时,
只导入所需 API,不需要导入上述类型。
回调约定
所有 API 都接收一个 options 对象:
| 字段 | 类型 | 说明 |
|---|---|---|
paramsJson |
string |
JSON 字符串;无参数时传 '{}'。 |
success |
function |
调用成功,参数为 JSON 字符串。 |
fail |
function |
调用失败,参数为 JSON 字符串。 |
complete |
function |
可选;成功或失败后都会调用。 |
建议在回调中先解析 JSON:
success: (resJson: string): void => {
const result = JSON.parse<UTSJSONObject>(resJson)
console.log(result)
}
newBuilder 额外支持 purchasesUpdated 和 userChoiceBilling;
startConnection 额外支持 disconnected。
推荐调用顺序
newBuilder:创建 BillingClient 并注册购买结果回调。startConnection:连接 Google Play 服务。queryProductDetailsAsync:查询并缓存商品详情。launchBillingFlow:使用已查询的商品拉起购买界面。- 在
purchasesUpdated中处理订单状态和purchaseToken。 - 非消耗型商品和订阅调用
acknowledgePurchase;消耗型商品调用consumeAsync。 - 启动应用或恢复会话时调用
queryPurchasesAsync核对有效订单。 - 页面或业务生命周期结束时调用
endConnection。
必须先查询商品详情,再对同一 productId 调用 launchBillingFlow。插件会在
当前 BillingClient 生命周期内缓存查询结果。
创建和连接 BillingClient
const builderOptions: BillingNewBuilderOptions = {
paramsJson: JSON.stringify({
enablePendingPurchases: true,
pendingPurchases: {
oneTimeProducts: true,
prepaidPlans: false,
},
enableAutoServiceReconnection: true,
}),
purchasesUpdated: (eventJson: string): void => {
const event = JSON.parse<UTSJSONObject>(eventJson)
console.log('购买结果', event)
},
success: (_resJson: string): void => {
const connectionOptions: BillingStartConnectionOptions = {
paramsJson: '{}',
disconnected: (_eventJson: string): void => {
console.warn('Google Play Billing 服务已断开')
},
success: (resJson: string): void => {
console.log('连接成功', JSON.parse<UTSJSONObject>(resJson))
},
fail: (errJson: string): void => {
console.error('连接失败', JSON.parse<UTSJSONObject>(errJson))
},
}
startConnection(connectionOptions)
},
fail: (errJson: string): void => {
console.error('创建失败', JSON.parse<UTSJSONObject>(errJson))
},
}
newBuilder(builderOptions)
newBuilder.paramsJson 支持:
| 字段 | 说明 |
|---|---|
enablePendingPurchases |
是否启用待处理订单,默认 true。 |
pendingPurchases.oneTimeProducts |
是否支持一次性商品待处理订单,默认 true。 |
pendingPurchases.prepaidPlans |
是否支持预付费订阅待处理订单,默认 false。 |
enableAutoServiceReconnection |
是否自动重连,建议设为 true。 |
enableAlternativeBillingOnly |
仅在账号和地区符合 Google Play 替代计费政策时启用。 |
enableBillingProgram |
是否启用 Billing Program。 |
billingProgram |
Billing Program 原始整数值。 |
enableUserChoiceBilling |
仅在符合用户选择计费政策时启用。 |
查询商品
一次性商品使用 inapp,订阅使用 subs:
const queryOptions: BillingJsonOptions = {
paramsJson: JSON.stringify({
productType: 'inapp',
productIds: [ 'coin_pack_100' ],
}),
success: (resJson: string): void => {
console.log('商品详情', JSON.parse<UTSJSONObject>(resJson))
},
fail: (errJson: string): void => {
console.error(JSON.parse<UTSJSONObject>(errJson))
},
}
queryProductDetailsAsync(queryOptions)
订阅购买需要从 subscriptionOfferDetails 中选择对应的 offerToken。一次性
商品的新优惠模型也可能返回 offerToken,应使用商品查询结果中的实际值。
拉起购买
一次性商品:
const purchaseOptions: BillingJsonOptions = {
paramsJson: JSON.stringify({
productId: 'coin_pack_100',
obfuscatedAccountId: 'hash-of-your-user-id',
}),
success: (resJson: string): void => {
console.log('购买界面已拉起', JSON.parse<UTSJSONObject>(resJson))
},
fail: (errJson: string): void => {
console.error('无法拉起购买界面', JSON.parse<UTSJSONObject>(errJson))
},
}
launchBillingFlow(purchaseOptions)
订阅:
const subscriptionOptions: BillingJsonOptions = {
paramsJson: JSON.stringify({
productId: 'premium_monthly',
offerToken: 'offer-token-from-product-details',
}),
success: (resJson: string): void => {
console.log(JSON.parse<UTSJSONObject>(resJson))
},
fail: (errJson: string): void => {
console.error(JSON.parse<UTSJSONObject>(errJson))
},
}
launchBillingFlow(subscriptionOptions)
launchBillingFlow.success 只表示购买界面成功拉起。最终购买结果由
newBuilder.purchasesUpdated 返回。同一时间只能存在一个购买流程。
恢复、确认和消耗订单
查询当前有效订单:
const restoreOptions: BillingJsonOptions = {
paramsJson: JSON.stringify({
productType: 'inapp',
includeSuspendedSubscriptions: false,
}),
success: (resJson: string): void => {
console.log('有效订单', JSON.parse<UTSJSONObject>(resJson))
},
fail: (errJson: string): void => {
console.error(JSON.parse<UTSJSONObject>(errJson))
},
}
queryPurchasesAsync(restoreOptions)
确认非消耗型商品或订阅:
const acknowledgeOptions: BillingJsonOptions = {
paramsJson: JSON.stringify({
purchaseToken: 'purchase-token-from-purchasesUpdated',
}),
success: (resJson: string): void => {
console.log('订单已确认', JSON.parse<UTSJSONObject>(resJson))
},
fail: (errJson: string): void => {
console.error(JSON.parse<UTSJSONObject>(errJson))
},
}
acknowledgePurchase(acknowledgeOptions)
消耗可重复购买的商品:
const consumeOptions: BillingJsonOptions = {
paramsJson: JSON.stringify({
purchaseToken: 'purchase-token-from-purchasesUpdated',
}),
success: (resJson: string): void => {
console.log('商品已消耗', JSON.parse<UTSJSONObject>(resJson))
},
fail: (errJson: string): void => {
console.error(JSON.parse<UTSJSONObject>(errJson))
},
}
consumeAsync(consumeOptions)
API 参数速查
| API | paramsJson 字段 |
|---|---|
newBuilder |
见“创建和连接 BillingClient”。 |
startConnection |
{}。 |
endConnection |
{}。结束连接并清空商品缓存。 |
isReady |
{}。返回 ready。 |
getConnectionState |
{}。返回 BillingClient 原始连接状态值。 |
isFeatureSupported |
feature:能力名称或 Billing Library 原始值。 |
queryProductDetailsAsync |
productType、productIds。 |
queryPurchasesAsync |
productType,可选 includeSuspendedSubscriptions。 |
launchBillingFlow |
必填 productId;可选 offerToken、obfuscatedAccountId、obfuscatedProfileId、isOfferPersonalized、replacementParams、subscriptionUpdateParams。 |
acknowledgePurchase |
purchaseToken。 |
consumeAsync |
purchaseToken。 |
getBillingConfigAsync |
{}。返回 Google Play 国家或地区代码。 |
showInAppMessages |
可选 categories 整数数组;不传时显示所有支持的类别。 |
launchExternalLink |
按政策场景传 billingProgram、launchMode、linkType、linkUri。 |
isAlternativeBillingOnlyAvailableAsync |
{}。 |
showAlternativeBillingOnlyInformationDialog |
{}。 |
createAlternativeBillingOnlyReportingDetailsAsync |
{}。 |
isBillingProgramAvailableAsync |
必填 billingProgram 整数值。 |
createBillingProgramReportingDetailsAsync |
必填 billingProgram 整数值。 |
replacementParams 支持 oldProductId、replacementMode;
subscriptionUpdateParams 支持 oldPurchaseToken、
originalExternalTransactionId。
替代计费、外部链接、用户选择计费和 Billing Program API 受 Google Play 账号、地区与政策限制。不要仅因为 SDK 接口可用就直接在生产环境启用。
返回结果
billingResult 通常包含:
| 字段 | 说明 |
|---|---|
responseCode |
Google Play Billing 响应码;0 表示 OK。 |
debugMessage |
Google Play 返回的调试信息。 |
onPurchasesUpdatedSubResponseCode |
购买失败的细分原因。 |
商品详情常用字段:
productId、productType、title、name、description。oneTimePurchaseOfferDetails、oneTimePurchaseOfferDetailsList。subscriptionOfferDetails,其中包含basePlanId、offerId、offerToken和pricingPhases。
购买记录常用字段:
purchaseToken、products、purchaseState、purchaseTime、quantity。isAcknowledged、isAutoRenewing、isSuspended、orderId。originalJson和signature仅用于校验,不应直接作为客户端授予权益的依据。
插件错误码
| 错误码 | 说明 |
|---|---|
9011001 |
paramsJson 格式错误或缺少必要参数。 |
9011002 |
当前平台不支持。 |
9011003 |
BillingClient 尚未创建、未连接或未查询到商品详情。 |
9011004 |
当前 Android Activity 不可用。 |
9011005 |
已有购买流程正在进行。 |
9011006 |
当前能力尚未实现。 |
9011099 |
原生层内部错误。 |
插件错误通过 errCode 和 errMsg 返回;Google Play 服务错误通过
billingResult.responseCode 和 debugMessage 返回,两者需要分别处理。
生产环境注意事项
- 不要信任客户端自行上报的购买成功结果。将
purchaseToken发送到业务服务端, 使用 Google Play Developer API 验证订单后再授予权益。 - 只有订单处于已购买状态时才授予权益;待处理订单完成前不要发货。
- 非消耗型商品和订阅需要确认,消耗型商品需要消耗。Google Play 要求在规定 时间内完成处理,否则订单可能被退款。
obfuscatedAccountId和obfuscatedProfileId应使用不可逆、稳定且不包含明文 个人信息的业务标识。- 应同时处理
purchasesUpdated和queryPurchasesAsync,避免应用重启、断网或 回调丢失导致漏单。
Google Play 官方安全建议: https://developer.android.com/google/play/billing/security
Google Play 购买生命周期: https://developer.android.com/google/play/billing/lifecycle/one-time
常见问题
商品查询成功但列表为空
检查商品是否已启用、productType 是否正确、测试账号是否已加入、包名和签名
是否与 Play Console 一致,以及应用是否通过测试轨道安装。未取得的商品会出现在
unfetchedProducts 中。
startConnection 返回非 0
检查手机是否安装并登录 Google Play、当前地区和账号是否支持 Billing,以及网络
是否能访问 Google Play 服务。具体原因以 debugMessage 为准。
标准基座中调用失败
标准基座不包含本插件的 Maven 依赖。请重新生成包含本插件的 Android 自定义基座, 并确认运行时选择了该基座。
页面提示 BillingClient 未就绪
先调用 newBuilder,再等待 startConnection.success,之后才能查询商品、恢复
订单或拉起购买。

收藏人数:
购买源码授权版(
试用
使用 HBuilderX 导入示例项目
赞赏(0)
下载 387
赞赏 0
下载 12518030
赞赏 1943
赞赏
京公网安备:11010802035340号