Flutter 接入iOS苹果内购支付踩坑过程

4,985 阅读4分钟

如何配置内购商品

在这里插入图片描述

坑1:项目与价格配置

苹果内购支付和我们平时接入支付宝或者微信支付有很大的差别。

  1. 苹果内购支付的价格只能选择,不能直接设置。如图: 在这里插入图片描述

  2. 苹果内购支付是通过配置项目的模式来实现支付的。我们应该把每个项目看作一个配置在苹果后台的商品,而不仅仅是一个支付配置。这样苹果内购比较好理解一点。

  3. 项目的类型有很多种,每一种作用不同,甚至还会影响审核

  4. 第一次配置好一个项目后,需要重新提一个版本后才能生效的。所以,第一次只能通过沙盒测试了。

坑2:内购项目类型

  1. 消耗型商品

可以消耗使用的商品, 比如游戏中的金币, 钻石等, 可以用来购买应用内虚拟物品的货币。

  1. 非消耗型商品 无法被消耗的商品,比如一些教育型APP中的课程, 再比如一些赛车游戏中的赛道, 这类商品需要在审核添加恢复购买按钮, 用于用户购买过后再误删除或其他原因卸载APP后的恢复流程, 否则提交审核会被拒绝。

  2. 非续期订阅 此类商品与消耗型商品类似, 比如一个月的会员, 一个季度的会员等,与消耗型商品的差异在于, 这类商品在验证凭证时需要传递共享秘钥

  3. 自动续期订阅 这类商品和其他商品的流程也有些许不同, 应用比如视频APP中的连续包月会员, 此类商品到期会自动扣费, 服务器的验证逻辑也会有所不同

在国内用的比较多的类型应该是消耗型商品,我们一般都是通过自己的服务器来处理支付逻辑的。而使用订阅类型商品还要处理一些其他的逻辑。

注意:所有的消耗型商品就需要实现 “恢复购买” 功能的,否则过不了审核。

消耗型支付流程

在这里插入图片描述

坑3:苹果内购漏单问题处理

  • 苹果内购支付和微信/支付宝支付的流程有一个很大的不同。 微信/支付宝支付的结果通过notify_url 回调支付结果到自己的服务器。这样就能极大的保证了用户支付成功后,后台是能够接受到支付结果的。 而苹果内购支付成功后还需要客户端请求服务器的验证的接口,验证成功后才能判断支付有效。这个过程中容易因为网络闪退等问题导致漏单情况。

  • 漏单情况的处理 针对上面的分析,我们需要在购买前让后台产生一个订单。在得知苹果支付成功后,将订单和苹果返回的验证数据保存到本地。最后请求后台接口进行验证,验证通过了再删除本地的验证数据。否者下次打开APP要自动进行验证。

坑4:测试时只能使用沙盒来测试,即使是TestFlight上也是沙盒测试

说不上很坑,只是开发完不能通过实际支付来测试,让人心里没底。实际测试要上线之后测,出问题了也只能是重新提一个版本来修改了。不过让人值得安慰的是在沙盒没问题上线了一般也没问题的。

坑5:实际支付测试

由于苹果内购要收取30%的手续费。那么实际支付测试就不能用产品的实际金额来支付了。只能配置1元的商品来进行测试。而问题就是小额的支付,苹果的扣款延时可能比较大。我们就遇到连续的支付三次后,商品购买成功了。不过绑定的支付宝没有扣款提醒。还以为漏扣钱了,结果几个小时后才扣款。

Flutter 苹果内购组件flutter_inapp_purchase 的使用

  1. 下载依赖
  flutter_inapp_purchase: ^3.0.1
  1. 初始化组件与监听
    var result = await FlutterInappPurchase.instance.initConnection;
    //设置结果监听
    // 更新购买订阅消息
    _purchaseUpdatedSubscription =
        FlutterInappPurchase.purchaseUpdated.listen((productItem) {
          print('purchase-updated: $productItem');
          if(productItem.transactionStateIOS == TransactionState.purchased) {
            //todo
          }else{
            closeProgressDialog();
          }
        });
    // 购买报错订阅消息
    _purchaseErrorSubscription =
        FlutterInappPurchase.purchaseError.listen((purchaseError) {
          print('purchase-error: $purchaseError');
          closeProgressDialog();
        });
  1. 获取苹果服务器上的项目列表,即使用不上,支付之前也要获取一次,否者支付失败。
List<IAPItem> items = 
await FlutterInappPurchase.instance.getProducts( ['0001', '0002', '0003'] );
  1. 拉起苹果支付
var result = FlutterInappPurchase.instance.requestPurchase(‘0001’);
  1. 获取需要 “恢复购买” 的列表,消耗型商品需要处理
List<PurchasedItem> items = 
await FlutterInappPurchase.instance.getAvailablePurchases();

如果创建的是消耗型商品,常用的方法就这些了。

总结

苹果内购并不复杂,只是对于第一次接触苹果内购的人来说,很多配置都莫名其妙的。不过你后面理解了就会焕然大悟。

所以,我这篇文章并不是一个很细致的教程,不过是把一些坑和一些对苹果支付的理解写下来罢了。不过,我相信你看完这篇文章后,再去做苹果内购会顺很多。