如何在ios中阅读离线收据inpp购买?

时间:2017-05-22 13:05:33

标签: ios objective-c in-app-purchase

我已经在我的应用程序中实施了Inapp购买并验证了收据但我在离线时遇到验证收据的问题。我该怎么做?

以下是我的代码,用于验证我的互联网何时连接。

-(void)refreshRecipt
{
    NSError *error;
    _isUserActive = NO;

    NSURL *recieptUrl = [[NSBundle mainBundle]appStoreReceiptURL];
    NSError *recieptError;

    BOOL isPresent = [recieptUrl checkResourceIsReachableAndReturnError:&recieptError];

    if (!isPresent)
    {
        SKReceiptRefreshRequest *ref = [[SKReceiptRefreshRequest alloc]init];
        ref.delegate =self;
        [ref start];
        return;
    }

    NSData *reciptData = [NSData dataWithContentsOfURL:recieptUrl];
    if (!reciptData)
    {
        return;
    }

    dicPayload = [NSMutableDictionary dictionaryWithObject:[reciptData base64EncodedStringWithOptions:0] forKey:@"receipt-data"];

    [dicPayload setObject:@"21f843e264474b68b3a81c6b7ca19938" forKey:@"password"];

    NSData *requestData = [NSJSONSerialization dataWithJSONObject:dicPayload
                                                          options:0
                                                            error:&error];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:verifyRecieptURL]];
    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:requestData];

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [NSURLConnection sendAsynchronousRequest:request queue:queue
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
                               if (connectionError) {
                                   NSLog(@"error");

                               } else {
                                   NSError *error;
                                   NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
                                           if ([jsonResponse objectForKey:@"latest_receipt_info"])
                                           {
                                               NSArray *array = [jsonResponse objectForKey:@"latest_receipt_info"];
                                               NSLog(@"%@",array);

                                               NSDictionary *latestDetail = [array lastObject];
                                                if ([latestDetail objectForKey:@"is_trial_period"])
                                                {
                                                   if ([[latestDetail objectForKey:@"is_trial_period"] isEqualToString:@"true"])
                                                   {
                                                       _isFreeTrialActive  = YES;
                                                   }
                                                   else
                                                   {
                                                       _isFreeTrialActive = NO;
                                                   }

                                                   _isUserActive = [self calculateCurrentSubscriptionActive:[latestDetail objectForKey:@"expires_date_ms"]];


                                                   if (_isUserActive)
                                                   {
                                                       NSLog(@"User is active");
                                                       _SubscriptionActive = YES;

                                                   }
                                                   else
                                                   {
                                                       _SubscriptionActive = NO;
                                                       NSLog(@"User is not active");
                                                   }
                                                }
                                               else
                                               {
                                                   NSLog(@"no purachase done,first time user!");
                                               }
                                   }
                               }
                           }];

}

请帮我解决这个问题。

1 个答案:

答案 0 :(得分:0)

您可以在本地验证收据,这是您根据Apple文档执行此操作的方式:

  

验证收据

     

要验证收据,请按顺序执行以下测试:

     

1-找到收据。   如果没有收据,则验证失败。

     

2-确认Apple已正确签署收据。   如果它未由Apple签名,则验证失败。

     

3-验证收据中的包标识符是否与包含Info.plist文件中所需的CFBundleIdentifier值的硬编码常量相匹配。   如果它们不匹配,则验证失败。

     

4-验证收据中的版本标识符字符串是否与包含CFBundleShortVersionString值(对于macOS)或CFBundleVersion值(对于iOS)在Info.plist文件中所需的硬编码常量匹配。   如果它们不匹配,则验证失败。

     

5-计算GUID的哈希值,如计算GUID的哈希值中所述。   如果结果与收据中的哈希不匹配,则验证失败。

     

如果所有测试都通过,则验证通过。

为此,您首先需要解密收据。为此,您可以使用RMStore之类的库。使用此库,您可以执行以下操作:

- (RMAppReceipt *)validReceipt {
    RMAppReceipt *receipt = [RMAppReceipt bundleReceipt];

    if (!receipt)
        //No receipt
        return nil;

    if (![receipt.bundleIdentifier isEqualToString:@"Your bundle ID"]) {
        //Receipt is invalid
        return nil;
    }
    if (![receipt verifyReceiptHash]) {
        //Receipt is invalid
        return nil;
    }

    //Receipt is valid
    return receipt;
}

RMAppReceipt包含收据中的所有信息。