前言
不知道大家有没有了解过苹果的内购,也就是我们说的苹果支付 IAP,如果大家的 App 有使用 IAP 功能,那么可能会遇到用户反馈苹果充值成功,但是服务没有到账的情况,用户一般会提供这样的苹果收据:
用户反馈时提供的苹果收据中,有一个字段中 ORDER ID
,苹果叫 Invoice order ID
(发票订单号),与我们开发者从 App 内获取到的 receipt
收据解析后,并没有 ORDER ID 字段!!!所以,我们无法定位和联系这个用户提供的发票与我们后台的订单号,从而无法给用户正常补发服务,开发者也是很无奈!但是最近苹果开发了一个新的功能,也就是我们的StoreKit 2,它让我们苹果支付可以变得更好,并且也可以用他们新的验证票据的方式哦
StoreKit 2 主要更新
- 一套新的基于 Swift 语言特性
- 更新收据和交易(数据格式和字段变更)
- 更多订阅类型的接口
- 相同的 StoreKit 框架
StoreKit 2 for Swift only
!没错!仅适用于 Swift !StoreKit 2
利用 Swift的最新特性,包括 Swift并发 等新语言接口,简化在App中获取产品信息、商品产品、处理交易以及管理对内容和订阅的访问。并且,StoreKit 2 只支持 iOS 15+ 。
Powerful new APIs
StoreKit 2
提供了以上更新的类(方法)来轻松访问 IAP 接口,可以理解为增强的版本,
- Products:有关在 App Store Connect 中配置的内购品项的信息
- Purchases:更新购买品项接口的可选参数,可绑定用户ID
- Transaction info:更新交易信息的内容格式
- Transaction history:提供查询交易历史记录的接口
- Subscription status:提供订阅品项的状态查询接口
除了原有的请示品项信息外,购买时,增加了一些可选参数 Purchase opthons
。
除了购买数据、促销优惠 外,最重要的是新字段:App account token
!
- 开发者创建
App account token
- 关联到 App 里的用户账号
App account token
使用UUID
格式- 在交易(Transcation)订单中永久保存
这个 `App account token` 是给开发者将用户的 ID 绑定到交易(Transcation)中,也就是把苹果的交易订单数据与用户信息进行映射,可以起到防止充值掉单的问题啊~
JWS
签名的交易(Transcation)信息:
- 每笔交易一个对象
- 签名的交易信息,数据格式使用 JWS(JSON Web Signature)
- 使用原生接口读取数据
Manage in-app purchases on your server 里讲解使用 JWS 数据格式的原因:
- 1、增强安全性
- 2、更容易解码
- 3、不用连接苹果服务器验证,开发者本地就可以单独验单!
JWS的主要目的是保证了数据在传输过程中不被修改,验证数据的完整性。但由于仅采用Base64对消息内容编码,因此不保证数据的不可泄露性。所以不适合用于传输敏感数据
JWS 格式的 transaction info 格式:
Base64() + "." + Base64(payload) + "." + sign( Base64(header) + "." + Base64(payload) )
这个 header 与 payload 通过 header 中声明的 alg 加密方式,使用密钥 secret 进行加密,生成签名。然后逆向构造过程,decode出 JWT 的三个部分:
- 头部(Header)
- 载荷(PayLoad)
- 签名(signature)
developer.apple.com/videos/play… demo
怎么解密呢
JWS x5c头参数包含用于签名和验证JWS的整个证书链。不需要获取任何其他证书或密钥。
RFC指定与用于签署JWS的公钥对应的证书必须是第一个证书。
您可以从此证书中提取公钥,并使用它来验证JWS签名。在这个答案中有一些指导
StoreKit2的一个重大改进是不再需要使用服务器来安全地验证应用内购买交易。
在StuteKIT2上的苹果WWDC 2021会话描述了JWS的内容,还展示了如何在设备上验证JWS实际上是为该设备生成的。
但是,如果您确实希望在服务器上验证事务,该怎么办?由于x5c声明包含证书链,攻击者可以使用自己的证书对伪造的JWS进行签名,并将该证书包含在x5c声明中。
答案是让你的应用程序将原始交易ID以及你需要的任何其他信息(如用户的帐户标识符)发送到服务器。然后,您的服务器可以从Apple请求相应的JWS,并验证返回的JWS的签名。
由于JWS是通过您的服务器代码从Apple获取的,因此可以确保它不是伪造的JWS。
如果可能,在您的购买请求中包含一个appAcCountToken
,并根据用户对服务器的身份验证来确定预期的令牌值,或者(不太有效)让您的应用在提供原始交易ID时提供令牌。然后,您可以验证JWS中的令牌值是否与预期值匹配。这使得攻击者更难重播其他购买事件。
transactions history
提供了三个新的交易(Transcation)相关的 API:
- All transactions:全部的购买交易订单
- Latest transactions:最新的购买交易订单。(分为订阅品项和除订阅品项外的所有类型二种)
- Current entitlements:当前用户有购买的权限。(全部的订阅品项、和非消耗品项)
获取用户的交易历史记录,包括他们在你的 App 中的所有应用内购买。 也是只需要参数一个:originalTransactionId
,注意,只需要是用户的任意一个交易的 originalTransactionId 就可以啦。这个大家一看就明白了,就不展开了。详细文档:Get Transaction History
新的验签接口
App Store Server 接口标准:
- JWT 认证
- JWS 交易内容格式
- Json 请求和响应
- 基于 originalTransactionId 标识参数
所有的 App Store Server API 接口都必须使用 JWT 认证,关于验证规则和流程,请查看文档:Generating Tokens for API Requests
结束
其实就是给大家介绍下 StoreKit 1和 StoreKit 2,对于苹果内购的一些更新吧!