1.0 内购类型
a. 消耗型商品:只可以使用一次的产品,使用以后即失效,必须再次购买。
示例:小说App购买的书币书券。
b. 非消耗型商品:只需购买一次,不会过时或随着使用而减小的产品。
示例:游戏 App 的赛道。
c. 自动续期订阅:容许用户在固定时间段内购买动态内容的产品。除非用户选择取消,不然此类订阅会自动续期。
示例:每个月订阅提供流媒体服务的 App。
d. 非续期订阅:容许用户购买有时限性服务的产品。此 App 内购买项目的内容能够是静态的。此类订阅不会自动续期。
示例:为期一年的已归档文章目录订阅。
2.0 内购的通用流程
a. 客户端向Appstore请求购买产品(假设产品信息已经取得),Appstore验证产品成功后,从用户的Apple账户余额中扣费。
b. Appstore向客户端返回一段receipt-data,里面记录了本次交易的证书和签名信息。
c. 客户端向我们可以信任的服务器提供receipt-data
d. 服务器对receipt-data进行一次base64编码
e. 把编码后的receipt-data发往itunes.appstore进行验证
f. itunes.appstore返回验证结果给服务器
g. 服务器对商品购买状态以及商品类型,向客户端发放相应的道具与推送数据更新通知
3.0 实际应用中的内购流程(自己产品为例)
a. 验证苹果自动续费的合理性: 是否是切换了账号了,是否是同一个账号下有2个不同的appleid订阅(订阅类型会进行此校验,消耗性直接走b)
b. 后台校验成功后,创建后台订单
c. 订单生成后,传入productID发起购买请求,苹果服务器验证产品成功后,从用户的Apple账户余额中扣费并向客户端返回凭证(receipt-data)
d. 客户端拿到凭证后,向服务器发起凭证校验,服务器拿到凭证进行一次base64编码,发到苹果服务器进行校验并返回结果给服务器。
e. 服务器对商品购买状态以及商品类型,向客户端发放相应的道具与推送数据更新通知
内购的遇到的问题
a、掉单问题
解决掉单问题前,我们要先简单把从支付请求开始到结束的步骤按照顺序排列出来,然后分析每一个步骤可能存在的调单情况。
- 发起支付请求 ---> 2. 扣费成功,得到receipt(支付凭据)---> 3. 去后台验证凭据获取e豆 ---> 4. 返回数据,前端刷新数据
调单的处理可分为在拿到交易订单之后调用 IPA 创建一个 IPA 交易,并且添加到支付队列,收到回调前跟收到回调后。
在创建后台订单时,此时后台会把订单信息回调,并将其已模型的形式存入Keychain中(存入Keychain中数据不会因卸载app等操作丢失)
情况1 创建订单完成,并没有发起支付请求
通过校验队列中的transactions进行判断,没有的话就是没有发起支付请求,那么此时需要重新发起支付的请求。
情况2 收到回调前(此时未拿到transactionId、凭证)
通过校验队列中的transactions进行判断,有的话就是已经发起支付请求但是没有收到回调,此时需要做SKPaymentQueue.default().restoreCompletedTransactions()(恢复已经完成的 交易)
情况2 收到回调后
首先将transactionId和凭证更新到已存入的Keychain中,通过校验Keychain中的transactionId是否存在,来确定是否已经收到回调,此时需要拿着存入Keychain中的凭证等到后台去校验。
网友评论