美文网首页
iOS-应用内购买看

iOS-应用内购买看

作者: 那C乱我心 | 来源:发表于2019-03-20 17:50 被阅读0次

    第一步,准备工作

    1、写代码之前,一定要阅读苹果的《APP内购买项目》文档
    2、在iTunes connect后台配置项目的内容,这里就不在多写了。

    第二步,代码部分

    1.判断用户是否开启内购,代码如下

        //有支付行为的时候开启,监听支付结果
       [[SKPaymentQueue defaultQueue]addTransactionObserver:self];
    
       if ([SKPaymentQueue canMakePayments]) {
            [SVProgressHUDManager showLoding:@"创建订单中"];
            //在这里找服务器创建订单
         
        }else{
            [SVProgressHUDManager showToast:@"购买失败"];
        }
    

    3.拿到订单号后去苹果那里查询商品ID,商品ID在iTunes Connect里设置过了

             //productID为iTunes Connect里的商品ID
            NSArray *product = [[NSArray alloc] initWithObjects:self.productID,nil];
            NSSet *nsset = [NSSet setWithArray:product];
            SKProductsRequest *request = [[SKProductsRequest alloc]initWithProductIdentifiers:nsset];
            request.delegate = self;
            [request start];
    

    查询的结果将通过SKProductsRequestDelegate得到查询的结果,代理方法如下:

    //查询成功返回
    - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
        NSArray *product = response.products;
        if (product.count == 0) {
            [SVProgressHUDManager dismissHUD];
            [SVProgressHUDManager showToast:@"购买失败"];
            return;
        }
        SKProduct *prod = nil;
        for (SKProduct *pro in product) {
            if ([pro.productIdentifier isEqualToString:self.productID]) {
                prod = pro;
            }
        }
        //查询成功发送购买请求
        if (prod != nil) {
            SKPayment *payment = [SKPayment paymentWithProduct:prod];
            [[SKPaymentQueue defaultQueue] addPayment:payment];
        }
    }
    
    // 请求失败回调,如果请求失败,在这里处理一下
    - (void)request:(SKRequest *)request didFailWithError:(NSError *)error{
        [SVProgressHUDManager dismissHUD];
        [SVProgressHUDManager showToast:@"购买失败"];
    }
    
    // 请求成功回调
    - (void)requestDidFinish:(SKRequest *)request{
        [SVProgressHUDManager dismissHUD];
    }
    

    4、监听支付成功或者失败的方法

    // 监听购买结果
    - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions{
        for (SKPaymentTransaction *tran in transactions) {
            switch (tran.transactionState) {
                case SKPaymentTransactionStatePurchased:
                    NSLog(@"购买成功");
                    //本地进行进行校验
                    //[self verifyPurchaseWithPaymentTransactionWith:tran];
                    //服务端进行校验
                    [self requestWithApplePay];
                    [[SKPaymentQueue defaultQueue] finishTransaction:tran];
                    break;
                case SKPaymentTransactionStatePurchasing:
                    NSLog(@"商品添加进列表");
                    break;
                case SKPaymentTransactionStateRestored:
                    NSLog(@"已经购买过商品");
                    [[SKPaymentQueue defaultQueue] finishTransaction:tran];
                    break;
                case SKPaymentTransactionStateFailed:
                    NSLog(@"购买失败");
                    [[SKPaymentQueue defaultQueue] finishTransaction:tran];
                    [SVProgressHUDManager showToast:@"购买失败"];
                    break;
                default:
                    [[SKPaymentQueue defaultQueue] finishTransaction:tran];
                    break;
            }
        }
    }
    
    

    5、校验
    当SKPaymentTransactionStatePurchased时,也就是支付成功的时候,要进行订单校验,这个一般都放在服务器,我们支付成功,告诉服务器,服务器去校验的同时也能更新服务器端用户数据
    服务器校验就不在多说,这里说下本地校验

    本地校验这里要多说一句:

    进行网络检验的时候,开始的时候用的程序里封装的AF进行网络校验,一直反馈21002,后来发现可以通过设置

    [AFHTTPSessionManager manager].responseSerializer.acceptableContentTypes 解决,但是要改全局设置,不方便

    直接用下面代码块的请求就解决了

    #ifdef DEBUG //测试阶段
    #define ApplePay_Check @"https://sandbox.itunes.apple.com/verifyReceipt"
    #else //发布阶段
    #define ApplePay_Check @"https://buy.itunes.apple.com/verifyReceipt"
    #endif
    //购买成功,本地校验
    -(void)verifyPurchaseWithPaymentTransactionWith:(SKPaymentTransaction *)tran{
        //从沙盒中获取交易凭证并且拼接成请求体数据
        NSURL *receiptUrl=[[NSBundle mainBundle] appStoreReceiptURL];
        NSData *receiptData=[NSData dataWithContentsOfURL:receiptUrl];
        NSString *receiptString = [receiptData base64EncodedStringWithOptions:0];
        
        if ([CommonTools isNullWithString:receiptString]) {
            return;
        }
        
        NSError *error;
        NSDictionary *requestContents = @{
                                          @"receipt-data":receiptString
                                          };
        NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents
                                                              options:0
                                                                error:&error];
        // Create a POST request with the receipt data.
        NSURL *storeURL = [NSURL URLWithString:ApplePay_Check];
        NSMutableURLRequest *storeRequest = [NSMutableURLRequest requestWithURL:storeURL];
        [storeRequest setHTTPMethod:@"POST"];
        [storeRequest setHTTPBody:requestData];
        NSOperationQueue *queue = [[NSOperationQueue alloc] init];
        [NSURLConnection sendAsynchronousRequest:storeRequest queue:queue
                               completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
            if (connectionError) {
               /* ... Handle error ... */
            } else {
               NSError *error;
               NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
               if (!jsonResponse) { /* ... Handle error ...*/ }
               /* ... Send a response back to the device ... */
            }
        }];
    
    }
    

    5、最后一步

    - (void)dealloc {
            [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
    }
    

    最后,杂谈

    关于沙盒账号的问题,推荐一篇
    https://www.jianshu.com/p/1ef61a785508
    我过程中遇到原来设置的测试员一直不能用的问题,删除重新加入就行了。

    最后,希望这篇文章能对各位带来帮助。

    相关文章

      网友评论

          本文标题:iOS-应用内购买看

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