前段时间做了点内购的东西,记录一下内购流程,对于丢单的处理留到下一篇再记录,本次先不考虑丢单的情况。开发者中心设置税务财务就不记了,直接上代码逻辑。
先来看下内购的流程图:
image
在此我默认内购的商品已经在开发者中心配置好,服务端也已经同步。
大概流程就是:
1.选择某个商品,客户端向服务端发起请求生成一个订单号,存到本地。
2.客户端向苹果发起支付请求,苹果处理支付请求,将成功或者失败返回给客户端。
3.如果苹果返回给客户端支付成功的话,会同时返回一个支付凭证,客户端需要把这个支付凭证和第一步生成的订单号回传给服务端,由服务端向APPLE验证支付的合法性,完成订单状态的最终修改。
首先要导入用于内购的框架:
import StoreKit
配置获取支付凭证的地址,分为正式环境和沙盒环境:
//沙盒测试环境验证
let SANDBOX = "https://sandbox.itunes.apple.com/verifyReceipt"
//正式环境验证
let AppStore = "https://buy.itunes.apple.com/verifyReceipt"
首先要声明一个SKProductsRequestDelegate和一个SKPaymentTransactionObserver,前者是获取商品详情的代理,后者是支付状态观察者的回调。
声明两个全局变量:
/**
当前购买任务
*/
private var currentTransaction:SKPaymentTransaction?
/**
商品对象
*/
private var myProduct:SKProduct?
判断是否支持支付:
override init() {
super.init()
if SKPaymentQueue.canMakePayments(){
SKPaymentQueue.default().add(self)//添加观察者
}else{
debugPrint("用户禁止应用内购买,操作失败!")
}
}
根据商品id请求商品详情,这个id是在开发者后台配置好的.
//MARK:- ==== 请求商品
func requestProductWithId(productId:String)->Bool {
if productId.count > 0{
debugPrint("商品id:\(productId)")
let productRequest = SKProductsRequest.init(productIdentifiers: [productId])//向苹果发送请求,请求所有可买的商品
productRequest.delegate = self
productRequest.start()
return true
}else{
return false
}
}
//MARK:-发起购买商品
func purchaseProduct(skProduct:SKProduct)->Bool{
if SKPaymentQueue.canMakePayments(){
debugPrint("发起购买")
let payment = SKPayment.init(product: skProduct)// 1.创建票据
SKPaymentQueue.default().add(payment)// 2.将票据加入到交易队列
return true
}else{
debugPrint("用户禁止应用内购买,操作失败!")
return false
}
}
实现支付状态回调的代理方法
//MARK: - == SKPaymentTransactionObserver Delegate ==
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction in transactions {
debugPrint("identifer:\(String(describing: transaction.transactionIdentifier))")
switch transaction.transactionState{
case .purchasing://商品添加进列表
debugPrint("商品 \(transaction.payment.productIdentifier) 被添加进购买列表")
break
case .purchased://交易成功
debugPrint("购买成功")
self.completeTransaction(transaction: transaction)
break
case .failed://交易失败
debugPrint("交易失败")
self.failedTransaction(transaction: transaction)
break
case .restored://已购买过该商品
debugPrint("已购买过该商品")
queue.finishTransaction(transaction)
break
case .deferred://交易延迟
debugPrint("交易延迟")
break
}
}
}
获取支付凭证
//MARK: - ================ Private Methods =================
func completeTransaction(transaction:SKPaymentTransaction){
// 验证凭据,获取到苹果返回的交易凭据
// appStoreReceiptURL iOS7.0增加的,购买交易完成后,会将凭据存放在该地址
let recioptUrl = Bundle.main.appStoreReceiptURL
do{
let receiptData = try Data.init(contentsOf: recioptUrl!, options: Data.ReadingOptions.alwaysMapped)
}catch{
debugPrint("requestDidFinish出错!")
}
self.currentTransaction = transaction
}
func failedTransaction(transaction:SKPaymentTransaction){
if (transaction.error != nil) {
}
SKPaymentQueue.default().finishTransaction(transaction)
self.currentTransaction = transaction
}
deinit {
SKPaymentQueue.default().remove(self)
}
//MARK:-结束当前交易
func finishTransaction(){
SKPaymentQueue.default().finishTransaction(self.currentTransaction!)
}
网友评论