美文网首页
苹果内购流程

苹果内购流程

作者: linggaozhen | 来源:发表于2018-10-31 18:46 被阅读0次

苹果内购流程

苹果现在对应用市场的审核规则越来越严格,不仅对马甲包进行大批量下架,而且对应用内的支付也有了严格的规定,凡是虚拟商品的购买都要使用苹果内购进行支付,否则应用不能被审核通过,而且苹果还要分成30%。无奈之下,只能遵循苹果的规则,毕竟是依赖它的平台进行开发的,所以苹果内购买流程是开发者必须要掌握的技能。

一、填写协议、税务和银行业务

登录苹果开发者中心网站,选择进入App Store Connect,然后点击 “协议、税务和银行业务”,按照流程填写一些基本信息


协议、税务和银行业务.png

二、添加App 内购买项目

  • 选择要添加内购项目的App


    我的App.png
  • 选择功能菜单,便可添加内购项目


    添加内购项目.png
  • 选择内购商品的类型,点击创建


    项目类型.png
  • 创建产品后,填写产品的基本信息


    A04B5140-E0D1-41EE-ADC7-EE3C61FEF2DC.png
    4FF81F75-3C39-49DC-A93C-C521CFC13B13.png
    截图,审核备注.png
  • 下面这些就是已经创建好的内购商品


    创建好的商品.png

三、添加沙箱测试员账号,在测试的环境下方便测试人员购买

  • 点击进入


    添加沙箱测试的入口.png
  • 填写账号信息,创建成功后就可以使用账号测试购买


    填写沙箱账号的信息.png

四、代码实现

支付流程

  • 从公司的服务器获取商品ID,也就是我们在开发中中心添加的内购项目的ID

  • 根据商品ID,向苹果发送请求,请求所有可买的商品

/// 获取苹果内购商品信息
    ///
    /// - Parameters:
    ///   - productId: 内购商品product_id
    ///   - completion: 内购商品SKProduct回调
    func fetchProduct(_ productId: String?, completion: @escaping CompletionResult) {
        
        guard let product_id = productId else {
            completion(Result.failure(RxSwiftMoyaError.filterError("抱歉,商品id无效")))
            return
        }
        
        // 检查用户是否允许支付
        guard SKPaymentQueue.canMakePayments() == true else {
            completion(Result.failure(RxSwiftMoyaError.filterError("检查是否允许支付功能或者该设备是否支持支付.")))
            return
        }
        
        self.completionResult = completion
        
        /// 请求商品信息
        let set: Set<String> = [product_id]
        let request = SKProductsRequest.init(productIdentifiers: set)
        request.delegate = self
        request.start()
    }
  • 在代理方法里面获取所有的可卖商品
// MARK: - 获取苹果商品对象
extension IAPService: SKProductsRequestDelegate {
    
    /// 接收苹果商品信息回调
    ///
    /// - Parameters:
    ///   - request: 请求体
    ///   - response: 返回结果
    func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
        
        let products = response.products
        guard products.count > 0, let product = products.first else {
            self.completionResult?(Result.failure(RxSwiftMoyaError.filterError("抱歉,商品信息无效!")))
            return
        }
        //将商品实体回调出去,作为发起支付时的入参
        self.completionResult?(Result.success(product))
    }
}
  • 创建票据SKPayment,将票据加入到交易队列,便可发起支付
/// 发起苹果支付
    ///
    /// - Parameter product: 苹果内购商品对象
    func purchase(_ product: SKProduct, completion: @escaping PaymentCompletionResult) {
        Logger.log(product.productIdentifier)
        
        self.paymentCompletionResult = completion
        let payment = SKPayment.init(product: product)
        SKPaymentQueue.default().add(payment)
    }
  • 在init方法中添加观察者,监听用户是否支付的各种状态
override init() {
        super.init()
     
        // 监听支付事务回调
        SKPaymentQueue.default().add(self as SKPaymentTransactionObserver)
    }
  • 监听支付的各种事物
// MARK: - 支付事物监听
extension IAPService: SKPaymentTransactionObserver {
    
    /// 当事务数组发生更改时发送(添加或状态更改)。客户端应该检查事务状态,并在适当的时候完成。
    ///
    /// - Parameters:
    ///   - queue: 支付队列
    ///   - transactions: 支付事务数组
    func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        Logger.log("")
        
