// // QSLVipManager.swift // QuickSearchLocation // // Created by Destiny on 2024/12/11. // import StoreKit typealias payComplete = ((QSLPayStatus, String) -> ()) typealias restoreComplete = ((Bool) -> ()) enum QSLPayStatus: Int { case fail = 0 case success case cancel case ignore case searchFail } class QSLVipManager: NSObject { static let shared = QSLVipManager() // 选择支付的商品 var selectGoods: QSLGoodModel? // 订单模型 var orderModel: QSLOrderModel? var payCompleteCloure: payComplete? var restoreCompleteClosure: restoreComplete? // 支付查询的次数 var statusSearchCount = 0 var isCheck: Bool = false // 是否正在恢复 var isPaying: Bool = false // 是否正在恢复 var isRestoring: Bool = false override init() { super.init() SKPaymentQueue.default().add(self) } deinit { SKPaymentQueue.default().remove(self) } } extension QSLVipManager { // func check() { // print("检查自动续费订单") // self.isCheck = true // } // 开始支付 func startPay(goods: QSLGoodModel, complete: payComplete?) { self.isPaying = true self.isCheck = false // 支付前查询自动续费的订单,将订单置为支付状态 let transactions = SKPaymentQueue.default().transactions if transactions.count > 0 { for tran in transactions { if tran.transactionState == .purchased { SKPaymentQueue.default().finishTransaction(tran) } } } selectGoods = goods payCompleteCloure = complete self.requestOrderPay() } // 应用启动后检查未支付完成的订单 func openAppRePay(receiptData: String, complete: payComplete?) { payCompleteCloure = complete self.requestOrderResult(receiptData: receiptData) } // 恢复订阅 func restoreAction(complete: restoreComplete?) { if complete != nil { self.restoreCompleteClosure = complete } // 支付前查询自动续费的订单,将订单置为支付状态 let transactions = SKPaymentQueue.default().transactions if transactions.count > 0 { for tran in transactions { if tran.transactionState == .purchased { SKPaymentQueue.default().finishTransaction(tran) } } } self.isPaying = true self.isCheck = false print("开始恢复订阅") SKPaymentQueue.default().restoreCompletedTransactions() Timer.scheduledTimer(withTimeInterval: 15.0, repeats: false) { timer in if let restoreCompleteClosure = self.restoreCompleteClosure { print("恢复订阅 15秒超时") restoreCompleteClosure(false) } self.restoreCompleteClosure = nil // 停止定时器并从运行循环中移除 timer.invalidate() } } } // 网络请求 extension QSLVipManager { // 发起支付请求 func requestOrderPay() { var dict = [String: Any]() dict["itemId"] = self.selectGoods?.goodId dict["payPlatform"] = 2 dict["payMethod"] = 3 QSLNetwork().request(.vipOrderSubmitAndPay(dict: dict)) { response in self.orderModel = response.mapObject(QSLOrderModel.self, modelKey: "data") if let selectGoods = self.selectGoods { self.orderModel?.selectGoods = selectGoods } self.submitIAP() } fail: { code, msg in if let payCompleteCloure = self.payCompleteCloure { payCompleteCloure(.fail, msg) self.payCompleteCloure = nil } } } // 网络请求订单结果 func requestOrderResult(receiptData: String) { var dict = [String: String]() if let tradeNum = self.orderModel?.outTradeNo { dict["outTradeNo"] = tradeNum dict["receiptData"] = receiptData } QSLNetwork().request(.vipOrderPayStatus(dict: dict)) { [weak self] response in let payStatus = response.toJSON(modelKey: "data>payStatus").intValue // 继续轮询查询支付状态 if payStatus == 0 || payStatus == 1 { QSLVipManager.shared.statusSearchCount = QSLVipManager.shared.statusSearchCount + 1 if QSLVipManager.shared.statusSearchCount < 10 { self?.cacheOrder(isFinish: false) DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) { // 在主线程上执行查询 DispatchQueue.main.async { self?.requestOrderResult(receiptData: receiptData) } } } else { self?.cacheOrder(isFinish: false) // 查询失败 if let payCompleteCloure = self?.payCompleteCloure { payCompleteCloure(.searchFail, "") } self?.payCompleteCloure = nil QSLVipManager.shared.statusSearchCount = 0 } } else if payStatus == 2 { self?.cacheOrder(isFinish: true) // 支付成功 if let payCompleteCloure = self?.payCompleteCloure { payCompleteCloure(.success, self?.orderModel?.outTradeNo ?? "") } self?.payCompleteCloure = nil QSLVipManager.shared.statusSearchCount = 0 } else if payStatus == 3 { self?.cacheOrder(isFinish: false) // 支付失败 if let payCompleteCloure = self?.payCompleteCloure { payCompleteCloure(.fail, "") } self?.payCompleteCloure = nil QSLVipManager.shared.statusSearchCount = 0 } else if payStatus == 4 { QSLVipManager.shared.statusSearchCount = 0 } } fail: { code, msg in self.cacheOrder(isFinish: false) if let payCompleteCloure = self.payCompleteCloure { payCompleteCloure(.fail, "") } self.payCompleteCloure = nil QSLVipManager.shared.statusSearchCount = 0 } } func requestRestoreOrder(receiptData: String) { self.isRestoring = true var params: [String: Any] = [String: Any]() params["receiptData"] = receiptData params["payPlatform"] = 2 params["payMethod"] = 3 QSLNetwork().request(.vipMemberResume(dict: params)) { response in self.isRestoring = false if let restoreCompleteClosure = self.restoreCompleteClosure { restoreCompleteClosure(true) } self.restoreCompleteClosure = nil } fail: { code, msg in if let restoreCompleteClosure = self.restoreCompleteClosure { restoreCompleteClosure(false) } self.restoreCompleteClosure = nil } } } extension QSLVipManager: SKPaymentTransactionObserver { // 提交内购 func submitIAP() { if SKPaymentQueue.canMakePayments() { let payment = SKMutablePayment() if let appleGoodId = self.selectGoods?.appleGoodsId { payment.productIdentifier = appleGoodId } payment.applicationUsername = self.orderModel?.appAccountToken payment.quantity = 1 SKPaymentQueue.default().add(payment) } } // 查询订单 func localSearchOrder(transaction: SKPaymentTransaction) { if let receiptUrl = Bundle.main.appStoreReceiptURL { let receiptData = try? Data(contentsOf: receiptUrl) if let receiptString = receiptData?.base64EncodedString(options: .endLineWithLineFeed) { debugPrint("receiptString = \(String(describing: receiptString))") // if let orderModel = HolaOrderCacheManager.getModel() { // if orderModel.receiptData.count > 0 { // if orderModel.receiptData == receiptString { // // 支付失败 // if let payCompleteCloure = self.payCompleteCloure { // payCompleteCloure(.cancel, "") // } // self.payCompleteCloure = nil // return // } // } // } self.orderModel?.receiptData = receiptString self.cacheOrder(isFinish: false) self.requestOrderResult(receiptData: receiptString) } } } // 恢复订阅 func restoreOrder(transaction: SKPaymentTransaction) { if isRestoring { return } if let receiptUrl = Bundle.main.appStoreReceiptURL { let receiptData = try? Data(contentsOf: receiptUrl) if let receiptString = receiptData?.base64EncodedString(options: .endLineWithLineFeed) { debugPrint("receiptString = \(String(describing: receiptString))") self.requestRestoreOrder(receiptData: receiptString) } } } // 缓存支付的结果 func cacheOrder(isFinish: Bool) { if var order = self.orderModel { order.isFinish = isFinish QSLCacheManager.cacheOrderModel(order) } } func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { print("监听AppStore支付状态 updatedTransactions") DispatchQueue.main.async { for tran in transactions { switch tran.transactionState { case .purchased: print("商品已苹果支付成功") if self.isCheck { SKPaymentQueue.default().finishTransaction(tran) } else { self.localSearchOrder(transaction: tran) SKPaymentQueue.default().finishTransaction(tran) } case .purchasing: print("正在购买中,商品已添加进列表") case .restored: print("恢复订阅") self.restoreOrder(transaction: tran) SKPaymentQueue.default().finishTransaction(tran) case .failed: print("商品支付失败") // 需要前台响应 if let payCompleteCloure = self.payCompleteCloure { payCompleteCloure(.fail, "") } self.payCompleteCloure = nil // 需要前台响应 if let restoreCompleteClosure = self.restoreCompleteClosure { restoreCompleteClosure(false) } self.restoreCompleteClosure = nil SKPaymentQueue.default().finishTransaction(tran) case .deferred: print("未确定") default: break } } } } func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: Error) { print("恢复购买失败\(error.localizedDescription)") } }