更新记录
1.0.1(2024-12-21) 下载此版本
简化支付流程,增加支付速度
1.0.0(2024-03-23) 下载此版本
初始版,只有订阅测试过
平台兼容性
Android | iOS |
---|---|
× | 适用版本区间:11 - 17 |
原生插件通用使用流程:
- 购买插件,选择该插件绑定的项目。
- 在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原生插件配置”->”云端插件“列表中删除该插件重新选择
示例
封装 ipa 支付类
// iap.js
export class Iap {
_channelName = 'appleiap'
IAPSdk = null
constructor() {
// 引入插件
this.IAPSdk = uni.requireNativePlugin('xpc-IAPPlugin')
}
// 获取支付实例
getChannels() {
uni.getProvider({
service: 'payment',
success: (res) => {
this._channel = res.providers.find((channel) => {
return channel.id === this._channelName
})
if (!this._channel) {
// 这里没有找到支付渠道,报错
}
}
})
}
//向苹果或者谷歌服务器获取产品列表
getProduct(productIdList) {
return new Promise((resolve, reject) => {
this._channel.requestProduct(
productIdList,
(res) => {
resolve(res)
},
(err) => {
reject(err)
}
)
})
}
// 注册插件回掉
initializingAndRegisteringListeners(type, callBack) {
this.IAPSdk.initializingAndRegisteringListeners(type, callBack)
}
// 移除观察者
removeObserver() {
this.IAPSdk.removeObserver()
}
//获取苹果服务器已支付且未关闭的交易列表
restoreCompletedTransactions() {
this.IAPSdk.restorePurchase()
}
}
支付流程
- 初始化支付类
this._iap = new Iap()
- 获取支付 ID,由后端返回,再将 IDS 传递给苹果获取产品信息
const productIdList = uni.request({
url: '/getProductId',
method: 'GET'
})
this.productList = this._iap.getProduct(productIdList)
- 注册原生插件回掉,支付信息从回掉中回来
/**
* 获取最大值
*/
export const getLatestOrders = (arr, productIds) => {
if (!arr.length) return
// 过滤掉不在 productIds 中的订单
const filteredArr =
productIds && Array.isArray(productIds)
? arr.filter((order) => productIds.includes(order.payment.productid))
: arr
// 如果过滤后没有订单,返回 undefined
if (!filteredArr.length) return
// 寻找 transactionDate 最大的订单
return filteredArr.reduce((max, order) =>
new Date(order.transactionDate).getTime() >
new Date(max.transactionDate).getTime()
? order
: max
)
}
const listenBack = (arr) => {
if (typeof arr === 'string') {
// 出现字符串说明出错了,报错
console.log(arr)
return
}
if (arr.length === 0) {
// 说明没得支付记录
return
}
// 如果是恢复购买的话这里面有所有的支付历史,只取出第一条
// 支付的话就只有一条
const transaction = getLatestOrders(
arr,
clustersProduct(this.SKUListSource, this.purchaseMembershipType, true)
)
switch (transaction.transactionState) {
case IapTransactionState.purchasing:
console.log('正在支付中')
break
case IapTransactionState.purchased:
console.log('支付成功')
// 和后端校验
TODO()
// 完成后移除回掉
this._iap.removeObserver()
break
case IapTransactionState.failed:
// 移除回掉
this._iap.removeObserver()
break
case IapTransactionState.restored:
console.log('恢复购买')
// 和后端校验
TODO()
break
}
}
// 数字标识是否只初始化原生支付,不触发回掉,统一为1,需要回掉
this._iap.initializingAndRegisteringListeners(1, this.listenBack)
- 发起支付
// 传苹果返回的产品ID 如果自己保存的对的也可以直接传自己的
const productid = this.productList[0].productid
// 支付结果从上面回掉中返回
this._iap.requestPayment({
productid
})
- 恢复购买
// 结果从上面回掉中返回
this._iap.restoreCompletedTransactions()