更新记录
1.0.3(2023-12-06)
- 支持showInAppMessages
1.0.2(2023-11-08)
- 添加isFeatureSupported接口
- 修复sdk内部异常导致没有回调
1.0.1(2023-08-21)
- 兼容Android 14
- 支持用户升级、降级或更改订阅
平台兼容性
Android | Android CPU类型 | iOS |
---|---|---|
适用版本区间:5.0 - 14.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原生插件配置”->”云端插件“列表中删除该插件重新选择
说明
此插件提供 android google v5/v6 支付功能
使用前提
-
支付接入流程请参考
-
支付前请确保配置好您的商品,官方文档
-
支付流程参考 官方文档
-
交易归因参考 官方文档
-
服务器后端集成简介 官方文档
-
实时开发者通知:订阅用户注意 官方文档
-
账号保留功能:订阅用户注意 官方文档
-
允许用户升级、降级或更改订阅 官方文档
注意
切记不要用国内 google 账号,国内账号已经不能支付
试用说明
试用打包aab,需要在项目根目录创建文件 AndroidManifest.xml,内容如下
(不需要导入插件,如果导入插件必须删除AndroidManifest.xml)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
package="改成你的应用包名">
<!--permissions-->
<uses-permission android:name="com.android.vending.BILLING" />
<queries>
<intent>
<action android:name="com.android.vending.billing.InAppBillingService.BIND" />
</intent>
</queries>
<application>
<!--meta-data-->
<meta-data android:name="com.google.android.play.billingclient.version" android:value="6.1.0" />
</application>
</manifest>
(以上配置即可解决我们检测到此版本中包含的一个或多个 app bundle 使用的是以下 Play 结算库版本)
如果还是有问题,需要打包aab,请,即可协助打包
使用
获取模块,需要用googlePay的任何地方执行即可,也可以全局加载
var googlePay = uni.requireNativePlugin("sn-googlepay5");
方法
- init - 初始化
// 初始化
googlePay.init({}, (e) => {
if (e.code == 0) {
// 初始化成功
} else {
// 初始化失败
}
});
- isFeatureSupported - 是否支持PRODUCT_DETAILS,用于检查手机是否安装最新play商店,防止不兼容
googlePay.isFeatureSupported((e) => {
if (e.code == 0) {
// 支持
} else {
// 不支持,需要升级play商店应用
}
});
- querySku - 查询 sku
// 查询sku
googlePay.querySku(
{
inapp: ["inapp_test", "inapp_test1"], // 与subs二选一, 参数为商品ID(字符串)数组
subs: ["sub_test", "sub_test1"], // 与inapp二选一,参数为商品ID(字符串)数组
},
(e) => {
if (e.code == 0) {
// 查询成功
e.list; // 查询结果, array
} else {
// 查询失败
}
},
);
googlePay.pay({
productId: "", // 产品id
offerToken: "", // 折扣token,可选参数 (如果querySku返回了offerToken,则必须传,否则支付掉不起来)
// 以下参数用于更新订阅, 参数参考 https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.SubscriptionUpdateParams.Builder
oldPurchaseToken: "", //
replacementMode: 0, //
prorationMode: 0, //
externalTransactionId: "", //
}, (e) => {
if (e.code == 0) {
// 支付成功
e.data; //支付结果, array [ {original:{ }, signature: ''} ]
} else {
// 支付失败
}
});
-
payAll - 发起支付,可以支持更多参数。比如设置交易归因
googlePay.payAll(
{
productId: "", // 产品id
offerToken: "", // 折扣token,可选参数 (如果querySku返回了offerToken,则必须传,否则支付掉不起来)
accountId: "", // 用户Id,可选参数
profileId: "", // 个人资料Id,可选参数
// 以下参数用于更新订阅,参数参考 https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.SubscriptionUpdateParams.Builder
oldPurchaseToken: "", //
replacementMode: 0, //
prorationMode: 0, //
externalTransactionId: "", //
},
(e) => {
if (e.code == 0) {
// 支付成功
e.data; //支付结果, array [ {original:{ }, signature: ''} ]
} else {
// 支付失败
}
},
);
- consume - 消耗品 确认交易
googlePay.consume(
{
purchaseToken: "aa", // 来自支付结果的original.purchaseToken (或 original.token)
},
(e) => {
if (e.code == 0) {
// 确认成功
} else {
// 确认失败
}
},
);
- acknowledge - 非消耗品、订阅型 确认交易
googlePay.acknowledge(
{
original: {}, // 来自支付结果
signature: "",
},
(e) => {
if (e.code == 0) {
// 确认成功
} else {
// 确认失败
}
},
);
- queryPurchases - 查询当前购买记录
googlePay.queryPurchases(
{
skuType: "inapp", // inapp 或 subs
},
(e) => {
if (e.code == 0) {
// 查询成功
e.billingResult; // 采购结果, {code:0,msg:''}
e.purchasesList; // 采购列表,不一定有 [ {original:{ }, signature: ''} ]
} else {
// 查询失败
}
},
);
- queryPurchaseHistory - 查询历史购买记录
googlePay.queryPurchaseHistory(
{
skuType: "inapp", // inapp 或 subs
},
(e) => {
if (e.code == 0) {
// 查询成功
e.billingResult; // 采购结果, {code:0,msg:''}
e.purchasesList; // 采购列表,不一定有 [ {original:{ }, signature: ''} ]
} else {
// 查询失败
}
},
);
- showInAppMessages - 显示应用内消息
googlePay.showInAppMessages(
{
categoryId: 2
},
(e) => {
if (e.code == 0) {
// NO_ACTION_NEEDED
} else if (e.code == 1) {
// SUBSCRIPTION_STATUS_UPDATED
// e.purchaseToken
}
}
)
示例
<template>
<view class="content">
<button class="btn" type="default" @click="payInApp">内购</button>
<button class="btn" type="default" @click="paySubs">订阅</button>
</view>
</template>
<script>
var googlePay = uni.requireNativePlugin('sn-googlepay5');
export default {
data() {
return {
isConnected: false
};
},
onLoad() {
googlePay.init({}, (e) => {
console.log('init', e);
if (e.code == 0) {
this.isConnected = true;
// 初始化成功
} else {
// 初始化失败
this.isConnected = false;
}
});
},
methods: {
payInApp() {
if (this.isConnected == false) {
console.log('请先init,保证服务连接成功');
return;
}
var pId = 'inapp_test';
// 步骤一:查询sku
googlePay.querySku(
{
inapp: [pId]
},
(e) => {
if (e.code == 0) {
console.log('querySku', e.list);
if (e.list.length > 0) {
var pd = e.list[0];
// 步骤二:支付
googlePay.pay(
{
productId: pId // 产品id
},
(e) => {
console.log('pay result', e);
// 步骤三:确认订单
googlePay.consume(
{
purchaseToken: e.data[0].original.purchaseToken
},
(e) => {
console.log('consume result', e);
}
);
}
);
} else {
console.log('未查询到产品');
}
} else {
//查询失败
console.log('querySku fail', e);
}
}
);
},
paySubs() {
if (this.isConnected == false) {
console.log('请先init,保证服务连接成功');
return;
}
// var pId = 'vip_yue';
var pId = 'vip10000';
// 步骤一:查询sku
googlePay.querySku(
{
subs: [pId]
},
(e) => {
if (e.code == 0) {
console.log('querySku', e.list);
if (e.list.length > 0) {
var pd = e.list[0];
var offerToken = '';
if (pd.subscriptionOfferDetails && pd.subscriptionOfferDetails.length > 0) {
offerToken = pd.subscriptionOfferDetails[0].offerToken;
}
// 步骤二:支付
googlePay.pay(
{
productId: pId, // 产品id
offerToken
},
(e) => {
console.log('pay result', e);
if (e.code == 0) {
// 步骤三:确认订单
// 支付成功后,一定别忘记调用acknowledge, 参数具体看接口
googlePay.acknowledge(
{
original: e.data[0].original,
signature: e.data[0].signature
},
(e) => {
console.log('acknowledge result', e);
}
);
}
}
);
} else {
console.log('未查询到产品');
}
} else {
//查询失败
console.log('querySku fail', e);
}
}
);
}
}
};
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
.btn {
width: 500rpx;
}
</style>
常见错误
-
Billing Unavailable
主要原因:
- 手机未正确安装play商店 app
- play商店使用的google账号不具备支付能力,需要找一个具备支付能力的账号(以可以拉起支付弹窗为准)
-
Google Play In-app Billing API version is less than 3
主要原因:
- google play 版本过低,需要升级
- google play 登陆过国内账号,需要清除缓存 ,参考https://www.jianshu.com/p/85d5dd523cb7
-
常见错误 code
-
Invalid SKU details
{ "code": 5, "msg": "Invalid SKU details." }
如果报这个错,请检查 2 点:1、必须国外 google 账号测试 2、google play 版本是否太低,升级试试
-
无法购买
请参考以下文章排查
-
originalJson排序问题
后台验证originalJson需要保证json字符串key的顺序问题,但是接口返回的是json object,因此需要处理下
// 以下代码请在pay/payAll回调调用 var original = e.data[0].original; var originalJson = JSON.stringify(original, ['orderId','packageName','productId','purchaseTime', 'purchaseState','purchaseToken','quantity','acknowledged']); // 然后originalJson就可以传给后台做验证
-
应用签名证书不一致问题
很多新手,上架play商店是,都用了play后台自动生成的应用签名证书,应用云打包又是另一个证书,导致证书不一致,无法拉起支付。解决办法,替换play后台应用证书,参考 或 参考2
jks在线转pem工具:
- https://myssl.com/cert_convert.html
- https://tools.wendy8.com/cert_convert