//import StoreKit@objcMembers public class FastApplePay: NSObject, SKPaymentTransactionObserver, SKProductsRequestDelegate {public static let shared = FastApplePay()public typealias FastApplePayBlock = (FastApplePayState,String?,String?)->Voidpublic enum FastApplePayState :String{case start = "商品开始购买"case success = "商品购买成功"case failed = "商品购买失败"case productContent = "商品信息列表获取失败"case payFailed = "商品支付失败"case cancel = "用户取消交易"case error = "商品交易失败"case catchError = "后台验证接口崩溃"case end = "商品交易完成"case transactionEnd = "扣款成功"case guaJiePayURLError = "挂接中心回调地址请求失败"}/**回调*/var callBack:FastApplePayBlock?/**商品ID*/var gamebuyGoodId:String?/**服务器回调地址*/var gamePayCallbackUrl:String?/**订单号*/var gameAppPayIdentifier:String?/**商品*/var product:SKProduct?/**服务器验证字典参数*/var userPayParame:Dictionary<String,Any>?var productList:Array<Dictionary<String,Any>> = [] // 商品列表var isGetProductList = false // 是否是获取商品列表信息var productListCallBack:FastStrBlock? // 商品列表回调/**购买商品*/public func buyProduct(param:Dictionary<String,Any>,blcok:@escaping FastApplePayBlock) {self.callBack = blcokself.isGetProductList = falseprint(param)if let gamebuyGoodId = param.string("productId"),let gamePayCallbackUrl = param.string("notify_url") {self.gamePayCallbackUrl = gamePayCallbackUrlself.gamebuyGoodId = gamebuyGoodIduserPayParame = param.value("data") as? Dictionary<String,Any>if SKPaymentQueue.canMakePayments(){let productsRequest = SKProductsRequest(productIdentifiers: [gamebuyGoodId])productsRequest.start()productsRequest.delegate = selfcallBack(.start, orderid: nil, desc:nil)}else{FastLog.error("无法支付-----")print("无法支付-----")}}else{FastLog.error("参数错误")print("参数错误")}}/**支付状态回调*/func callBack(_ state:FastApplePayState,orderid:String?,desc:String?){self.callBack?(state,orderid,desc)}/**成功处理*/func completeTransaction(transaction: SKPaymentTransaction){if let gamePayCallbackUrl = self.gamePayCallbackUrl,let gameAppPayIdentifier = transaction.transactionIdentifier,let url = Bundle.main.appStoreReceiptURL{if let data = try? Data(contentsOf: url) {// 凭证let receipt = data.base64EncodedString(options: .endLineWithLineFeed)userPayParame?["transaction_id"] = gameAppPayIdentifierFastNetWorking.shared.post(inUrl: gamePayCallbackUrl, parameDic: userPayParame, receipt) {[weak self] suc inprint("status:\(suc.dic?.value(Int.self,"status"))")//判断服务器凭证验证状态if let status = suc.dic?.value(Int.self,"status"){if status != 1{self?.callBack(.payFailed, orderid: gameAppPayIdentifier, desc: suc.dic?.string("msg"))return}SKPaymentQueue.default().finishTransaction(transaction)self?.callBack(.end, orderid: gameAppPayIdentifier, desc: suc)}else{self?.callBack(.payFailed, orderid: gameAppPayIdentifier, desc: suc.dic?.string("msg"))}} fai: {[weak self] str inself?.callBack(.payFailed, orderid: gameAppPayIdentifier, desc: str)}}else{callBack(.payFailed, orderid: nil, desc: nil)}}else{callBack(.payFailed, orderid: nil, desc: nil)}}/**失败处理*/func failedTransaction(transaction: SKPaymentTransaction){if let err:SKError = transaction.error as? SKError {if err.code == SKError.Code.paymentCancelled{ //交易取消callBack(.cancel, orderid: nil, desc: nil)}else{//购买失败callBack(.failed, orderid: nil, desc: nil)}}SKPaymentQueue.default().finishTransaction(transaction)}// MARK: 商品信息回调public func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {print("商品信息回调 response.products = \(response.products)")FastLog.debug(response.products)if response.products.count > 1{if self.isGetProductList{self.callBackProductList(list: response.products)}}else{if let product = response.products.first {print("Product title: \(product.localizedTitle)")print("Product description: \(product.localizedDescription)")print("Product price: \(product.price)")print("Product productIdentifier: \(product.productIdentifier)")print("Product priceLocale: \(product.priceLocale)")print("地区编码: \(product.priceLocale.identifier)")print("货币代码: \(String(describing: product.priceLocale.currencyCode))")print("货币符号: \(String(describing: product.priceLocale.currencySymbol))")if #available(iOS 16, *) {FastLog.log("地区语言: \(product.priceLocale.language)")} else {// Fallback on earlier versions}self.product = product// 发起请求let payment = SKPayment(product: self.product!)SKPaymentQueue.default().add(payment)SKPaymentQueue.default().add(self)}else{print("商品信息列表获取失败 response.products = \(response.products)")//商品信息列表获取失败callBack(.productContent, orderid: nil, desc: nil)}}}// MARK: 失败执行的方法public func request(_ request: SKRequest, didFailWithError error: Error) {callBack(.error, orderid: nil, desc: nil)print("货币符号error: \(error)")}// MARK: 购买完成public func requestDidFinish(_ request: SKRequest) {callBack(.success,orderid: gamebuyGoodId,desc: nil)}// MARK: - SKPaymentTransactionObserverpublic func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {for transaction in transactions {FastLog.debug(transaction.transactionState)switch transaction.transactionState {case .purchased:FastLog.debug("purchased")// 交易完成completeTransaction(transaction: transaction)callBack(.transactionEnd, orderid: nil, desc: nil)breakcase .failed:FastLog.debug("failed")// 处理购买失败的逻辑failedTransaction(transaction: transaction)breakcase .restored:FastLog.debug("restored")// 处理购买或恢复购买的逻辑queue.finishTransaction(transaction)default:break}}}/// 查询苹果是否有需要补单的订单/// - Returns: 结果public func selectPayDropOrder() -> Bool{if SKPaymentQueue.default().transactions.count > 0{return true}else{return false}}/// 返回掉单支付所有订单对象/// - Returns: 结果public func allTransaction() -> Array<SKPaymentTransaction>{return SKPaymentQueue.default().transactions}public func getLocalInfo(productList:String,callBack:@escaping FastStrBlock){self.productListCallBack = callBackself.isGetProductList = trueif let dic = productList.dic{if let arr = dic.value(Array<Dictionary<String,Any>>.self, "product_list"){var productIds:Set<String> = []for product in arr{if let data:Dictionary<String,Any> = product as? Dictionary<String, Any>{self.productList.append(data)if let product_id = data.string("product_id"){productIds.insert(product_id)}}}if productIds.count > 0{let productsRequest = SKProductsRequest(productIdentifiers: productIds)productsRequest.delegate = selfproductsRequest.start()print("productId start .. ")}else{print("productIds 为空 直接返回JSON数据\(productList)")callBack(productList)}}else{print("productList JSON解析错误 直接返回JSON数据\(productList)")callBack(productList)}}else{FastLog.debug("productList JSON解析错误 直接返回JSON数据\(productList)")callBack(productList)}}func callBackProductList(list:Array<SKProduct>){var newProductList:Array<Dictionary<String,Any>> = []for product in list{print("新商品列表 product = \(product)")for data in self.productList{print("新商品列表 data = \(data)")if product.productIdentifier == data.string("product_id"){var newData = datanewData["local"] = ["price":product.price,"currencyCode":product.priceLocale.currencyCode ?? "","title":product.localizedTitle,]newProductList.append(newData)}}}self.productListCallBack?(["product_list":newProductList].json)} }