更新记录

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:未测试 ×

原生插件通用使用流程:

  1. 购买插件,选择该插件绑定的项目。
  2. 在HBuilderX里找到项目,在manifest的app原生插件配置中勾选模块,如需要填写参数则参考插件作者的文档添加。
  3. 根据插件作者的提供的文档开发代码,在代码中引用插件,调用插件功能。
  4. 打包自定义基座,选择插件,得到自定义基座,然后运行时选择自定义基座,进行log输出测试。
  5. 开发完毕后正式云打包

付费原生插件目前不支持离线打包。
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 发送到业务服务端验证。
  • 服务端验单并完成发货后,再由业务代码调用 doConsumedoAcknowledgePurchase
  • 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 可能包含多个基础方案和优惠。实际项目应根据 basePlanIdofferIdofferTags 选择目标 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 可选传入 accountIdprofileId

GooglePayV5.doPay(
  {
    productId: product.productId,
    productType: "inapp",
    accountId: "your_obfuscated_account_id",
    profileId: "your_obfuscated_profile_id"
  },
  handlePurchaseResult
);

doPayAll 保留用于兼容旧代码,参数和行为与 doPay 相同。

accountIdprofileId 均为可选参数;传 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. 消费一次性商品

仅用于可重复购买的消耗型一次性商品。调用前应确保:

  1. purchaseState === 1
  2. 业务服务端已完成验单。
  3. 权益已经成功发放。
GooglePayV5.doConsume(
  {
    purchaseToken: purchase.purchaseToken
  },
  (result) => {
    if (result.code === 200) {
      console.log("商品消费成功");
    } else {
      console.log(
        "商品消费失败",
        result.billingResponseCode,
        result.debugMessage
      );
    }
  }
);

消费成功后,该一次性商品可以再次购买。

8. 确认非消耗品或订阅

用于非消耗型一次性商品和订阅。originalsignature 来自 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 官方页面为准。

官方文档

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件支付功能使用Google SDK,参考其官方网站 https://policies.google.com/privacy

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率: