苹果内购相关内容整理

第一步:iTunesConnect的《协议税务和银行业务》里填写好银行卡信息和公司地址等信息

第二步:如果是已上架APP直接在“我的APP”->“功能”页面创建APP内购项目,未上架或者未创建APP项目请先自行创建并配置APP证书

第三步:代码部分

//******判断是否允许内购******//

if ([SKPaymentQueue canMakePayments]) {
        [MBProgressHUD showMessage:LELocalizedString(@"正在加载。。。", nil)];

    NSLog(@"允许程序内付费购买");
        [self RequestProductData];//去苹果服务器请求商品
       
    }
    else
    {
        NSLog(@"不允许程序内付费购买");
        UIAlertView *alerView =  [[UIAlertView alloc] initWithTitle:LELocalizedString(@"提示", nil)
                                                            message:LELocalizedString(@"您的手机没有打开程序内付费购买", nil)
                                                           delegate:nil cancelButtonTitle:LELocalizedString(@"关闭",nil) otherButtonTitles:nil];
        
        [alerView show];
        
    }

//******去苹果服务器请求商品******//

-(void)RequestProductData
{
    NSLog(@"---------请求对应的产品信息------------");
    NSArray *product = nil;
    switch (buyType) {
        case 0:
            product=[[NSArray alloc] initWithObjects:ProductID_IAP0p6,nil];//ProductID_IAP0p6 产品ID常量
            break;
        case 1:
            product=[[NSArray alloc] initWithObjects:ProductID_IAP1p18,nil];
            break;
        default:
            break;
    }
    NSSet *nsset = [NSSet setWithArray:product];
    SKProductsRequest *request=[[SKProductsRequest alloc] initWithProductIdentifiers: nsset];
    request.delegate=self;
    [request start];
    
}

//******SKProductsRequest请求协议 收到的产品返回信息******//
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
   
    NSLog(@"-----------收到产品反馈信息--------------");
    NSArray *myProduct = response.products;
    
//    NSLog(@"产品Product ID:%@",response.invalidProductIdentifiers);
//    NSLog(@"产品付费数量: %d", (int)[myProduct count]);
    
    if([myProduct count] == 0){
        [MBProgressHUD hideHUD];
        NSLog(@"--------------没有商品------------------");
        return;
    }
    
    
    // populate UI
    NSString *currentProId;
    switch (buyType) {
        case 0:
            currentProId = ProductID_IAP0p6;
            break;
        case 1:
            currentProId = ProductID_IAP1p18;
            break;
        default:
            break;
    }

    SKProduct *p = nil;
    for(SKProduct *product in myProduct){
//        NSLog(@"product info");
//        NSLog(@"SKProduct 描述信息%@", [product description]);
//        NSLog(@"产品标题 %@" , product.localizedTitle);
//        NSLog(@"产品描述信息: %@" , product.localizedDescription);
//        NSLog(@"价格: %@" , product.price);
        _productPrice = [product.price integerValue];
//        NSLog(@"Product id: %@" , product.productIdentifier);
        
        if([product.productIdentifier isEqualToString:currentProId]){
            p = product;
        }
        
    }

    SKPayment *payment = [SKPayment paymentWithProduct:p];
    
    NSLog(@"---------发送购买请求------------");
    [[SKPaymentQueue defaultQueue] addPayment:payment];
    
}
//******请求失败******//
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error{
    [MBProgressHUD hideHUD];
    NSLog(@"-------弹出错误信息----------");
    UIAlertView *alerView =  [[UIAlertView alloc] initWithTitle:LELocalizedString(@"Alert",NULL) message:[error localizedDescription]
                                                       delegate:nil cancelButtonTitle:LELocalizedString(@"Close",nil) otherButtonTitles:nil];
    [alerView show];
    
}

-(void) requestDidFinish:(SKRequest *)request
{
    [MBProgressHUD hideHUD];
    NSLog(@"----------反馈信息结束--------------");
    
}

//SKPaymentTransactionObserver 千万不要忘记绑定,代码如下:
//----监听购买结果
//[[SKPaymentQueue defaultQueue] addTransactionObserver:self];

