如果用户卸载应用程序并重新安装,我如何获得 IAP 收据? SWIFT
How can I get IAP receipt If user uninstall the app and install it again? SWIFT
如果我购买东西并查看购买收据,我可以通过以下方式获取它的编码值:
if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL,
FileManager.default.fileExists(atPath: appStoreReceiptURL.path) {
do {
let receiptData = try Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped)
print(receiptData)
let receiptString = receiptData.base64EncodedString(options: [])
print("receiptString \(receiptString)")
// Read receiptData
}
catch { print("Couldn't read receipt data with error: " + error.localizedDescription) }
}
但是如果我购买了东西,然后删除应用程序并重新安装并查看收据,我无法使用上面的代码获得任何东西。它只是得到 appStoreReceiptURL
并直接走,而不输入 do {} catch
。在这种情况下如何获得收据?
如果您尝试恢复购买,用户将不会退还所购买的金额,但是您可以验证用户是否购买了该产品,并且还会收到收据包含他之前购买的所有信息,因此您可以在您的应用程序中安全地验证购买。
App Store Review Guides 中明确指出
Any credits or in-game currencies purchased via in-app purchase may
not expire, and you should make sure you have a restore mechanism for
any restorable in-app purchases.
这意味着无论用户卸载应用程序的情况如何,您都应该提供某种机制(例如恢复购买按钮)。在您的情况下,您可以直接在登录屏幕上提供恢复按钮。查看 Apple Human Interface guidelines.
中恢复购买按钮的一些灵感
我想直接通过 Apple 恢复购买 API 在用户点击恢复购买按钮后,您可以使用:
SKPaymentQueue.default().restoreCompletedTransactions()
,这会触发 Apple 服务器,检查用户的 Apple ID 并获取他们之前购买的所有应用程序以及 returns 您使用以下代码观察到的 SKPaymentTransactionObserver
交易:
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction in transactions {
if transaction.transactionState == .restored {
//here is your restored transaction
}
}
}
但是,如果您想要获得包含所有收据数据(包括以前的购买)的新收据,我建议不要直接使用 Apple API,而是使用 SwiftyStoreKit
库:link on github 。下面的代码示例:
func restoreYourPurchases( completion: @escaping (Result<Bool,Error>) -> Void) {
SwiftyStoreKit.restorePurchases(atomically: true) { results in
var restoreSuccessfull = false
if results.restoreFailedPurchases.count > 0 {
print("Restore Failed: \(results.restoreFailedPurchases)")
}
else if results.restoredPurchases.count > 0 {
print("Restore Success: \(results.restoredPurchases)")
for purchase in results.restoredPurchases {
if purchase.productId == "yourID" {
let timeOfPurchase = purchase.originalPurchaseDate
}
}
}
else {
print("Nothing to Restore")
completion(.success(false))
}
}
}
如果我购买东西并查看购买收据,我可以通过以下方式获取它的编码值:
if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL,
FileManager.default.fileExists(atPath: appStoreReceiptURL.path) {
do {
let receiptData = try Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped)
print(receiptData)
let receiptString = receiptData.base64EncodedString(options: [])
print("receiptString \(receiptString)")
// Read receiptData
}
catch { print("Couldn't read receipt data with error: " + error.localizedDescription) }
}
但是如果我购买了东西,然后删除应用程序并重新安装并查看收据,我无法使用上面的代码获得任何东西。它只是得到 appStoreReceiptURL
并直接走,而不输入 do {} catch
。在这种情况下如何获得收据?
如果您尝试恢复购买,用户将不会退还所购买的金额,但是您可以验证用户是否购买了该产品,并且还会收到收据包含他之前购买的所有信息,因此您可以在您的应用程序中安全地验证购买。
App Store Review Guides 中明确指出
Any credits or in-game currencies purchased via in-app purchase may not expire, and you should make sure you have a restore mechanism for any restorable in-app purchases.
这意味着无论用户卸载应用程序的情况如何,您都应该提供某种机制(例如恢复购买按钮)。在您的情况下,您可以直接在登录屏幕上提供恢复按钮。查看 Apple Human Interface guidelines.
中恢复购买按钮的一些灵感我想直接通过 Apple 恢复购买 API 在用户点击恢复购买按钮后,您可以使用:
SKPaymentQueue.default().restoreCompletedTransactions()
,这会触发 Apple 服务器,检查用户的 Apple ID 并获取他们之前购买的所有应用程序以及 returns 您使用以下代码观察到的 SKPaymentTransactionObserver
交易:
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction in transactions {
if transaction.transactionState == .restored {
//here is your restored transaction
}
}
}
但是,如果您想要获得包含所有收据数据(包括以前的购买)的新收据,我建议不要直接使用 Apple API,而是使用 SwiftyStoreKit
库:link on github 。下面的代码示例:
func restoreYourPurchases( completion: @escaping (Result<Bool,Error>) -> Void) {
SwiftyStoreKit.restorePurchases(atomically: true) { results in
var restoreSuccessfull = false
if results.restoreFailedPurchases.count > 0 {
print("Restore Failed: \(results.restoreFailedPurchases)")
}
else if results.restoredPurchases.count > 0 {
print("Restore Success: \(results.restoredPurchases)")
for purchase in results.restoredPurchases {
if purchase.productId == "yourID" {
let timeOfPurchase = purchase.originalPurchaseDate
}
}
}
else {
print("Nothing to Restore")
completion(.success(false))
}
}
}