更新记录

1.0.1(2024-12-21) 下载此版本

简化支付流程,增加支付速度

1.0.0(2024-03-23) 下载此版本

初始版,只有订阅测试过


平台兼容性

Android iOS
× 适用版本区间:11 - 17

原生插件通用使用流程:

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


示例

封装 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()

隐私、权限声明

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

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

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

许可协议

作者未提供license.md

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