前几天 苹果网慢,有玩家账单处于待处理状态2天多
这。。。苹果内购还是很坑的,有时候回调购买成功了,票据有可能拿不到,还要去刷新票据。。。还要处理玩家退款。。。苹果抽成还高。。。网上有说可以通过邮件等方式引导用户到第三方去支付,苹果官方又找不到相关说明,也没见哪个大厂游戏这么做 
不能依赖等待状态,玩家在支付过程中可能会进后台,杀进程,等各种情况。
对账这个事情没有办法100%完美解决的,苹果不给厂商订单->用户的对应关系,这个是根本原因,所以你没办法100%识别。因此市场上才有黑卡代充这种事情。
好在这种情况发生的应该很少,有玩家来找的时候运营结合玩家给的id、订单截图、你们保存的订单数据和校验结果、以及是否有发道具的情况,综合判断一下。
支付过程中app进程被杀死,如果支付成功再次启动app,苹果会把收据发给你,再把收据发到服务端去处理,难点在于把这笔收据和原始订单对应上,一笔支付好处理,多笔支付就难对应上,贴主遇到的就是这种对应不上的情况。一次支付时让玩家处于等待状态,是防止玩家在上笔支付未完成,又发起一次相同商品ID的支付,这时app意外中断,如果玩家在外面,两笔都支付了,再启动app拿到收据,服务端就很难对应上了。所以让玩家处在等待状态,这样处理应该会好点吧。。。暂时没想到更好的处理办法
这种时候需要独立的内购项id,每个id给的东西是确定的。
就是这么回事!
目前的解决办法是
商店里多个物品 每个id不同, 每个物品的购买没结束前 不能再次购买这个物品,但可以购买其他不同ID的物品,这样 拿不到订单号时(applicationUsername ==nil)可以用 物品id来查找一个 交易中的订单号,前提是 游戏订单号等信息需要存储在本地, 要是 玩家支付成功,票据没验证时,卸载了游戏,本地存的数据也就丢时了,等票据回来也找不到订单号了,这决定会丢单!但可以用钥匙串来存数据,这样能减少这种丢单!
你没考虑到一个问题,如果这个人有两个苹果手机一个苹果账号,当手机a支付完成但没完成时,在手机B上支付同样的商品会返回手机A上没完成的订单,这时候你服务器怎么处理,所以我的做法是,服务器不负责下单,只负责拿到客户端上传的苹果订单信息去服务器验证,这个会返回订单是否有效的等相关信息,最重要的是里面会包含申请的唯一product_id, 如果订单有效服务器就判断传上该订单数据的角色是否可以购买该道具,可以就发放道具然后告诉客户端完成订单就可以了,如果不能购买就告诉客户端弹出提示啥的,这个流程是统一的,一般苹果审核比较严的时候会要求恢复订单,即掉单后,客户端在角色进入新游戏调用苹果api接口获取是否有未完成的订单,如果有就主动弹出一个弹框告诉用户有未完成的订单,点击确认后走之前的流程就可以了,即使出现在角色a购买,恢复的登录的是角色b, 因为弹出的确认框告知了用户,这也说得过去
你这个用例 我试过,并不确定票据会返回到哪个手机,至少我不确定,
你的用例是 A手机支付完成,但没等到票据的时候,关机,B手机登录相同的Apple id,进入游戏,B手机并不支付,B手机是否会收到票据?
咱们的前提是 进入游戏就注册票据回调
此时 如果B手机收到票据,但B手机上并没有游戏订单号,(我现在的做法是,根据此时的信息,做了个订单号,让服务器去处理吧!估计会把 道具发给目前登录的角色)
苹果有restore流程 你查看一下文档就知道,简单来说就是一个商品订单如果没有调用api接口finish掉,会一直存在,只要是相同的苹果账号上,都可以通货接口拿到该订单,就是你说的票据
我的意思是服务器只管拿到票据发放道具就可以,至于是账号a或者账号b发起的支付并不重要,最多就是处理不是主动购买而是恢复购买时弹出不一样的提示告诉玩家是否需要恢复到该账号角色上
我其实觉得你的这个内部订单号创建时机有点问题,我们是不在客户端本地保存任何订单号的,直到客户端拿到苹果支付成功的票据以后,才去服务端创建订单号并校验客户端上传的票据,如果成功那就返回给客户端去finish。
你的这种方式, 如果 拿到票据的时候 用户切换了帐号, 或者 角色, 那么道具就发放到当前登录的这个角色上, 这可能和当初支付时的角色 并不是一个角色呀!
好吧,我们确实不需要考虑多角色的问题。但是这个问题无法避免,在客户端本地缓存可以一定程度上缓解问题,但是还是不能彻底解决。
新的 StoreKit 2 出来之后,增加了一个类似的字段 appAccountToken 。老的 StoreKit 也改了规则,applicationUsername 现在传 UUID String 苹果后端会保存,也能透传回前端。
不过虽然苹果说 applicationUsername 传 UUID 前端可以获取回传,但实际可能存在 Bug,重启后的 Transaction applicationUsername 是 nil。类似问题:flutter GitHub issue
在后端 verifyReceipt 或者用新的 App Store Server API 接口,一定能拿到这个值,用这个字段做订单关联就不会有丢单问题了。
