显示 IAP 页面之前的收据验证
Receipt validation before showing IAP-page
我对我们的应用内购买流程有疑问,因为它被 Apple 拒绝了。
因为我们不知道用户是否有有效订阅,所以我们必须先获取收据,这会导致 iTunes Store 密码提示(这是我们在非生产环境中正确理解的正常行为) .然后进行验证,根据结果,我们显示自动续订订阅页面或通过请求的操作。
我们的流程是:
- 正在获取收据
- 正在验证收据
- 如果
- 有效:通过请求的操作;
- 无效:显示自动续订订阅页面,用户可以在其中进行购买。
现在 Apple 在他们的拒绝中评论说他们看不到自动续订订阅页面。相反,他们从 iTunes Store 收到了密码提示。
正如我们正确理解的那样,密码提示是非生产环境中的正常行为,但 Apple 似乎并不期望这种行为。我们在获取收据的方式上没有任何改变。
我们使用 SwiftyStoreKit 以便于处理。这是我们的代码:
SwiftyStoreKit.fetchReceipt(forceRefresh: false) { result in
switch result {
case .success(let receiptData):
let encryptedReceipt = receiptData.base64EncodedString(options: [])
Log.info("Fetch receipt success")
//further code to send the receipt to our server
case .error(let error):
observer.send(error: error.localizedDescription)
}
}
我们的流程是否不正确,或者我们如何在不获取收据的情况下验证用户是否具有有效订阅?我们在这里有点困惑。有人可以在这里给我们任何建议吗?
您当前的流程没有提供很好的用户体验;他们启动您的应用程序并看到 iTunes 帐户密码提示,但没有任何关于它出现原因的上下文。
我建议您采用类似于以下的流程:
- 当您在此设备上验证订阅时,向 UserDefaults 添加一个布尔值
- 当您的应用程序启动时,检查此值。
- 如果值为真则刷新收据并验证订阅
- 如果值为 false/not,则显示您的商店界面。确保您的商店界面包含 "Restore" 按钮。
- 现在,如果用户知道他们有订阅,他们可以点击恢复,您可以验证他们的订阅;如果此时系统提示他们输入 iTunes 帐户密码,他们就会明白原因。
- 如果用户没有订阅,则他们可以购买一个。即使他们确实有一个并开始购买,StoreKit 也会处理并告诉他们他们已经有一个有效的订阅
- 无论订阅是购买还是恢复,您都将获得订阅的交易。然后您可以更新 UserDefaults 并按照步骤 3 继续。
或者,在尝试刷新之前检查本地收据是否存在。如果收据不存在,则可能会提示用户输入 iTunes 密码:
if let receiptDataURL = appStoreReceiptURL,
let _ = try? Data(contentsOf: receiptDataURL) {
SwiftyStoreKit.fetchReceipt(forceRefresh: false) { result in
switch result {
case .success(let receiptData):
let encryptedReceipt = receiptData.base64EncodedString(options: [])
Log.info("Fetch receipt success")
//further code to send the receipt to our server
case .error(let error):
observer.send(error: error.localizedDescription)
}
}
} else {
// Display purchase/restore interface
}
我对我们的应用内购买流程有疑问,因为它被 Apple 拒绝了。
因为我们不知道用户是否有有效订阅,所以我们必须先获取收据,这会导致 iTunes Store 密码提示(这是我们在非生产环境中正确理解的正常行为) .然后进行验证,根据结果,我们显示自动续订订阅页面或通过请求的操作。
我们的流程是:
- 正在获取收据
- 正在验证收据
- 如果
- 有效:通过请求的操作;
- 无效:显示自动续订订阅页面,用户可以在其中进行购买。
现在 Apple 在他们的拒绝中评论说他们看不到自动续订订阅页面。相反,他们从 iTunes Store 收到了密码提示。
正如我们正确理解的那样,密码提示是非生产环境中的正常行为,但 Apple 似乎并不期望这种行为。我们在获取收据的方式上没有任何改变。
我们使用 SwiftyStoreKit 以便于处理。这是我们的代码:
SwiftyStoreKit.fetchReceipt(forceRefresh: false) { result in
switch result {
case .success(let receiptData):
let encryptedReceipt = receiptData.base64EncodedString(options: [])
Log.info("Fetch receipt success")
//further code to send the receipt to our server
case .error(let error):
observer.send(error: error.localizedDescription)
}
}
我们的流程是否不正确,或者我们如何在不获取收据的情况下验证用户是否具有有效订阅?我们在这里有点困惑。有人可以在这里给我们任何建议吗?
您当前的流程没有提供很好的用户体验;他们启动您的应用程序并看到 iTunes 帐户密码提示,但没有任何关于它出现原因的上下文。
我建议您采用类似于以下的流程:
- 当您在此设备上验证订阅时,向 UserDefaults 添加一个布尔值
- 当您的应用程序启动时,检查此值。
- 如果值为真则刷新收据并验证订阅
- 如果值为 false/not,则显示您的商店界面。确保您的商店界面包含 "Restore" 按钮。
- 现在,如果用户知道他们有订阅,他们可以点击恢复,您可以验证他们的订阅;如果此时系统提示他们输入 iTunes 帐户密码,他们就会明白原因。
- 如果用户没有订阅,则他们可以购买一个。即使他们确实有一个并开始购买,StoreKit 也会处理并告诉他们他们已经有一个有效的订阅
- 无论订阅是购买还是恢复,您都将获得订阅的交易。然后您可以更新 UserDefaults 并按照步骤 3 继续。
或者,在尝试刷新之前检查本地收据是否存在。如果收据不存在,则可能会提示用户输入 iTunes 密码:
if let receiptDataURL = appStoreReceiptURL,
let _ = try? Data(contentsOf: receiptDataURL) {
SwiftyStoreKit.fetchReceipt(forceRefresh: false) { result in
switch result {
case .success(let receiptData):
let encryptedReceipt = receiptData.base64EncodedString(options: [])
Log.info("Fetch receipt success")
//further code to send the receipt to our server
case .error(let error):
observer.send(error: error.localizedDescription)
}
}
} else {
// Display purchase/restore interface
}