Highlight
StoreKit 2 新增
showManageSubscriptions()和beginRefundRequest()API,让用户在应用内管理订阅和申请退款;Consumption API 让开发者向 Apple 提供消费数据,参与退款决策。
核心内容
用户想取消订阅,但找不到入口。用户想申请退款,但不知道怎么做。这些场景下,用户可能给应用差评,或者联系 Apple 支持。如果能在应用内直接解决这些问题,用户体验会好很多。
StoreKit 2 今年新增了三个 API 来解决这些痛点。
详细内容
应用内管理订阅
(11:42)
以前用户要管理订阅,必须离开应用去 App Store。现在可以在应用内直接打开管理页面。
import StoreKit
// 显示订阅管理页面
func showSubscriptionManagement() {
if let windowScene = view.window?.windowScene {
Task {
try await AppStore.showManageSubscriptions(in: windowScene)
}
}
}
(12:20)
关键点:
AppStore.showManageSubscriptions(in:)显示系统管理页面- 用户可以看到当前订阅、续订选项
- 可以升级、降级或取消订阅
- 所有操作同步到 App Store
你还可以在管理页面前展示挽留优惠:
// 在用户点击取消前展示优惠
func showRetentionOffer() {
// 展示自定义挽留界面
// 如果用户仍想取消,再调用 showManageSubscriptions
}
应用内申请退款
(13:36)
用户可以直接在应用内申请退款,不需要联系 Apple 支持。
import StoreKit
// 申请退款
func requestRefund(for transaction: Transaction) async {
do {
let refundStatus = try await transaction.beginRefundRequest(
in: view.window!.windowScene!
)
switch refundStatus {
case .success:
// 退款申请已提交
showRefundSubmittedMessage()
case .userCancelled:
// 用户取消了申请
break
}
} catch {
// 处理错误
print("Refund request failed: \(error)")
}
}
(14:14)
关键点:
transaction.beginRefundRequest(in:)发起退款申请- 系统显示退款原因选择界面
- 退款批准后服务器收到
REFUND通知 - 退款被拒绝后服务器收到
REFUND_DECLINED通知 - 沙盒环境支持退款测试
Invoice Lookup API
(03:44)
用户联系客服说 “我买了东西但没收到”。客服可以要求用户提供订单号(order ID),然后通过 Invoice Lookup API 查询。
GET https://api.storekit.itunes.apple.com/inApps/v1/lookup/{orderId}
返回:
{
"status": 0,
"signedTransactions": [
{
"transactionId": "1000000123456789",
"originalTransactionId": "1000000098765432",
"productId": "com.example.coins",
"purchaseDate": 1620000000000,
"quantity": 100
}
]
}
(04:20)
关键点:
status0 表示有效,1 表示订单号无效,2 表示无匹配交易- 返回 JWS 格式的签名交易数据
- 可以验证交易状态和退款状态
- 帮助客服快速定位问题
Refund Lookup API
(06:02)
查询某个用户的所有退款记录:
GET https://api.storekit.itunes.apple.com/inApps/v1/refund/lookup/{originalTransactionId}
适合处理服务器 outage 后补同步退款数据。
(06:44)
关键点:
- 用
originalTransactionId查询 - 返回该用户的所有退款交易
- 适合补同步和审计
- 返回 JWS 格式数据
Subscription Extension API
(09:40)
如果服务出现故障(如直播中断),你可以免费延长用户的订阅时间作为补偿。
PUT https://api.storekit.itunes.apple.com/inApps/v1/subscriptions/extend
{
"originalTransactionId": "1000000098765432",
"extensionDuration": 7,
"extensionReason": 1,
"requestIdentifier": "unique-request-id"
}
(10:23)
关键点:
- 每个订阅每年最多延长 2 次
- 每次最多延长 90 天
- 需要提供原因代码
- 用户会收到邮件通知
- 延长期不计入 85% 分成的一年期限
Consumption API
(19:12)
当用户申请退款时,Apple 会向你的服务器发送 CONSUMPTION_REQUEST 通知。你可以在 12 小时内回复消费数据,帮助 Apple 做退款决策。
PUT https://api.storekit.itunes.apple.com/inApps/v1/consumption/{originalTransactionId}
{
"customerConsented": true,
"consumptionStatus": 1,
"consumptionPlatform": 1,
"sampleContent": 1,
"deliveryStatus": 0,
"appAccountToken": "uuid-string",
"accountTenure": 365,
"playTime": 120,
"lifetimeSpend": 99.99,
"userStatus": 0
}
(20:00)
关键点:
customerConsented:用户是否同意分享数据consumptionStatus:0=未消费,1=部分消费,2=完全消费,3=已转让deliveryStatus:0=成功交付,1=交付失败- 必须在 12 小时内回复
- 数据帮助 Apple 做更准确的退款决策
核心启发
-
在应用内提供订阅管理入口。用户不需要离开应用就能查看和修改订阅。入口 API:
AppStore.showManageSubscriptions(in:)。 -
在应用内提供退款申请入口。减少用户给差评或联系 Apple 支持的概率。入口 API:
transaction.beginRefundRequest(in:)。 -
用 Invoice Lookup API 辅助客服。用户报问题时,用订单号快速查询交易状态。入口 API:
GET /inApps/v1/lookup/{orderId}。 -
用 Subscription Extension API 补偿服务故障。直播中断或服务器故障时,免费延长用户订阅。入口 API:
PUT /inApps/v1/subscriptions/extend。 -
回复 Consumption Request 参与退款决策。提供消费数据,减少不合理的退款。入口 API:
PUT /inApps/v1/consumption/{originalTransactionId}。
关联 Session
- Manage in-app purchases on your server — 服务端内购管理
- Meet StoreKit 2 — StoreKit 2 新特性
- Meet in-app events on the App Store — App Store 应用内活动
评论
GitHub Issues · utterances