|
@@ -59,12 +59,15 @@ enum KMInAppPurchaseState: String, CaseIterable {
|
|
|
case restoreVerFailed = "Restore 2-step Verification Failed"//"restore二次验证失败"
|
|
|
case noReceipt = "No Order Information"//"无票据信息"
|
|
|
case orderFailed = "Order Creation Failed"//"订单创建失败"
|
|
|
+ case checkSubscriptionSuccess = "checkSubscriptionSuccess" //检测是否订阅成功
|
|
|
+ case checkSubscriptionFailed = "checkSubscriptionFailed" //检测是否订阅失败
|
|
|
}
|
|
|
|
|
|
class KMInAppPurchaseManager: NSObject {
|
|
|
public static let manager = KMInAppPurchaseManager()
|
|
|
|
|
|
var restoreCompletion: KMPurchaseRestoreCompletion?
|
|
|
+ var checkSubscriptionStatusCompletion: KMPurchaseCheckSubscriptionStatusCompletion?
|
|
|
var fetchProductCompletion: KMPurchaseFetchProductCompletion?
|
|
|
var purchaseProductCompletion: KMPurchaseCompletion?
|
|
|
var availableProducts: [SKProduct] = []
|
|
@@ -76,10 +79,8 @@ class KMInAppPurchaseManager: NSObject {
|
|
|
}
|
|
|
|
|
|
var orderId: String?
|
|
|
- var isPurchase: Bool = false
|
|
|
|
|
|
deinit {
|
|
|
- isPurchase = false
|
|
|
SKPaymentQueue.default().remove(self)
|
|
|
}
|
|
|
|
|
@@ -106,7 +107,6 @@ class KMInAppPurchaseManager: NSObject {
|
|
|
func purchaseProduct(productIdentifier: String, orderId: String = "", completion: @escaping KMPurchaseCompletion) {
|
|
|
self.purchaseProductCompletion = completion
|
|
|
self.orderId = orderId
|
|
|
- isPurchase = true
|
|
|
if SKPaymentQueue.canMakePayments() {
|
|
|
if let product = availableProducts.first(where: { $0.productIdentifier == productIdentifier }) {
|
|
|
KMPrint("\("购买产品") + \(productIdentifier)")
|
|
@@ -147,11 +147,12 @@ class KMInAppPurchaseManager: NSObject {
|
|
|
#endif
|
|
|
DispatchQueue.main.async { [unowned self] in
|
|
|
if state == .verSuccess {
|
|
|
- isPurchase = false
|
|
|
purchaseProductCompletion?(true, state)
|
|
|
+ purchaseProductCompletion = nil
|
|
|
} else if state == .restoreVerFailed ||
|
|
|
state == .restoreVerFailed {
|
|
|
restoreCompletion?(false, state)
|
|
|
+ restoreCompletion = nil
|
|
|
} else if state == .restoreVerSuccess ||
|
|
|
state == .restoreSuccess {
|
|
|
if state == .restoreVerSuccess {
|
|
@@ -159,14 +160,33 @@ class KMInAppPurchaseManager: NSObject {
|
|
|
} else {
|
|
|
restoreCompletion?(false, state)
|
|
|
}
|
|
|
+
|
|
|
+ restoreCompletion = nil
|
|
|
+ } else if state == .checkSubscriptionSuccess ||
|
|
|
+ state == .checkSubscriptionFailed {
|
|
|
+ if state == .checkSubscriptionSuccess {
|
|
|
+ checkSubscriptionStatusCompletion?(true)
|
|
|
+ } else {
|
|
|
+ checkSubscriptionStatusCompletion?(false)
|
|
|
+ }
|
|
|
+ checkSubscriptionStatusCompletion = nil
|
|
|
} else {
|
|
|
- isPurchase = false
|
|
|
purchaseProductCompletion?(false, state)
|
|
|
fetchProductCompletion?(false, [], state)
|
|
|
restoreCompletion?(false, state)
|
|
|
+
|
|
|
+ purchaseProductCompletion = nil
|
|
|
+ restoreCompletion = nil
|
|
|
+ fetchProductCompletion = nil
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ //判断是否订阅过
|
|
|
+ func checkSubscriptionStatus(_ completion: @escaping KMPurchaseCheckSubscriptionStatusCompletion) {
|
|
|
+ self.checkSubscriptionStatusCompletion = completion
|
|
|
+ SKPaymentQueue.default().restoreCompletedTransactions()
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
extension KMInAppPurchaseManager: SKProductsRequestDelegate {
|
|
@@ -193,6 +213,8 @@ extension KMInAppPurchaseManager: SKProductsRequestDelegate {
|
|
|
|
|
|
DispatchQueue.main.async { [unowned self] in
|
|
|
callBack(true, availableProducts, .productSuccess)
|
|
|
+
|
|
|
+ fetchProductCompletion = nil
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -204,6 +226,16 @@ extension KMInAppPurchaseManager: SKProductsRequestDelegate {
|
|
|
}
|
|
|
|
|
|
extension KMInAppPurchaseManager: SKPaymentTransactionObserver {
|
|
|
+ func paymentQueueDidChangeStorefront(_ queue: SKPaymentQueue) {
|
|
|
+ KMPrint("paymentQueueDidChangeStorefront")
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // Sent when entitlements for a user have changed and access to the specified IAPs has been revoked.
|
|
|
+ func paymentQueue(_ queue: SKPaymentQueue, didRevokeEntitlementsForProductIdentifiers productIdentifiers: [String]) {
|
|
|
+ KMPrint("didRevokeEntitlementsForProductIdentifiers")
|
|
|
+ }
|
|
|
+
|
|
|
func paymentQueue(_ queue: SKPaymentQueue, shouldAddStorePayment payment: SKPayment, for product: SKProduct) -> Bool {
|
|
|
// Handle the purchase intent here
|
|
|
// Return true to allow the purchase or false to deny it
|
|
@@ -211,36 +243,57 @@ extension KMInAppPurchaseManager: SKPaymentTransactionObserver {
|
|
|
}
|
|
|
|
|
|
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
|
|
|
- KMPrint("服务器返回数据")
|
|
|
+ KMPrint("苹果服务器返回数据")
|
|
|
if transactions.count > 0 {
|
|
|
- let transaction = transactions.first!
|
|
|
+ var isSuccess = false
|
|
|
for transaction in transactions {
|
|
|
if kPRODUCTS.contains(transaction.original?.payment.productIdentifier ?? PRODUCT_1) {
|
|
|
// 检查购买的产品是否是订阅产品
|
|
|
switch transaction.transactionState {
|
|
|
case .purchased:
|
|
|
- if isPurchase {
|
|
|
- // 购买成功,进行本地二次验证
|
|
|
- KMPrint("购买成功,进行本地二次验证")
|
|
|
- validatePurchase(transaction: transaction)
|
|
|
- }
|
|
|
+ isSuccess = true
|
|
|
case .failed:
|
|
|
- // 购买失败,处理错误
|
|
|
- KMPrint("购买失败,处理错误")
|
|
|
- handleError(transaction: transaction)
|
|
|
+ break
|
|
|
case .restored:
|
|
|
- KMPrint("恢复购买,进行本地二次验证")
|
|
|
- validatePurchase(transaction: transaction)
|
|
|
+ isSuccess = true
|
|
|
default:
|
|
|
break
|
|
|
}
|
|
|
- break
|
|
|
}
|
|
|
}
|
|
|
+ if isSuccess {
|
|
|
+ if let purchase = purchaseProductCompletion {
|
|
|
+ KMPrint("购买成功,进行本地二次验证")
|
|
|
+ validatePurchase(transaction: nil)
|
|
|
+ } else if let callBack = self.checkSubscriptionStatusCompletion {
|
|
|
+ KMPrint("恢复购买 checkSubscriptionStatusCompletion")
|
|
|
+ handleAction(state: .checkSubscriptionSuccess)
|
|
|
+ } else if let restore = self.restoreCompletion {
|
|
|
+ KMPrint("恢复购买,进行本地二次验证")
|
|
|
+ validatePurchase(transaction: nil)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ KMPrint("购买失败,处理错误")
|
|
|
+ if let callBack = self.checkSubscriptionStatusCompletion {
|
|
|
+ handleAction(state: .checkSubscriptionFailed)
|
|
|
+ } else if let restore = self.restoreCompletion {
|
|
|
+ handleAction(state: .restoreFailed)
|
|
|
+ } else if let purchase = purchaseProductCompletion {
|
|
|
+ handleAction(state: .productFailed)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ self.handleAction(state: .productCorrespondenceFailed)
|
|
|
+ }
|
|
|
+
|
|
|
+ for transaction in queue.transactions {
|
|
|
+ if transaction.transactionState != .purchasing {
|
|
|
+ SKPaymentQueue.default().finishTransaction(transaction)
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- func validatePurchase(transaction: SKPaymentTransaction) {
|
|
|
+ func validatePurchase(transaction: SKPaymentTransaction?) {
|
|
|
// 获取购买凭证
|
|
|
if let receiptURL = Bundle.main.appStoreReceiptURL,
|
|
|
let receiptData = try? Data(contentsOf: receiptURL) {
|
|
@@ -264,12 +317,13 @@ extension KMInAppPurchaseManager: SKPaymentTransactionObserver {
|
|
|
21007 订单信息是测试用(sandbox),但却被发送到产品环境中验证
|
|
|
21008 订单信息是产品环境中使用,但却被发送到测试环境中验证
|
|
|
*/
|
|
|
- func sendReceiptToServer(receiptData: Data, transaction: SKPaymentTransaction) {
|
|
|
+ func sendReceiptToServer(receiptData: Data, transaction: SKPaymentTransaction?) {
|
|
|
// 构建请求
|
|
|
let receiptString = receiptData.base64EncodedString(options: [])
|
|
|
let tempOrderId = self.orderId ?? ""
|
|
|
KMPrint(receiptString)
|
|
|
- if transaction.transactionState == .restored {
|
|
|
+// if transaction.transactionState == .restored {
|
|
|
+ if let restore = restoreCompletion {
|
|
|
KMRequestServerManager.manager.parseVerification(applePayProductId: PRODUCT_1, orderId: tempOrderId, receipt: receiptString, restore: 1) { [unowned self] success, result in
|
|
|
if success, let data = result?.result {
|
|
|
// 处理服务器返回的验证结果
|
|
@@ -284,7 +338,7 @@ extension KMInAppPurchaseManager: SKPaymentTransactionObserver {
|
|
|
self.handleAction(state: .restoreVerFailed)
|
|
|
}
|
|
|
}
|
|
|
- } else {
|
|
|
+ } else if let purchase = purchaseProductCompletion {
|
|
|
KMRequestServerManager.manager.parseVerification(applePayProductId: PRODUCT_1, orderId: tempOrderId, receipt: receiptString) { [unowned self] success, result in
|
|
|
if success, let data = result?.result {
|
|
|
// 处理服务器返回的验证结果
|
|
@@ -300,7 +354,7 @@ extension KMInAppPurchaseManager: SKPaymentTransactionObserver {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- SKPaymentQueue.default().finishTransaction(transaction)
|
|
|
+// SKPaymentQueue.default().finishTransaction(transaction)
|
|
|
}
|
|
|
|
|
|
func sendReceiptToAppleServer(receiptData: Data, transaction: SKPaymentTransaction) {
|
|
@@ -354,6 +408,11 @@ extension KMInAppPurchaseManager: SKPaymentTransactionObserver {
|
|
|
}
|
|
|
|
|
|
func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: Error) {
|
|
|
+ restoreCompletion?(false,.success)
|
|
|
+ restoreCompletion = nil
|
|
|
+
|
|
|
+ checkSubscriptionStatusCompletion?(false)
|
|
|
+ checkSubscriptionStatusCompletion = nil
|
|
|
KMPrint("restoreCompletedTransactionsFailedWithError")
|
|
|
}
|
|
|
|
|
@@ -409,15 +468,18 @@ extension KMInAppPurchaseManager: SKPaymentTransactionObserver {
|
|
|
return true
|
|
|
}
|
|
|
|
|
|
- func handleError(transaction: SKPaymentTransaction) {
|
|
|
+ func handleError(transaction: SKPaymentTransaction?) {
|
|
|
// 处理购买失败的逻辑
|
|
|
- SKPaymentQueue.default().finishTransaction(transaction)
|
|
|
- if transaction.transactionState == .restored {
|
|
|
- self.handleAction(state: .restoreFailed)
|
|
|
+ if let t = transaction {
|
|
|
+ SKPaymentQueue.default().finishTransaction(t)
|
|
|
+ if t.transactionState == .restored {
|
|
|
+ self.handleAction(state: .restoreFailed)
|
|
|
+ } else {
|
|
|
+ self.handleAction(state: .failed)
|
|
|
+ }
|
|
|
} else {
|
|
|
self.handleAction(state: .failed)
|
|
|
}
|
|
|
- // ...
|
|
|
}
|
|
|
|
|
|
func verifyPurchase(purchase: [String: Any]) -> KMPurchaseManagerState {
|