//******监听购买结果******//
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
    NSLog(@"-----paymentQueue--------");
    for (SKPaymentTransaction *transaction in transactions)
    {
        switch (transaction.transactionState)
        {
            case SKPaymentTransactionStatePurchased:{//交易完成
                NSLog(@"-----交易完成 --------");
                
                // 发送到苹果服务器验证凭证
                [self verifyPurchaseWithPaymentTransaction:AppPurchase];
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                
            } break;
            case SKPaymentTransactionStatePurchasing:
                NSLog(@"商品添加进列表");
                
                break;
            case SKPaymentTransactionStateRestored:{
                NSLog(@"已经购买过商品");
                
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
            }
                break;
            case SKPaymentTransactionStateFailed:{
                NSLog(@"交易失败");
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                 [MBProgressHUD showError:LELocalizedString(@"购买失败",nil)];
                [self hideLoadingView];
            }
                break;
            default:
                break;
        }
    }
}


//******验证购买,避免越狱软件模拟苹果请求达到非法购买问题******//
-(void)verifyPurchaseWithPaymentTransaction:(NSString *)verifyUrlStr
{
    
    [MBProgressHUD showMessage:LELocalizedString(@"正在验证订单。。。", nil)];
    //从沙盒中获取交易凭证并且拼接成请求体数据
    NSURL *receiptUrl=[[NSBundle mainBundle] appStoreReceiptURL];
    NSData *receiptData=[NSData dataWithContentsOfURL:receiptUrl];
    
    NSString *receiptString=[receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];//转化为base64字符串
    
    NSString *bodyString = [NSString stringWithFormat:@"{\"receipt-data\" : \"%@\"}", receiptString];//拼接请求数据
    NSData *bodyData = [bodyString dataUsingEncoding:NSUTF8StringEncoding];
    
    
    //创建请求到苹果官方进行购买验证
    NSURL *url=[NSURL URLWithString:verifyUrlStr];
    NSMutableURLRequest *requestM=[NSMutableURLRequest requestWithURL:url];
    requestM.HTTPBody=bodyData;
    requestM.HTTPMethod=@"POST";
    //创建连接并发送同步请求
    NSError *error=nil;
    NSData *responseData=[NSURLConnection sendSynchronousRequest:requestM returningResponse:nil error:&error];
    if (error) {
        NSString *errStr = [NSString stringWithFormat:LELocalizedString(@"验证购买过程中发生错误,错误信息:%@",nil),error.localizedDescription];
//        NSLog(@"验证购买过程中发生错误,错误信息:%@",error.localizedDescription);
        [MBProgressHUD hideHUD];
        
        [MBProgressHUD showError:errStr];
        return;
    }
    NSDictionary *dic=[NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingAllowFragments error:nil];
    NSLog(@"%@",dic);
    if([dic[@"status"] intValue]==0)
    {
        [MBProgressHUD hideHUD];
        NSLog(@"购买成功!");
       // [self buySuccess:dic];调取自己服务器函数
    }
    else if ([dic[@"status"] intValue]==21007)
    {
//         SANDBOX
        NSLog(@"应验证沙盒环境!");
        [self verifyPurchaseWithPaymentTransaction:SANDBOX];
    }
    else{
        NSLog(@"购买失败,未通过验证!");
        [MBProgressHUD hideHUD];
        
        [MBProgressHUD showError:LELocalizedString(@"购买失败",nil)];
    }
}

PS:

1、//沙盒测试环境验证购买
#define SANDBOX @"https://sandbox.itunes.apple.com/verifyReceipt"

//真实环境验证购买
#define APPSTORE @"https://buy.itunes.apple.com/verifyReceipt"

苹果审核时使用的仍是沙盒测试,所以需要确保在真实环境中沙盒测试依然可行,我的方案是dic[@"status"] intValue]==21007时多一步向沙盒请求验证购买,后台交易记录时记录购买环境

2、除非App Store版本,其它包均只能使用沙盒测试

3、内购项目的提交审核必须和包含内购代码的APP版本一起审核

posted @ 2017-10-17 10:41  锦夏ing  阅读(237)  评论(0编辑  收藏  举报