Highlight
App Store Server API 支持主动查询交易历史、订阅状态和退款信息;Server Notifications V2 覆盖 20+ 种事件类型;新增 Family Sharing 支持和沙盒环境改进。
核心内容
你的应用有内购功能。用户购买后,客户端把 receipt 发给服务器验证。但用户可能在离线时购买,或者客户端请求失败。你怎么确保服务器上的购买记录是完整的?
App Store Server API 和 Server Notifications V2 让你可以主动拉取数据,而不是被动等待客户端上报。
详细内容
App Store Server API
(01:14)
Server API 是一组 RESTful 接口,你的服务器可以用 JWT 认证后调用。
查询交易历史:
GET https://api.storekit.itunes.apple.com/inApps/v1/history/{originalTransactionId}
返回用户的完整交易历史,包括所有续订、升级、降级和退款。
查询订阅状态:
GET https://api.storekit.itunes.apple.com/inApps/v1/subscriptions/{originalTransactionId}
返回当前订阅的详细状态,包括过期时间、自动续订状态、优惠类型等。
(02:30)
关键点:
- 用
originalTransactionId查询,不是transactionId originalTransactionId在整个订阅生命周期中不变- 返回 JWS(JSON Web Signature)格式的签名数据
- 需要验证签名确保数据来自 Apple
Server Notifications V2
(04:00)
V2 的通知类型从 V1 的 10 种扩展到 20+ 种,覆盖订阅生命周期的所有关键事件:
| 通知类型 | 说明 |
|---|---|
SUBSCRIBED | 新订阅 |
RENEWAL | 自动续订成功 |
DID_CHANGE_RENEWAL_STATUS | 用户开启/关闭自动续订 |
DID_CHANGE_RENEWAL_PREF | 用户升级/降级订阅 |
EXPIRED | 订阅过期 |
REFUND | 退款 |
REFUND_DECLINED | 退款被拒绝 |
CONSUMPTION_REQUEST | 请求消费数据 |
REVOKE | 家庭共享被撤销 |
(05:15)
关键点:
- V2 通知包含更丰富的信息
- 所有通知都是 JWS 格式
- 需要验证签名
- 如果返回非 200,Apple 会在几天内重试
验证 JWS 签名
(06:30)
Server API 和通知返回的数据都是 JWS 格式,需要验证签名:
import CryptoKit
func verifyJWS(_ jwsString: String) throws -> Transaction {
// 1. 分离 JWS 的三个部分
let parts = jwsString.split(separator: ".")
guard parts.count == 3 else { throw VerificationError.invalidFormat }
// 2. 解析 header,获取证书
let headerData = base64Decode(String(parts[0]))
let header = try JSONDecoder().decode(JWSHeader.self, from: headerData)
// 3. 从 Apple 获取公钥并验证证书链
let certificate = try validateCertificateChain(header.x5c)
// 4. 验证签名
let signedData = Data((parts[0] + "." + parts[1]).utf8)
let signature = base64Decode(String(parts[2]))
let isValid = certificate.publicKey.isValidSignature(signature, for: signedData)
guard isValid else { throw VerificationError.invalidSignature }
// 5. 解析 payload
let payloadData = base64Decode(String(parts[1]))
return try JSONDecoder().decode(Transaction.self, from: payloadData)
}
(07:45)
关键点:
- JWS 包含 header、payload、signature 三部分
- 从 Apple 获取根证书验证证书链
- 验证签名确保数据未被篡改
- 解析 payload 获取交易信息
Family Sharing
(09:00)
iOS 15 支持内购的 Family Sharing。用户购买后,家庭成员可以自动访问,不需要额外付费。
Server API 中可以通过 inAppOwnershipType 字段区分:
PURCHASED:用户自己购买FAMILY_SHARED:通过家庭共享获得
当家庭共享被撤销时,服务器会收到 REVOKE 通知。
(10:15)
关键点:
inAppOwnershipType区分购买和共享REVOKE通知表示共享被撤销- 需要处理共享用户的访问权限
- 适合订阅和非消耗型内购
沙盒环境改进
(11:30)
沙盒环境新增功能:
- 测试订阅加速:沙盒中的订阅周期被压缩(1年=1小时)
- 测试退款:可以在沙盒中模拟退款流程
- 测试家庭共享:可以在沙盒中测试 Family Sharing
- 测试优惠:可以在沙盒中测试 introductory offer 和 promotional offer
(12:45)
关键点:
- 沙盒订阅周期加速,方便测试续订
- 沙盒支持退款测试
- 沙盒支持家庭共享测试
- 测试账号在 App Store Connect 中管理
核心启发
-
用 Server API 主动同步购买状态。不要只依赖客户端上报,服务器定期拉取确保数据一致。入口 API:
GET /inApps/v1/history/{originalTransactionId}。 -
用 Server Notifications V2 实时响应状态变化。20+ 种事件类型覆盖订阅全生命周期。入口 API:配置服务器 URL 接收 JWS 通知。
-
验证所有 JWS 数据的签名。防止中间人攻击和数据篡改。入口 API:Apple 根证书 + JWS 签名验证。
-
支持 Family Sharing。区分
PURCHASED和FAMILY_SHARED,处理REVOKE通知。入口 API:inAppOwnershipType+REVOKE通知。 -
在沙盒中测试完整购买流程。利用加速订阅周期快速测试续订、升级、降级和退款。入口 API:App Store Connect 沙盒测试账号。
关联 Session
- Support customers and handle refunds — 客户支持和退款处理
- Meet StoreKit 2 — StoreKit 2 新特性
- Meet in-app events on the App Store — App Store 应用内活动
评论
GitHub Issues · utterances