        for transaction in transactions {
            Logger.log(transaction.transactionState.rawValue)
            
            switch transaction.transactionState {
            case .purchasing: // 交易事务进行中
                break
            case .purchased: // 交易完成
                
                self.handlerTransaction(transaction)
                break
            case .failed: // 交易失败
                
                self.handlerTransaction(transaction)
                break
            case .restored: // 从用户的购买历史中恢复交易
                
                self.handlerTransaction(transaction)
                break
            default:
                /// 结束支付事务
                SKPaymentQueue.default().finishTransaction(transaction)
                break
            }
        }
        
    }
    
    /// 当事务从队列中删除时被调用
    ///
    /// - Parameters:
    ///   - queue: 支付队列
    ///   - transactions: 支付事务数组
    func paymentQueue(_ queue: SKPaymentQueue, removedTransactions transactions: [SKPaymentTransaction]) {
        Logger.log("")
        
        for transaction in transactions {
            Logger.log("删除事务: \(transaction.payment.productIdentifier)")
            /// 结束该条支付事务: 否则出现弹框 您已购买此 App 内购买项目。此项目将免费恢复。
            SKPaymentQueue.default().finishTransaction(transaction)
        }
    }
    
    /// 当遇到错误时发送,同时从用户的购买历史中添加事务回到队列
    ///
    /// - Parameters:
    ///   - queue: 支付队列
    ///   - error: 错误
    func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: Error) {
        
        Logger.log(error.localizedDescription)
    }
    
    /// 当用户的购买记录的所有事务都成功地添加到队列中时被调用
    ///
    /// - Parameter queue: 支付队列
    func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
        
        Logger.log("")
    }
    
    /// 当用户从应用程序商店发起IAP购买时发送
    ///
    /// - Parameters:
    ///   - queue: 支付队列
    ///   - payment: 支付对象
    ///   - product: 商品信息
    /// - Returns: 是否发起支付
    func paymentQueue(_ queue: SKPaymentQueue, shouldAddStorePayment payment: SKPayment, for product: SKProduct) -> Bool {
        
        Logger.log(product.productIdentifier)
        return true
    }
}
  • 对监听到的支付事物进行处理
/// 自定义处理支付事务
    ///
    /// - Parameter transaction: 支付事务
    func handlerTransaction(_ transaction: SKPaymentTransaction) {
        
        let error = transaction.error as NSError?
        if error?.code == SKError.paymentCancelled.rawValue {
            
            // 用户手动取消支付
            SKPaymentQueue.default().finishTransaction(transaction)
            self.paymentCompletionResult?(Result.failure(RxSwiftMoyaError.filterError("已取消支付")))
        }else{
            
            switch transaction.transactionState {
            case .purchased, .restored:
                
                // 苹果订单校验
                self.verifyReceipt(transaction)
                break
            case .failed:
                SKPaymentQueue.default().finishTransaction(transaction)
                if let error = transaction.error as NSError? {
                    self.completionResult?(Result.failure(RxSwiftMoyaError.error(error)))
                }
                break
            default:
                
                SKPaymentQueue.default().finishTransaction(transaction)
                break
            }
        }
    }
  • 最后支付成功后,上传支付凭证到服务器

相关文章

  • 苹果内购流程

    苹果内购流程

  • 苹果内购和Apple Pay 的区别

    苹果内购 和 Apple Pay 的区别 关注苹果支付和内购也是从苹果发布打赏功能必须走“内购”流程后,引发微信以...

  • 苹果内购流程

    苹果内购流程 苹果现在对应用市场的审核规则越来越严格,不仅对马甲包进行大批量下架,而且对应用内的支付也有了严格的规...

  • 苹果内购流程

    苹果内购是指在Apple Store的应用内购买,是苹果为App内购买虚拟商品或服务提供的一套交易系统。一. 内购...

  • 苹果内购流程

    1.登录开发者中心[开发者中心链接](https://developer.apple.com)2.点击iTunes...

  • APP内购

    关于内购的介绍和如何添加内购就不在这介绍了。下面直接上内购流程以及实现 内购流程 1.向苹果请求准备卖的商品 2....

  • 内购和Apple Pay的区别

    内购 和 Apple Pay 关注苹果支付和内购也是从苹果发布打赏功能必须走“内购”流程后,引发微信以及其他直播平...

  • 内购流程

    内购流程 1.构建内购的设置,需要设置内购商品,填写银行卡信息 进入苹果官方后台配置需要内购商品的信息(包括内购的...

  • iOS-苹果内购

    网上关于苹果内购已经有无数的文章,最近刚好接触苹果内购,简单总结一下整体流程:① 苹果结算账户信息,公司信息填写(...

  • iOS 苹果内购流程

    本文参考: iOS开发之内购完全笔记 iOS开发内购全套图文教程 iOS应用程序内购/内付费(一) 代码...

网友评论

      本文标题:苹果内购流程

      本文链接:https://www.haomeiwen.com/subject/fofztqtx.html