更新记录

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

原生插件通用使用流程:

  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原生插件配置”->”云端插件“列表中删除该插件重新选择


说明

此插件提供 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 {
    // 支付失败
  }
});
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

    BillingResponseCode

  • 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

隐私、权限声明

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

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

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

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

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问