// // 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 _ = 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() if model.buy_type == .coins { self.waitRestoreModel?.buyType = .coins } else if model.buy_type == .subVip { self.waitRestoreModel?.buyType = .vip } 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 isLoding { SPHUD.dismiss() } guard let model = model else { completer?(false) return } let buyType = self.waitRestoreModel?.buyType self.waitRestoreModel = nil UserDefaults.jx_setObject(self.waitRestoreModel, forKey: kSPWaitRestoreIAPDefaultsKey) if model.status == "success" { SPLoginManager.manager.userInfo?.is_vip = true if isLoding { SPToast.show(text: "success".localized) } completer?(true) if buyType == .vip { NotificationCenter.default.post(name: SPIAPManager.buyVipFinishNotification, object: nil) } } else { // SPToast.show(text: "failure".localized) completer?(false) } } } } //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 guard let model = model else { self.completionHandler?(false) return } let buyType = self.waitRestoreModel?.buyType self.waitRestoreModel = nil UserDefaults.jx_setObject(self.waitRestoreModel, forKey: kSPWaitRestoreIAPDefaultsKey) if model.status == "success" { SPLoginManager.manager.userInfo?.is_vip = true SPToast.show(text: "success".localized) self.completionHandler?(true) if buyType == .vip { NotificationCenter.default.post(name: SPIAPManager.buyVipFinishNotification, object: nil) } } 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) } } extension SPIAPManager { ///成功购买会员 @objc static let buyVipFinishNotification = NSNotification.Name(rawValue: "SPIAPManager.buyVipFinishNotification") }