ios 内购 恢复内购

陌路散爱 提交于 2019-11-28 19:52:33

申请内购部分略。。。。。。。
代码部分

1 //准备工作

[[SKPaymentQueue defaultQueue] addTransactionObserver:self]; 
<SKPaymentTransactionObserver,SKProductsRequestDelegate> //遵循代理
打开支付开关 如下图:

在这里插入图片描述
2 //商品查询 msg 是商品编号

    if ([SKPaymentQueue canMakePayments]) {
        NSLog(@"用户允许内购");
        
        NSArray *product = [[NSArray alloc] initWithObjects:msg,nil];
        NSSet *nsset = [NSSet setWithArray:product];
        
        //初始化请求
        SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:nsset];
        request.delegate = self;
        
        //开始请求
        [request start];
        
    } else {
        NSLog(@"用户不允许内购");
    }
    

3//请求到商品信息 然后在里面验证 在发起支付

#pragma mark - SKProductsRequestDelegate
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response NS_AVAILABLE_IOS(3_0)
{
    NSArray *product = response.products;
    
    //如果服务器没有产品
    if([product count] == 0){
        NSLog(@"没有该商品");
        return;
    }
    
    SKProduct *requestProduct = nil;
    for (SKProduct *pro in product) {
        
        NSLog(@"%@", [pro description]);
        NSLog(@"%@", [pro localizedTitle]);
        NSLog(@"%@", [pro localizedDescription]);
        NSLog(@"%@", [pro price]);
        NSLog(@"%@", [pro productIdentifier]);
        
        //如果后台消费条目的ID与我这里需要请求的一样(用于确保订单的正确性)
        if([pro.productIdentifier isEqualToString:_payStr]){
            requestProduct = pro;
        }
    }
    
    //发送购买请求
    SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:requestProduct];
    payment.applicationUsername = [self getRandomStr];//可以是userId,也可以是订单id,跟你自己需要而定
    [[SKPaymentQueue defaultQueue] addPayment:payment];
}
- (NSString *)getRandomStr {
    char data[6];
    for (int x=0;x < 6;data[x++] = (char)('A' + (arc4random_uniform(26))));
    NSString *randomStr = [[NSString alloc] initWithBytes:data length:6 encoding:NSUTF8StringEncoding];
    NSString *string = [NSString stringWithFormat:@"%@",randomStr];
    return string;
    
}
//请求失败
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error
{
    NSLog(@"error:%@", error);
}

//请求结束
- (void)requestDidFinish:(SKRequest *)request
{
    NSLog(@"请求结束");
}

4购买结果

#pragma mark - SKPaymentTransactionObserver
//监听购买结果
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
    for(SKPaymentTransaction *tran in transactions) {
        switch (tran.transactionState) {
            case SKPaymentTransactionStatePurchased:
                NSLog(@"交易完成");
                [self hidden];
                [self completeTransaction:tran];
                
                break;
            case SKPaymentTransactionStatePurchasing:
                NSLog(@"商品添加进列表");
                
                break;
            case SKPaymentTransactionStateRestored:
                NSLog(@"已经购买过商品");
                [self hidden];
                [self paySucess];
                [[SKPaymentQueue defaultQueue] finishTransaction:tran]; //消耗型商品不用写
                break;
            case SKPaymentTransactionStateFailed:
                NSLog(@"交易失败");
                [self hidden];
                [[SKPaymentQueue defaultQueue] finishTransaction:tran];
                break;
            default:
                break;
        }
    }
}
#pragma mark 验证购买
//交易结束,当交易结束后还要去appstore上验证支付信息是否都正确,只有所有都正确后,我们就可以给用户方法我们的虚拟物品了。
- (void)completeTransaction:(SKPaymentTransaction *)transaction {
    
    NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
    NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
    NSURL *url = [NSURL URLWithString:APPSTOREURL];
    
    NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:15.0f];
    urlRequest.HTTPMethod = @"POST";
    
    NSString *encodeStr = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
    NSString *payload = [NSString stringWithFormat:@"{\"receipt-data\" : \"%@\"}", encodeStr];
    NSData *payloadData = [payload dataUsingEncoding:NSUTF8StringEncoding];
    urlRequest.HTTPBody = payloadData;
    
    NSData *result = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:nil error:nil];
    
    if (result == nil) {
        NSLog(@"验证失败");
        return;
    }
    
    //    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:result options:NSJSONReadingAllowFragments error:nil];
    //    NSLog(@"请求成功后的数据:%@",dic);
    //这里可以通过判断 state == 0 验证凭据成功,然后进入自己服务器二次验证,,也可以直接进行服务器逻辑的判断。
    //本地服务器验证成功之后别忘了 [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
    
    //    NSString *productId = transaction.payment.productIdentifier;
    //    NSString *applicationUsername = transaction.payment.applicationUsername;
    //
    //    NSLog(@"applicationUsername++++%@",applicationUsername);
    //    NSLog(@"payment.productIdentifier++++%@",productId);
    
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
    [self paySucess];
}

5恢复购买 -->如果该appid购买过这个商品 可以恢复

先执行第一步 然后接下来
  [[SKPaymentQueue defaultQueue] restoreCompletedTransactions];//发起请求  
     
请求的回调
#pragma mark -- 恢复交易处理
- (void)restoreTransaction:(SKPaymentTransaction *)transaction {
    NSLog(@" 交易恢复处理ing");
    
}
//恢复失败
-(void) paymentQueue:(SKPaymentQueue *) paymentQueue restoreCompletedTransactionsFailedWithError:(NSError *)error{
    [self hidden];
    NSLog(@"-------paymentQueue----");
}

如果用户已经购买过这个商品 会走 - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions 会调 这个回调在上面写过了 这里就不在说了

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!