similing4
similing4
  • 发布:2022-09-15 23:04
  • 更新:2024-08-27 09:05
  • 阅读:2735

有关uniapp的苹果应用内支付调起代码编写经验分享

分类:uni-app

官方文档在这里:苹果应用内支付
官方文档有一部分说的比较模糊不太详细,报错也是如此。因此这里说一下方便大家排雷避坑

  1. 申请流程

    • 要有苹果开发者账号这个就不说了
    • 要在appstoreconnect的应用的功能下面管理你的 App 内购项目,亲测添加后把信息填写完整并保存,只要状态为准备提交即可!
    • 把你添加的商品的产品 ID记下来一会要用到(下文称pid)
    • 你需要到苹果开发者中心证书管理生成一个iOS App Development类型的证书并生成p12文件和Profile页面生成mobileprovision文件,具体生成教程很多就不一一列举了。生成后打包个自定义基座就可以写代码了。

      注意!上述过程一个都不能漏

  2. 代码编写流程
    代码编写文档放在文章开头了,这里说一下调起顺序:

    • 使用uni.getProvider获取id为appleiap的channel,下文称该channel为支付通道。例:
      async getIAPChannel() {  
      return await new Promise((recv, recj) => {  
      uni.getProvider({  
          service: 'payment',  
          success: res => {  
              const iapChannel = res.providers.find(channel => {  
                  return channel.id === 'appleiap';  
              });  
              if (iapChannel) recv(iapChannel);  
              recj(new Error('当前环境不支持使用IAP支付!'));  
          }  
      });  
      });  
      }
    • 使用通道的requestProduct方法获取pid对应的商品信息。例:
      let orderDetail = await new Promise((recv, recj) => {  
      channel.requestProduct([pid], recv, recj);  
      });

      注意!!!这一步不能省略,否则会无法调起支付!!!

    • 使用uni.requestPayment调起支付。例:
      let transaction = await new Promise((recv, recj) => {  
      uni.requestPayment({  
      provider: 'appleiap',  
      orderInfo: {  
          productid: pid,  
          username: 'ORDERID' + orderid,  
          quantity: 1,  
          manualFinishTransaction: true  
      },  
      success: t => {  
          recv(t);  
      },  
      fail: e => {  
          recj(new Error('支付调起失败:Errcode ' + e.errCode + ',' + e.errMsg));  
      }  
      });  
      });
  3. 掉单处理
    官方文档中说明部分与实际demo代码不一致。这里说一下流程:

    • 使用uni.getProvider获取id为appleiap的channel,下文称该channel为支付通道。例同代码编写流程
    • 使用支付通道的restoreCompletedTransactions方法获取可能掉单的订单列表(支付时一定要设置manualFinishTransaction为true否则这里就找不到了)。例:
      let customOrderList = await new Promise((recv, recj) => {  
      channel.restoreCompletedTransactions({}, recv, e => { //第一个参数必传,否则会导致app闪退!  
      recj(new Error('获取未完成订单列表失败:Errcode ' + e.errCode + ',' + e.errMsg));  
      });  
      });
    • 处理掉单,掉单分几种情况,官方文档有介绍:
      const IapTransactionState = {  
      purchasing: "0", // 【应用商店正在处理的交易】A transaction that is being processed by the App Store.  
      purchased: "1", // 【一个成功处理的交易】A successfully processed transaction.  
      failed: "2", // 【一个失败的交易】A failed transaction.  
      restored: "3", // 【已经购买过该商品】A transaction that restores content previously purchased by the user.  
      deferred: "4" // 【在队列中,但其最终状态为等待外部操作(如“请求购买”)的交易】A transaction that is in the queue, but its final status is pending external action such as Ask to Buy.  
      };

      我只需要处理failed和purchased两种状态的交易即可,具体根据业务需求决定。例:

      for (let i = 0; i < customOrderList.length; i++) {  
      if (customOrderList[i].transactionState == 2) {  
      //关闭失败订单  
      for (let b = 0; b < 5; b++)  
          try {  
              await new Promise((recv, recj) => {  
                  channel.finishTransaction(transaction, recv, recj);  
              });  
              break;  
          } catch (e) {  
              console.log(e);  
          }  
      } else  
          await this.verifyTransactionReceipt(customOrderList[i]); //上报已经成功但服务器没有处理的订单(把transactionReceipt属性值发给服务端就行了),接收到服务器成功响应后再关闭订单。  
      }
0 关注 分享

要回复文章请先登录注册

朱小

朱小

我这内购项目都已批准了还是获取不了产品 requestProduct
2024-08-27 09:05
zhaoyu2020

zhaoyu2020

楼主 请教下 App 内购买项目 这个是怎么变成准备就绪的
2024-03-18 14:46