iOS内购丢单的解决方案

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS内购丢单的解决方案相关的知识,希望对你有一定的参考价值。

参考技术A     ios内购这块的开发一直比较麻烦,除了各种购买选项的问题,最恶心的问题就是丢单问题。
    丢单就是iOS内购过程中付了钱,但是App没有发货的问题。要解决丢单问题,先要梳理一下整个购买的过程:

以上就是整个购买的过程,现在我们根据每一步分析下可能出问题的点

这一步的操作就是让服务器创建当前购买商品的订单,返回结果失败或者成功,这里基本不会出问题,成功就继续接下来的流程,失败的话,客户端返回失败的提醒就行。

绝大多数的问题都出在这里,在这里说一下我遇见的坑

对于第一个问题,内购的api有一个监听机制,在每次app刚启动的时候调用 [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; 方法, - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions ,会回调所有未执行 [[SKPaymentQueue defaultQueue] finishTransaction:tran]; 的transaction,这个时候再去和服务器进行订单的验证。这里还有一个很麻烦的问题,在上个流程中,调用服务器创建了订单,会返回一个订单号,验证的时候一般都是把订单号,以及receipt,transactionid一起发送给服务器,但是这里是拿不到订单号的。针对这个问题,网上有人用 applicationUsername 这个字段去存入订单号,但是也有一些人在使用这个字段的时候出现了Bug(App杀死后,获取这个字段的值为空,参见下面的引用),为了保险,这里还是不用字段。我的解决方案是在用户创建完订单之后,存储当前的订单信息,用户token等等,当购买完之后,再去取这个订单信息,完成验证,删除订单,这个方案的核心是永远只存储一个订单,若在购买的时候有未完成的订单,必须先验证之前的订单,验证完之后,再去发起新的购买,这样就能规避多个transaction不能匹配订单号的问题;
    对于第二个问题,这个问题好解决,不用这个第三方就行,自己造个轮子,基本的购买逻辑很简单,没必要用这个插件。当 - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions 返回的transaction的state为failure时候,finish这个transaction,state为purchsed的时候,去验证。
    这里还有一个问题,finishTransaction:的调用时机,一定要在与服务器完成验证之后,再去调用这个方法,因为在与服务器的验证的过程中,也是会出现错误的,如果再购买成功回调之后就调用这个方法,验证错误的订单也被finish了,下次去取transaction的时候,就取不到了,这样就造成了丢单问题。

    这里的逻辑基本就是自己的了,跟苹果内购关系不大,把订单、receipt等信息发给服务器就行,唯一需要注意的问题就是网络错误,这个时候我会做一个轮循,在发生错误的时候,轮循几次,超过这个次数,认为验证失败,等到用户购买下一个商品、或者app重新启动,会重新验证这个订单(当然,这个情况是极少的!为了严谨,做了以上处理)

    终于到最后一步了,这里有一个地方需要注意一下,就是本地服务器与苹果服务器验证的方式,之前我们公司出了个问题,在调用 /verifyReceip 这个接口去验证,苹果会返回一个数据status,它们认为status等于0就是完成购买了,但是这个字段的含义并非如此

    它只是反映这个receipt是不是完整的,并不能证明这次购买完成。正确的做法应该是服务器拿到此次的transaction和receipt之后,解析receipt,拿当前的transaction和receipt里的transaction数组去比对,若数组中有这个transaction对应的transactionid,则认为购买成功。
    苹果服务器返回的错误码中,我们只需留意21005即可,它代表验证服务器当前不可用(当然这种情况是级级级小的!为了严谨),处理的方式和网络错误的处理方式是一样的。

Flutter iOS内购(代码篇-全网最全)

参考技术A 在沙盒中验证receipt: https://sandbox.itunes.apple.com/verifyReceipt

在生产环境中验证receipt: https://buy.itunes.apple.com/verifyReceipt

以上是关于iOS内购丢单的解决方案的主要内容,如果未能解决你的问题,请参考以下文章

Keep客户端 In-App Purchase 掉单踩坑指南

Keep客户端 In-App Purchase 掉单踩坑指南

Keep客户端 In-App Purchase 掉单踩坑指南

Keep客户端 In-App Purchase 掉单踩坑指南

iOS 审核因为“内购”被拒的解决方案!

iOS内购 服务端票据验证及漏单引发的思考.