更新记录
2.0.0(2026-08-05)
新增适配Billing 9.1.0
1.3.0(2025-10-23)
谷歌支付SDK更新 sdk版本:8.0.0
1.2.0(2025-04-12)
1、使用新版本谷歌结算库:7.1.1 2、新增支持更新订阅方法 3、新增显示应用内消息方法
查看更多平台兼容性
| Android | Android CPU类型 | iOS |
|---|---|---|
| 适用版本区间:6.0 - 16.0 | armeabi-v7a:未测试,arm64-v8a:未测试,x86:未测试 | × |
原生插件通用使用流程:
- 购买插件,选择该插件绑定的项目。
- 在HBuilderX里找到项目,在manifest的app原生插件配置中勾选模块,如需要填写参数则参考插件作者的文档添加。
- 根据插件作者的提供的文档开发代码,在代码中引用插件,调用插件功能。
- 打包自定义基座,选择插件,得到自定义基座,然后运行时选择自定义基座,进行log输出测试。
- 开发完毕后正式云打包
付费原生插件目前不支持离线打包。
Android 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/android
iOS 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/ios
注意事项:使用HBuilderX2.7.14以下版本,如果同一插件且同一appid下购买并绑定了多个包名,提交云打包界面提示包名绑定不一致时,需要在HBuilderX项目中manifest.json->“App原生插件配置”->”云端插件“列表中删除该插件重新选择
Google Play Billing 9.1.0 支付内购与订阅插件
本插件是Android 谷歌支付原生插件,用于对接 Google Play Billing 9.1.0,支持一次性商品、订阅、订阅替换、消费、确认购买、恢复购买和应用内消息。
仅支持 Android 版 uni-app,不支持 uni-app x。
uni-app x/UTS 版本请使用:Google Play Billing UTS 插件
插件市场 ID 和模块名中的 V5 是历史兼容名称,不代表当前 Billing SDK 版本。当前实际依赖固定为:
com.android.billingclient:billing:9.1.0
环境要求
- Android 6.0 / API 23 及以上。
- 建议使用最新版 HBuilderX;至少使用支持
compileSdk 35的 HBuilderX 4.44 或更高版本。 - 应用必须已在 Google Play Console 中创建,并配置正确的 applicationId、签名、测试轨道、商品和许可测试账号。
- 原生插件修改后需要重新云打包或重新制作自定义基座,普通热更新不会替换原生 AAR。
重要职责说明
本插件只负责调用 Google Play Billing SDK,并把 Google 返回的购买信息交给 uni-app。
- 插件不负责服务端验单、发货、权益管理、补单或订单持久化。
code === 200只表示对应 SDK 调用成功或购买回调正常返回,不代表服务端已经验证交易。purchaseState === 1后,应先把purchaseToken发送到业务服务端验证。- 服务端验单并完成发货后,再由业务代码调用
doConsume或doAcknowledgePurchase。 purchaseState === 2表示交易处于 PENDING 状态,不得发货;后续可通过doQueryPurchases查询状态。
推荐流程:
doInit
→ doQuerySku
→ doPay / doPayAll / doUpdateSubs
→ 获取 Purchase 和 purchaseToken
→ 业务服务端验单与发货
→ doConsume / doAcknowledgePurchase
引用插件
const GooglePayV5 = uni.requireNativePlugin("GT-GooglePay-V5__PayModule");
公共回调字段
不同方法返回的数据略有区别,公共字段如下:
| 字段 | 说明 |
|---|---|
code |
插件状态码 |
data |
方法业务结果或说明 |
errorCode |
兼容保留的 Google Billing 响应码,部分本地参数错误可能没有 |
billingResponseCode |
Google Billing 主响应码 |
subResponseCode |
Billing 9.1 购买更新子响应码 |
onPurchasesUpdatedSubResponseCode |
subResponseCode 的完整字段名 |
debugMessage |
Google SDK 调试信息,不要依赖该文本做业务判断 |
插件状态码:
| code | 说明 |
|---|---|
200 |
SDK 操作成功或购买回调正常返回 |
400 |
一般失败 |
401 |
参数为空或参数不合法 |
402 |
商品查询成功,但没有返回可购买商品 |
403 |
未在插件缓存中找到指定商品,需要先执行 doQuerySku |
所有公开方法都是一次性回调。PENDING 交易状态改变后,应主动调用 doQueryPurchases,不要等待原支付回调再次触发。
1. 初始化
GooglePayV5.doInit(
{
// 默认 true。Billing 服务断开后由 SDK 自动重连。
enableAutoServiceReconnection: true,
// 以下能力受 Google Play 地区、账号资格及政策限制。
// 未加入对应计划时请保持 false。
enableExternalOffer: false,
enableAlternativeBillingOnly: false,
enableUserChoiceBilling: false
},
(result) => {
if (result.code === 200) {
console.log("Billing 初始化成功");
} else {
console.log(
"Billing 初始化失败",
result.billingResponseCode,
result.debugMessage
);
}
}
);
查询连接状态:
GooglePayV5.getConnectionState((result) => {
console.log("BillingClient ready:", result.ready);
});
2. 查询商品
支付前必须先调用 doQuerySku。查询结果会暂存在插件内存中,建议查询成功后尽快发起支付;应用长时间运行后应重新查询。
GooglePayV5.doQuerySku(
{
inapp: ["your_inapp_product_id"],
// subs: ["your_subscription_product_id"] // 与 inapp 二选一
},
(result) => {
if (result.code === 200) {
const productList = result.list || [];
console.log("查询到商品数量:", productList.length);
} else {
console.log(
"商品查询失败:",
result.billingResponseCode,
result.debugMessage,
result.unfetchedProductList
);
}
}
);
返回值:
list:成功获取的ProductDetails。unfetchedProductList:未获取到的商品及失败原因。
订阅商品的 subscriptionOfferDetails 可能包含多个基础方案和优惠。实际项目应根据 basePlanId、offerId 或 offerTags 选择目标 offer,不要默认第一个一定符合业务要求。
测试时可使用:
function getFirstOfferToken(productDetails) {
const offerList = productDetails?.subscriptionOfferDetails || [];
return offerList.length > 0 ? offerList[0].offerToken : "";
}
3. 发起购买
一次性商品:
GooglePayV5.doPay(
{
productId: inappProduct.productId,
productType: "inapp"
},
handlePurchaseResult
);
订阅商品必须传有效 offerToken:
const offerToken = getFirstOfferToken(subscriptionProduct);
GooglePayV5.doPay(
{
productId: subscriptionProduct.productId,
productType: "subs",
offerToken
},
handlePurchaseResult
);
购买结果处理示例:
function handlePurchaseResult(result) {
if (result.code !== 200) {
console.log(
"购买未完成:",
result.billingResponseCode,
result.subResponseCode,
result.debugMessage
);
return;
}
const purchase = Array.isArray(result.data) ? result.data[0] : null;
if (!purchase) {
return;
}
if (purchase.purchaseState === 1) {
// PURCHASED:
// 把 purchase.purchaseToken 发送到业务服务端验单。
// 服务端验单和发货成功后,再调用消费或确认购买方法。
} else if (purchase.purchaseState === 2) {
// PENDING:不能发货,后续调用 doQueryPurchases 查询。
}
}
4. 携带混淆账号标识购买
doPay 可选传入 accountId 和 profileId:
GooglePayV5.doPay(
{
productId: product.productId,
productType: "inapp",
accountId: "your_obfuscated_account_id",
profileId: "your_obfuscated_profile_id"
},
handlePurchaseResult
);
doPayAll 保留用于兼容旧代码,参数和行为与 doPay 相同。
accountId 和 profileId 均为可选参数;传 profileId 时应同时传 accountId。标识长度不能超过 64 个字符。
5. 更新订阅
先通过 doQueryPurchases("subs") 获取旧订阅 Purchase,再通过 doQuerySku 获取新订阅 ProductDetails。
const oldPurchase = ownedSubscription;
const newProduct = newSubscriptionProduct;
const offerToken = getFirstOfferToken(newProduct);
GooglePayV5.doUpdateSubs(
{
productId: newProduct.productId,
offerToken,
oldPurchaseToken: oldPurchase.purchaseToken,
// Billing 9 推荐传旧订阅商品 ID。
oldProductId: oldPurchase.products?.[0],
// 示例使用 WITH_TIME_PRORATION。
// 实际项目必须根据升级、降级和计费策略选择。
replacementMode: 1
},
handlePurchaseResult
);
可用的 replacementMode:
| 值 | 模式 |
|---|---|
1 |
WITH_TIME_PRORATION |
2 |
CHARGE_PRORATED_PRICE |
3 |
WITHOUT_PRORATION |
5 |
CHARGE_FULL_PRICE |
6 |
DEFERRED |
replacementMode不要传 0,它表示 UNKNOWN_REPLACEMENT_MODE。不同模式受到 Google Play 订阅替换规则限制,请根据实际业务选择。
订阅替换成功后同样需要服务端验单,并按业务流程确认新购买。
6. 查询当前拥有的购买
查询未消费的一次性商品:
GooglePayV5.doQueryPurchases("inapp", (result) => {
if (result.code === 200) {
const purchaseList = result.purchasesList || [];
}
});
查询当前拥有的订阅:
GooglePayV5.doQueryPurchases("subs", (result) => {
if (result.code === 200) {
const subscriptionList = result.purchasesList || [];
}
});
该方法不是服务端验单接口。一次性商品确认后仍可能保持“已拥有”状态,只有消费后才会允许再次购买。
7. 消费一次性商品
仅用于可重复购买的消耗型一次性商品。调用前应确保:
purchaseState === 1。- 业务服务端已完成验单。
- 权益已经成功发放。
GooglePayV5.doConsume(
{
purchaseToken: purchase.purchaseToken
},
(result) => {
if (result.code === 200) {
console.log("商品消费成功");
} else {
console.log(
"商品消费失败",
result.billingResponseCode,
result.debugMessage
);
}
}
);
消费成功后,该一次性商品可以再次购买。
8. 确认非消耗品或订阅
用于非消耗型一次性商品和订阅。original 与 signature 来自 Purchase 返回结果。
GooglePayV5.doAcknowledgePurchase(
{
original: purchase.original || purchase.originalJson,
signature: purchase.signature
},
(result) => {
if (result.code === 200) {
console.log(
result.alreadyAcknowledged
? "该购买此前已经确认"
: "确认购买成功"
);
} else {
console.log(
"确认购买失败",
result.billingResponseCode,
result.debugMessage
);
}
}
);
重复确认会按幂等成功返回,并包含 alreadyAcknowledged: true。
9. 显示 Google Play 应用内消息
GooglePayV5.doShowInAppMessages(
{
inAppMessageCategoryId: 2
},
(result) => {
if (result.code === 200) {
console.log("应用内消息响应码:", result.data?.responseCode);
}
}
);
具体响应含义以 Google Play Billing 应用内消息文档为准。
常见问题
商品查询返回 402
检查以下内容:
- 商品 ID 和商品类型是否正确。
- 商品是否已在 Google Play Console 中启用。
- 当前安装包的 applicationId、签名和 Play Console 配置是否一致。
- 测试账号是否加入许可测试。
- 应用是否已发布到内部测试、封闭测试或其他有效测试轨道。
- 查看
unfetchedProductList返回的具体原因。
支付返回 403
表示插件内存中没有对应 ProductDetails。请重新调用 doQuerySku,成功后再发起支付。
返回 USER_CANCELED
用户主动取消支付属于正常结果,应根据 billingResponseCode 处理,不要当作应用异常。
PENDING 交易没有再次回调
插件支付回调为一次性回调。PENDING 状态变化后,通过 doQueryPurchases 主动恢复交易。
Google Play Billing 版本政策
Google Play Billing Library 当前支持时间表:
| Billing 版本 | 新应用和更新截止日期 | 延期截止日期 |
|---|---|---|
| 7 | 2026-08-31 | 2026-11-01 |
| 8 | 2027-08-31 | 2027-11-01 |
| 9 | 2028-08-31 | 2028-11-01 |
本插件当前使用 Billing 9.1.0。版本政策可能继续调整,请以上线时 Google 官方页面为准。

收藏人数:
购买(
试用
使用 HBuilderX 导入示例项目
赞赏(0)
下载 826
赞赏 0
下载 13446
赞赏 1
赞赏
京公网安备:11010802035340号