iOS内购支付

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
//
  
 
import StoreKit
 
@objcMembers public class FastApplePay: NSObject, SKPaymentTransactionObserver, SKProductsRequestDelegate {
     
    public static let shared = FastApplePay()
     
    public typealias FastApplePayBlock = (FastApplePayState,String?,String?)->Void
     
    public 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 = blcok
        self.isGetProductList = false
        print(param)
        if let gamebuyGoodId = param.string("productId"),let gamePayCallbackUrl = param.string("notify_url") {
            self.gamePayCallbackUrl = gamePayCallbackUrl
            self.gamebuyGoodId = gamebuyGoodId
            userPayParame = param.value("data") as? Dictionary<String,Any>
            if SKPaymentQueue.canMakePayments(){
                let productsRequest = SKProductsRequest(productIdentifiers: [gamebuyGoodId])
                productsRequest.start()
                productsRequest.delegate = self
                callBack(.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"] = gameAppPayIdentifier
                 
                FastNetWorking.shared.post(inUrl: gamePayCallbackUrl, parameDic: userPayParame, receipt) {[weak self] suc in
                     
                    print("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 in
                    self?.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: - SKPaymentTransactionObserver
    public 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)
                break
            case .failed:
                FastLog.debug("failed")
                // 处理购买失败的逻辑
                failedTransaction(transaction: transaction)
                break
            case .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 = callBack
        self.isGetProductList = true
        if 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 = self
                    productsRequest.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 = data
                    newData["local"] = ["price":product.price,
                                        "currencyCode":product.priceLocale.currencyCode ?? "",
                                        "title":product.localizedTitle,
                    ]
                    newProductList.append(newData)
                }
            }
        }
        self.productListCallBack?(["product_list":newProductList].json)
         
    }
}

 

posted @   super1250  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
点击右上角即可分享
微信分享提示