// // SPIAPManager.swift // MoviaBox // // Created by 佳尔 on 2025/5/6. // import UIKit class SPIAPManager: NSObject { typealias CompletionHandler = ((_ finish: Bool) -> Void) ///内购模版前缀 static let IAPPrefix = "moviabox." static let manager = SPIAPManager() ///成功回调 private var completionHandler: CompletionHandler? private lazy var iapManager: JXIAPManager = { let manager = JXIAPManager() manager.delegate = self return manager }() private var orderCode: String? private var payId: String? ///恢复购买使用 ///等待恢复的数据 private var waitRestoreModel: SPWaitRestoreModel? = UserDefaults.jx_object(forKey: kSPWaitRestoreIAPDefaultsKey, class: SPWaitRestoreModel.self) as? SPWaitRestoreModel ///开始内购 func startRecharge(model: SPPayTemplateItem, shortPlayId: String? = nil, videoId: String? = nil, handler: CompletionHandler? = nil) { if let waitRestoreModel = self.waitRestoreModel { SPToast.show(text: "kToastMessage_02".localized) handler?(false) return } guard let payId = model.id else { handler?(false) return } self.completionHandler = handler self.waitRestoreModel = SPWaitRestoreModel() let productId = SPIAPManager.IAPPrefix + (model.ios_template_id ?? "") SPHUD.show() SPWalletAPI.requestCreateOrder(payId: payId, shortPlayId: shortPlayId ?? "0", videoId: videoId ?? "0") { orderModel in guard let orderModel = orderModel else { SPHUD.dismiss() self.waitRestoreModel = nil self.completionHandler?(false) return } self.orderCode = orderModel.order_code self.payId = payId self.waitRestoreModel?.payId = payId self.waitRestoreModel?.orderCode = orderModel.order_code self.iapManager.start(productId: productId, orderId: self.orderCode ?? "") } } func restore(isLoding: Bool = true, completer: ((_ isFinish: Bool) -> Void)?) { guard let waitRestoreModel = self.waitRestoreModel, let orderCode = waitRestoreModel.orderCode, let payId = waitRestoreModel.payId, let productId = waitRestoreModel.productId, let receipt = waitRestoreModel.receipt else { if isLoding { SPToast.show(text: "kToastMessage_01".localized) } return } if isLoding { SPHUD.show() } SPWalletAPI.requestVerifyOrder(orderCode: orderCode, payId: payId, productId: productId, purchaseToken: receipt) { model in if model?.status == "success" { self.waitRestoreModel = nil UserDefaults.jx_setObject(self.waitRestoreModel, forKey: kSPWaitRestoreIAPDefaultsKey) if isLoding { SPToast.show(text: "success".localized) } completer?(true) } else { // SPToast.show(text: "failure".localized) completer?(false) } if isLoding { SPHUD.dismiss() } } } } //MARK: -------------- JXIAPManagerDelegate -------------- extension SPIAPManager: JXIAPManagerDelegate { func jx_iapPaySuccess(productId: String, receipt: String, transactionIdentifier: String?) { guard let orderCode = self.orderCode, let payId = self.payId else { self.orderCode = nil self.payId = nil self.waitRestoreModel = nil self.completionHandler?(false) return } self.waitRestoreModel?.productId = productId self.waitRestoreModel?.receipt = receipt UserDefaults.jx_setObject(self.waitRestoreModel, forKey: kSPWaitRestoreIAPDefaultsKey) SPWalletAPI.requestVerifyOrder(orderCode: orderCode, payId: payId, productId: productId, purchaseToken: receipt) { model in SPHUD.dismiss() self.orderCode = nil self.payId = nil if model?.status == "success" { self.waitRestoreModel = nil UserDefaults.jx_setObject(self.waitRestoreModel, forKey: kSPWaitRestoreIAPDefaultsKey) SPToast.show(text: "success".localized) self.completionHandler?(true) } else { self.completionHandler?(false) } } } func jx_iapPayFailed(productId: String, code: JXIAPManagerCode) { self.orderCode = nil self.payId = nil self.waitRestoreModel = nil SPHUD.dismiss() if code == .noProduct { SPToast.show(text: "Invalid in-app purchase".localized) } self.completionHandler?(false) } }