iOS13 内购集成

简单记录。

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 
#import 

NS_ASSUME_NONNULL_BEGIN

@class SuenAppStorePay;
@protocol SuenAppStrorePayDelegate 
@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
/**商品ID*/
@property (nonatomic,strong) NSString *goodsId;
@property (nonatomic,weak) id  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 *)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 ()

//设置代理
  [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)
               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)
            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 内购集成)