//
|
// StoreTransaction.swift
|
// ExplorerProject
|
//
|
// Created by 无故事王国 on 2024/4/1.
|
// Copyright © 2024 younger_times. All rights reserved.
|
//
|
|
import SwiftyStoreKit
|
import StoreKit
|
import HandyJSON
|
|
struct PurchaseModel:HandyJSON{
|
var environment: String?
|
var receipt:PurchaseReceiptModel?
|
var status: Int = 0
|
}
|
|
struct PurchaseReceiptModel:HandyJSON{
|
var adam_id: Int = 0
|
var app_item_id: Int = 0
|
var application_version: Int = 0
|
var bundle_id: String?
|
var download_id: Int = 0
|
var in_app = [PurchageInAppModel]()
|
var original_application_version: String?
|
var original_purchase_date: String?
|
var original_purchase_date_ms: Int = 0
|
var original_purchase_date_pst: String?
|
var receipt_creation_date: String?
|
var receipt_creation_date_ms: Int = 0
|
var receipt_creation_date_pst: String?
|
var receipt_type: String?
|
var request_date: String?
|
var request_date_ms: Int = 0
|
var request_date_pst: String?
|
var version_external_identifier: Int = 0
|
}
|
|
struct PurchageInAppModel:HandyJSON{
|
|
}
|
|
struct PurchaseResultModel:HandyJSON{
|
var environment: String?
|
var receipt: PurchaseReceipt?
|
var status: Int = 0
|
}
|
|
struct PurchaseReceipt:HandyJSON{
|
var adam_id: Int = 0
|
var app_item_id: Int = 0
|
var application_version: String?
|
var bundle_id: String?
|
var download_id: Int = 0
|
var in_app = [PurchaseInAPP]()
|
var original_application_version: String?
|
var original_purchase_date: String?
|
var original_purchase_date_ms: String?
|
var original_purchase_date_pst: String?
|
var receipt_creation_date: String?
|
var receipt_creation_date_ms: String?
|
var receipt_creation_date_pst: String?
|
var receipt_type: String?
|
var request_date: String?
|
var request_date_ms: String?
|
var request_date_pst: String?
|
var version_external_identifier: Int = 0
|
}
|
|
struct PurchaseInAPP:HandyJSON{
|
var in_app_ownership_type: String?
|
var is_trial_period: String?
|
var original_purchase_date: String?
|
var original_purchase_date_ms: String?
|
var original_purchase_date_pst: String?
|
var original_transaction_id: String?
|
var product_id: String?
|
var purchase_date: String?
|
var purchase_date_ms: String?
|
var purchase_date_pst: String?
|
var quantity: String?
|
var transaction_id: String?
|
|
}
|
|
class InPurchaseManager:NSObject{
|
|
private static var _sharedInstance: InPurchaseManager!
|
private var productList = Set<String>()
|
private(set) var products = Set<SKProduct>()
|
|
@discardableResult
|
public class func instance() -> InPurchaseManager {
|
guard let instance = _sharedInstance else {
|
_sharedInstance = InPurchaseManager()
|
return _sharedInstance!
|
}
|
return instance
|
}
|
|
func setProductList(_ list:Set<String>,clouse:@escaping (Set<SKProduct>)->Void){
|
productList = list
|
|
SwiftyStoreKit.retrieveProductsInfo(list) { result in
|
if result.retrievedProducts.count > 0 {
|
InPurchaseManager._sharedInstance.products = result.retrievedProducts
|
clouse(result.retrievedProducts)
|
}
|
}
|
}
|
|
// func getIPAPrice(_ price:Int,clouse:@escaping (SKProduct)->Void){
|
// var ipaId = ""
|
// switch price {
|
// case 98: ipaId = "com.jkfitness.a.price.1"
|
// case 298:ipaId = "com.jkfitness.a.price.2"
|
// case 488:ipaId = "com.jkfitness.a.price.3"
|
// case 698:ipaId = "com.jkfitness.a.price.4"
|
// case 998:ipaId = "com.jkfitness.a.price.5"
|
// default:break
|
// }
|
//
|
// var productIds = Set<String>()
|
// productIds.insert(ipaId)
|
//
|
// InPurchaseManager.instance().setProductList(productIds) {products in
|
// if let product = products.first{
|
// clouse(product)
|
// }
|
// }
|
// }
|
|
|
func dismiss(){
|
InPurchaseManager._sharedInstance = nil
|
}
|
|
/// 购买
|
/// - Parameters:
|
/// - ID: ID值
|
/// - quantity: 购买数量
|
/// - applicationUsername: 购买用户名的唯一标识
|
class func purchaseProduct(ID:String,quantity:Int = 1,applicationUsername:String, completion: @escaping ( PurchaseResultModel) -> Void,errorClouse:@escaping (Error)->Void){
|
var purcahseProduct:SKProduct?
|
for product in _sharedInstance.products {
|
if product.productIdentifier == ID{
|
purcahseProduct = product;break
|
}
|
}
|
|
guard let product = purcahseProduct else {return}
|
var inSanbox:Bool = false
|
|
#if DEBUG
|
inSanbox = true
|
#endif
|
|
SwiftyStoreKit.completeTransactions { purchases in
|
if let product = purchases.first{
|
switch product.transaction.transactionState {
|
case .purchased:
|
alertSuccess(msg: "完成购买")
|
case .purchasing:
|
showHUD("购买中")
|
case .failed:
|
alertError(msg: "购买失败")
|
case .restored:
|
alertSuccess(msg: "恢复购买")
|
default:break
|
}
|
}
|
}
|
|
SwiftyStoreKit.purchaseProduct(product, quantity: quantity, atomically: true, applicationUsername: applicationUsername, simulatesAskToBuyInSandbox: false, paymentDiscount: nil) { result in
|
switch result {
|
case .success(let purchase):
|
var type:AppleReceiptValidator.VerifyReceiptURLType = .production
|
if inSanbox{
|
type = .sandbox
|
}
|
|
var recepit = AppleReceiptValidator(service: type, sharedSecret: nil)
|
SwiftyStoreKit.verifyReceipt(using: recepit) { result in
|
switch result {
|
case .success(let receipt):
|
if let model = PurchaseResultModel.deserialize(from: receipt){
|
completion(model)
|
}
|
break
|
case .error(let error):
|
errorClouse(error)
|
// print(error.localizedDescription)
|
}
|
}
|
case .error(let error):
|
// print(error.localizedDescription)
|
errorClouse(error)
|
}
|
}
|
}
|
|
/// 恢复购买
|
class func resotrePurchase(applicationUsername:String, completion: @escaping ( PurchaseResultModel) -> Void,errorClouse:@escaping (Error)->Void){
|
|
SwiftyStoreKit.completeTransactions { purchases in
|
if let product = purchases.first{
|
switch product.transaction.transactionState {
|
case .purchased:
|
alertSuccess(msg: "完成购买")
|
case .purchasing:
|
showHUD("购买中")
|
case .failed:
|
alertError(msg: "购买失败")
|
case .restored:
|
alertSuccess(msg: "恢复购买")
|
default:break
|
}
|
}
|
}
|
|
|
SwiftyStoreKit.restorePurchases(atomically: true, applicationUsername: applicationUsername) { result in
|
if result.restoreFailedPurchases.count > 0 {
|
//恢复失败
|
print("restore Failed:\(result.restoredPurchases)")
|
}else if result.restoredPurchases.count > 0 {
|
print("restore Success")
|
var inSanbox:Bool = false
|
|
#if DEBUG
|
inSanbox = true
|
#endif
|
var type:AppleReceiptValidator.VerifyReceiptURLType = .production
|
if inSanbox{
|
type = .sandbox
|
}
|
let recepit = AppleReceiptValidator(service: type, sharedSecret: nil)
|
SwiftyStoreKit.verifyReceipt(using: recepit) { result in
|
switch result {
|
case .success(let receipt):
|
if let model = PurchaseResultModel.deserialize(from: receipt){
|
completion(model)
|
}
|
break
|
case .error(let error):
|
errorClouse(error)
|
}
|
}
|
}else{
|
print("Nothing to Restore")
|
}
|
}
|
}
|
|
//获取APP 首次安装时间
|
// func test1(){
|
//
|
// let queue = DispatchQueue(label: "inapppurchasequeue")
|
// queue.async {
|
// let receiptURL = Bundle.main.appStoreReceiptURL
|
// guard receiptURL?.path != nil else { return }
|
// do {
|
// let receiptData = try Data(contentsOf: receiptURL!, options: .alwaysMapped)
|
// let base64EncodedReceipt = receiptData.base64EncodedString(options: [])
|
// var verifyReceipt:String = AppleReceiptValidator.VerifyReceiptURLType.sandbox.rawValue
|
//#if !DEBUG
|
// verifyReceipt = AppleReceiptValidator.VerifyReceiptURLType.production.rawValue
|
//#endif
|
// let purchaseURL = URL(string: verifyReceipt)!
|
//
|
// var request = URLRequest(url: purchaseURL)
|
// request.httpMethod = "POST"
|
// request.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
//
|
// let jsonBody: [String: Any] = [
|
// "receipt-data": base64EncodedReceipt,
|
// "password": ShareAppleKey // 你的共享密钥
|
// ]
|
//
|
// let jsonData = try JSONSerialization.data(withJSONObject: jsonBody, options: [])
|
// request.httpBody = jsonData
|
//
|
// let session = URLSession.shared
|
// let task = session.dataTask(with: request) { (data, response, error) in
|
// if let error = error {return}
|
// guard let data = data else { return }
|
// do {
|
// if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
|
// print(json)
|
// if let purchageModel = PurchaseModel.deserialize(from: json),purchageModel.status == 0{
|
//
|
// }
|
// }
|
// } catch {
|
// print("JSON processing failed: \(error)")
|
// }
|
// }
|
// task.resume()
|
// } catch {
|
// print("Error reading receipt data: \(error)")
|
// }
|
// }
|
// }
|
}
|