iOS13 内购集成

作者: 一个七 | 来源:发表于2020-03-26 17:13 被阅读0次

    简单记录。

    1.协议填写
    登录苹果商店中心直达链接选择协议条款填写信息。

    step1
    step2
    进去填写资料即可,具体填写可参考[Lebus的文章]

    2.创建商品
    进入我的App-功能-App内购买项目-点击加号
    添加内购商品
    选择对应的商品
    image.png
    ps:作者项目用到的是会员功能,选择的是非续期订阅,多次购买会提示续订或延长订阅时间达到续费的目的
    IMG_0823.PNG
    具体创建商品设置
    image.png
    image.png 上传你购买商品的截图

    以上配置工程基本完成

    未完成部分
    1.工程中开启内购功能

    Xcode11中点击 +Capablility 添加
    2.沙盒账号添加(用于付款)
    image.png
    国家选自己应用的地区!
    ps:1.不用退出手机设置中的APPID,内购时系统检测到沙盒环境(个人猜测)自动弹出登录框登录并保存沙盒账号,输入沙盒账号密码即可
    2.退出沙盒账号。设置-APPID-iTunes Store 与 App Store - 最底部就可以看到沙盒账户,点击对应账户就有退出登录选项
    退出沙盒账户

    实现APP内购买功能(代码部分)

    头文件部分

    
    #import <Foundation/Foundation.h>
    #import <StoreKit/StoreKit.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @class SuenAppStorePay;
    @protocol SuenAppStrorePayDelegate <NSObject>
    @optional
    
    /// 内购支付成功回调
    /// @param appStorePay 当前类
    /// @param transaction 返回值
    -(void)SuenAppStorePay:(SuenAppStorePay *)appStorePay responseAppStorePaySuccess:(SKPaymentTransaction *)transaction;
    
    
    /// 内购支付结果回调提示
    /// @param appStorePay 当前类
    /// @param transaction 返回值
    - (void)SuenAppStorePay:(SuenAppStorePay *)appStorePay responseAppStorePayStatusshow:(SKPaymentTransaction *)transaction;
    @end
    
    @interface SuenAppStorePay : NSObject<SKPaymentTransactionObserver,SKProductsRequestDelegate>
    /**商品ID*/
    @property (nonatomic,strong) NSString *goodsId;
    @property (nonatomic,weak) id <SuenAppStrorePayDelegate> delegate;
    +(instancetype)sharedInstance;
    
    /// 购买商品
    /// @param goodsID 商品ID
    -(void)starBuyToAppStore:(NSString *)goodsID;
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    

    实现文件

    #import "SuenAppStorePay.h"
    
    @implementation SuenAppStorePay
    +(instancetype)sharedInstance{
        static SuenAppStorePay *s;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken,^{
            s = [[SuenAppStorePay alloc]init];
        });
        
        return s;
    }
    -(instancetype)init{
        
        self = [super init];
        if (self) {
            [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
        }
        return self;
    }
    
    
    #pragma mark -释放TransactionObserver
    -(void)dealloc{
        [[SKPaymentQueue defaultQueue]removeTransactionObserver:self];
    }
    #pragma mark -购买商品
    -(void)starBuyToAppStore:(NSString *)goodsID{
    //    判断是否开启支付功能
        if ([SKPaymentQueue canMakePayments]) {
            [self getRequestAppleProduct:goodsID];
        }else{
    //提示开启支付功能
            [FRObj showAlert:@"请开启支付功能" time:1];
        }
    }
    #pragma makr -private 购买方法
    -(void)getRequestAppleProduct:(NSString *)goodsID{
        self.goodsId = goodsID;
        SKProductsRequest *request = [[SKProductsRequest alloc]initWithProductIdentifiers:[NSSet setWithObject:goodsID]];
        request.delegate = self;
        [request start];
    }
    
    #pragma mark -SKProductsRequestDelegate
    -(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
        SKProduct *product = nil;
        if (response.products.count > 0) {
            for (SKProduct *s in response.products) {
                if ([s.productIdentifier isEqualToString:self.goodsId]) {
                    product = s;
                }
            }
            if (product) {
    //            发送购买请求
                SKPayment *payment = [SKPayment paymentWithProduct:product];
                [[SKPaymentQueue defaultQueue] addPayment:payment];
            }
            
        }else{
    //        结束加载视图
            NSLog(@"没有这个产品");
            return;
        }
    }
    
    -(void)request:(SKRequest *)request didFailWithError:(NSError *)error{
    //    请求产品失败
        NSLog(@"请求产品失败");
    }
    -(void)requestDidFinish:(SKRequest *)request{
        //    请求产品结束
    }
    
    -(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions{
    //    购买状态
        if (self.delegate && [self.delegate respondsToSelector:@selector(SuenAppStorePay:responseAppStorePayStatusshow:)]) {
            if (transactions.count != 0) {
                SKPaymentTransaction *transaction = transactions[0];
                [self.delegate SuenAppStorePay:self responseAppStorePayStatusshow:transaction];
            }
          
        }
        
        for (SKPaymentTransaction *transaction in transactions) {
            switch (transaction.transactionState) {
                case SKPaymentTransactionStatePurchased:
                    [self completeTransaction:transaction];
    //                交易完成
                    break;
                case SKPaymentTransactionStateRestored:
    //                 购买过
                    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                    break;
                case SKPaymentTransactionStateFailed:
    //                  交易失败
                    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
    
                    break;
                    
                default:
                    break;
            }
        }
        
        
        
    }
    #pragma mark ------ 支付完成
    - (void)completeTransaction:(SKPaymentTransaction *)transaction{
        
        
    //    [transaction transactionIdentifier];
        if (self.delegate && [self.delegate respondsToSelector:@selector(SuenAppStorePay:responseAppStorePaySuccess:)]) {
    
            [self.delegate SuenAppStorePay:self responseAppStorePaySuccess:transaction];
         }
        
        
        [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
    
    }
    
    @end
    

    使用方法

    @interface YourViewController ()<SuenAppStrorePayDelegate>
    
    //设置代理
      [SuenAppStorePay sharedInstance].delegate = self;
    //出入商品ID
      [[SuenAppStorePay sharedInstance] starBuyToAppStore:goodsId];
    
    
    #pragma mark -SuenAppStorePayDelegate
    -(void)SuenAppStorePay:(SuenAppStorePay *)appStorePay responseAppStorePayStatusshow:(SKPaymentTransaction *)transaction{
    //    状态回调
        switch (transaction.transactionState) {
            case SKPaymentTransactionStateFailed:
                NSLog(@"取消或失败");
                break;
            case SKPaymentTransactionStateRestored:
                NSLog(@"从用户的购买历史中恢复。客户应完成交易");
                break;
            default:
                break;
        }
    }
    
    -(void)SuenAppStorePay:(SuenAppStorePay *)appStorePay responseAppStorePaySuccess:(SKPaymentTransaction *)transaction {
        //支付完成,需要二次验证的在此操作(后台大佬不搞二次验证,苹果不建议APP内验证故没做)
     
    }
    

    Swift 简单版

    
    import UIKit
    import StoreKit
    //Block模式
    typealias SuenStorePayStatusBlock = (_ transaction :SKPaymentTransaction) ->(Void)
    typealias SuenStorePaySuccessBlock = (_ transaction :SKPaymentTransaction) ->(Void)
    
    //代理模式
    protocol SuenIAPPayDelegate : NSObjectProtocol {
        func SuenAppStorePayStatus(iapPay: SuenIAPPay,transaction: SKPaymentTransaction)
        func SuenAppStorePaySuccess(iapPay: SuenIAPPay,transaction: SKPaymentTransaction)
    
    }
    
    class SuenIAPPay: NSObject,SKPaymentTransactionObserver,SKProductsRequestDelegate {
       
        
        /// 商品id
        var goodsId : String?
        
        /// 代理
        static weak var delegate : SuenIAPPayDelegate?
    
      //Block
        var statusBlock : SuenStorePayStatusBlock?
        var successBlock : SuenStorePaySuccessBlock?
    
        
        /// 单例
        static let su : SuenIAPPay = {
            let instance = SuenIAPPay()
            SKPaymentQueue.default().add(instance)
            return instance
        }()
    
    
      
        /// 实例购买方法
        /// - Parameter goodsId: 商品id
        func buyToAppStore(goodsId: String){
               if SKPaymentQueue.canMakePayments() {
                   self.goodsId = goodsId
                   let set = NSSet.init(object: goodsId)
                   let productsRequest = SKProductsRequest.init(productIdentifiers: set as! Set<String>)
                   productsRequest.delegate = self
                   productsRequest.start()
                   
               }else {
                   print("请开启支付功能")
               }
    
           }
        
        
          /// 购买
          /// - Parameter goodsId: 商品id
        class func starBuyToAppStore(goodsId: String){
            if SKPaymentQueue.canMakePayments() {
                su.goodsId = goodsId
                let set = NSSet.init(object: goodsId)
                let productsRequest = SKProductsRequest.init(productIdentifiers: set as! Set<String>)
                productsRequest.delegate = su
                productsRequest.start()
                
            }else {
                print("请开启支付功能")
            }
    
        }
          
          
          /// 支付完成
          /// - Parameter transaction: 购买的产品
        func completeTransaction(transaction: SKPaymentTransaction){
            
            if (SuenIAPPay.delegate != nil) {
                SuenIAPPay.delegate?.SuenAppStorePaySuccess(iapPay: self, transaction: transaction)
            }
            SKPaymentQueue.default().finishTransaction(transaction)
        }
     
        ///SKPaymentTransactionObserver
        func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
    
            if transactions.count > 0 {
                SuenIAPPay.delegate?.SuenAppStorePayStatus(iapPay: SuenIAPPay.su, transaction: transactions[0])
            }
            
            
            for transaction in transactions {
                switch transaction.transactionState {
                case .purchased:
    //                交易完成
                    self.completeTransaction(transaction: transaction)
                    break;
                case .restored:
    //                购买过
                    SKPaymentQueue.default().finishTransaction(transaction)
                    break
                case .failed:
    //                失败
                    SKPaymentQueue.default().finishTransaction(transaction)
    
                    break
                default: break
                    
                }
            }
            
            
        }
        ///SKProductsRequestDelegate
        func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
            if response.products.count > 0 {
                var product : SKProduct?
                for s in response.products {
                    if s.productIdentifier  == SuenIAPPay.su.goodsId  || s.productIdentifier  == self.goodsId{
                        product = s
                    }
                }
                if (product != nil) {
                    let payment = SKPayment.init(product: product!)
                    SKPaymentQueue.default().add(payment)
                }
       
            }else{
                print("没有这个产品")
            }
        }
        
        func requestDidFinish(_ request: SKRequest) {
    //        请求产品完成
        }
        func request(_ request: SKRequest, didFailWithError error: Error) {
    //        请求失败
        }
    
    }
    
    

    使用

    
    import UIKit
    import StoreKit
    class ViewController: UIViewController,SuenIAPPayDelegate {
        let suenIap = SuenIAPPay()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    /*
    单例购买
            SuenIAPPay.delegate = self
            SuenIAPPay.starBuyToAppStore(goodsId: "goods123")
    */
    
    //实例购买(Block)
         suenIap.buyToAppStore(goodsId: "bdymember01")
            suenIap.statusBlock = {(_ tr : SKPaymentTransaction) in
               print("状态回调")
            }
            suenIap.successBlock = {(_ tr : SKPaymentTransaction) in
              print("购买成功")
            }
    
            // Do any additional setup after loading the view.
        }
    
    //    TODO:状态
        func SuenAppStorePayStatus(iapPay: SuenIAPPay, transaction: SKPaymentTransaction) {
        }
        
    //    TODO:交易完成
        func SuenAppStorePaySuccess(iapPay: SuenIAPPay, transaction: SKPaymentTransaction) {
        }
    
    }
    

    相关文章

      网友评论

        本文标题:iOS13 内购集成

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