iOS In App购买收据生产或沙箱环境?

时间:2014-04-25 12:29:47

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

审核APPLE的消息

"我们发现您的应用未正确实施收据验证,因此无法正确区分审核(沙盒)环境和生产环境。这导致对生产服务器的验证查询而不是沙箱收据检查,并阻止我们查看您的应用程序"。

我们的查询: 我们正在验证申请中的本地收据。 在订阅问题时,我们会收到一张收据。应用程序不知道收据是属于Sandbox还是生产环境。因此,应用程序最初将收据发送到生产服务器。生产服务器返回21007,表示收据属于沙箱环境。然后我们将其发送到沙箱环境。您能否澄清这个程序是否错误?

订阅成功后获得收据:

-(void)checkReceipt:(NSData *)receipt forProdictId:(NSString *) productid
 {
AppDelegate *appDel = [[UIApplication sharedApplication] delegate];
[appDel showProgressViewWithText:@“Please wait...”];

[ReceiptCheck validateReceiptWithData:receipt completionHandler:^(BOOL success,NSString *response)
{
    if(success==YES) 
    {
        [self updateReceipt:receipt withResponse:response];

    }
    else
    {

        AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
        [appDelegate hideProgressView];
     }
  }
 }

---------------------------- 收据确认 ---------- ------------------------

#import "ReceiptCheck.h"
#import "NSString+Base64.h"
#import "SBJSON.h"

#define SHARED_SECRET @"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

#define RECEIPT_URL_SANDBOX @"https://sandbox.itunes.apple.com/verifyReceipt"
#define RECEIPT_URL_PRODUCTION @"https://buy.itunes.apple.com/verifyReceipt"

@implementation ReceiptCheck

@synthesize receiptData,completionBlock;

+(ReceiptCheck *)validateReceiptWithData:(NSData *)_receiptData completionHandler:(void(^)(BOOL,NSString *))handler {
ReceiptCheck *checker = [[ReceiptCheck alloc] init];
checker.receiptData=_receiptData;
checker.completionBlock=handler;
[checker checkReceipt];
return checker;

}

-(void)checkReceipt {
 // verifies receipt with Apple
 NSError *jsonError = nil;
 NSString *receiptBase64 = [NSString base64StringFromData:receiptData length:[receiptData length]];

 //    NSLog(@"Receipt Base64: %@",receiptBase64);
 NSData *jsonData = [NSJSONSerialization dataWithJSONObject:[NSDictionary dictionaryWithObjectsAndKeys: receiptBase64,@"receipt-data", SHARED_SECRET,@"password", nil] options:NSJSONWritingPrettyPrinted error:&jsonError];

if(jsonError)
{
    completionBlock(NO,[jsonError localizedDescription]);
    return;
}

NSURL *requestURL = [NSURL URLWithString:RECEIPT_URL_PRODUCTION];

NSMutableURLRequest *req = [[NSMutableURLRequest alloc] initWithURL:requestURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:150];
[req setHTTPMethod:@"POST"];
[req setHTTPBody:jsonData];
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];

if(conn) 
{
    receivedData = [[NSMutableData alloc] init];
} else 
{
    completionBlock(NO,@"Cannot create connection.");
}
}

 -(void)checkReceiptSandBox {
 // verifies receipt with Apple
 NSError *jsonError = nil;
 NSString *receiptBase64 = [NSString base64StringFromData:receiptData length:[receiptData length]];
  //    NSLog(@"Receipt Base64: %@",receiptBase64);
  //NSString *jsonRequest=[NSString stringWithFormat:@"{\"receipt-data\":\"%@\"}",receiptBase64];
  //NSLog(@"Sending this JSON: %@",jsonRequest);

 NSData *jsonData = [NSJSONSerialization dataWithJSONObject:[NSDictionary dictionaryWithObjectsAndKeys: receiptBase64,@"receipt-data", SHARED_SECRET,@"password", nil] options:NSJSONWritingPrettyPrinted error:&jsonError];
 //NSLog(@"JSON: %@",[[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding] );

if(jsonError)
{
    completionBlock(NO,[jsonError localizedDescription]);
    return;
}

NSURL *requestURL = [NSURL URLWithString:RECEIPT_URL_SANDBOX];

NSMutableURLRequest *req = [[NSMutableURLRequest alloc] initWithURL:requestURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:150];
[req setHTTPMethod:@"POST"];
[req setHTTPBody:jsonData];
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];

if(conn) 
{
    receivedData = [[NSMutableData alloc] init];
} else 
{
    completionBlock(NO,@"Cannot create connection.");
}
}

 -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 
 {
completionBlock(NO,[error localizedDescription]);
 }

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
{
[receivedData setLength:0];
}

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{
[receivedData appendData:data];
}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection 
{
NSString *response = [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];

NSData* data = [response dataUsingEncoding:NSUTF8StringEncoding];
NSString *json_string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
SBJSON *parser = [[SBJSON alloc] init];
NSDictionary *values = [parser objectWithString:json_string error:nil];


if([values valueForKey:@"status"])
{
    if([[values valueForKey:@"status"] integerValue] == 21007)
    { // SAND BOX RECEIPT

        [self checkReceiptSandBox];
        return;
    }
}

completionBlock(YES,response);
 }

 @end

更新收据后:

 - (void) updateReceipt:(NSData *)receipt  withResponse:(NSString *)response
 {
NSData* data = [response dataUsingEncoding:NSUTF8StringEncoding];
NSString *json_string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
SBJSON *parser = [[SBJSON alloc] init];

NSDictionary *values = [parser objectWithString:json_string error:nil];

NSLog(@"%@",values);


if([[values valueForKey:@"status"] integerValue] == 0)
{
    NSString *strReceipt=@"";
    if([values valueForKey:@"latest_receipt"])
    {


        strReceipt = [values valueForKey:@"latest_receipt"];

        if([values valueForKey:@"latest_receipt_info"])
        {
            [self saveReceiptDetailsWithReceipt:strReceipt andReceiptInfo:values];

            NSString *strProductID = [[values valueForKey:@"latest_receipt_info"] valueForKey:@"product_id"];

            NSLog(@"%@",strProductID);
            WebServices *webService = [[WebServices alloc] init];
            webService.delegate=self;
            AppDelegate *appDel = [[UIApplication sharedApplication] delegate];
            [appDel showProgressViewWithText:@"Please wait..."];
            webService.strSubscriptionProductID=strProductID;
            [webService afterSubscription:values andSubscriptionId:[self getSubscriptionIDForProductID:strProductID] receipt:strReceipt];
        }
    }
}
else if([[values valueForKey:@"status"] integerValue] == 21006)
{
    NSString *strReceipt=[NSString base64StringFromData:receipt length:[receipt length]];
    if([values valueForKey:@"latest_expired_receipt_info"])
    {
        [self saveReceiptDetailsWithReceipt:strReceipt andReceiptInfo:values];
    }
}
else if([[values valueForKey:@"status"] integerValue] == 21000)
{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"JSON Error" message:[NSString stringWithFormat:@"The App Store could not read the JSON object you provided."] delegate:nil cancelButtonTitle:@"Close" otherButtonTitles:nil];
    [alert show];
}
else if([[values valueForKey:@"status"] integerValue] == 21002)
{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Data Error" message:[NSString stringWithFormat:@"The data in the receipt-data property was malformed."] delegate:nil cancelButtonTitle:@"Close" otherButtonTitles:nil];
    [alert show];
}
else if([[values valueForKey:@"status"] integerValue] == 21003)
{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Receipt Authentication Error" message:[NSString stringWithFormat:@"The receipt could not be authenticated."] delegate:nil cancelButtonTitle:@"Close" otherButtonTitles:nil];
    [alert show];
}
else if([[values valueForKey:@"status"] integerValue] == 21004)
{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Shared Secret Error" message:[NSString stringWithFormat:@"The shared secret you provided does not match the shared secret on file for your account."] delegate:nil cancelButtonTitle:@"Close" otherButtonTitles:nil];
    [alert show];
}
else if([[values valueForKey:@"status"] integerValue] == 21005)
{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Server Error" message:[NSString stringWithFormat:@"The receipt server is not currently available."] delegate:nil cancelButtonTitle:@"Close" otherButtonTitles:nil];
    [alert show];
}
else if([[values valueForKey:@"status"] integerValue] == 21007)
{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Receipt Error" message:[NSString stringWithFormat:@"This receipt is a sandbox receipt, but it was sent to the production service for verification."] delegate:nil cancelButtonTitle:@"Close" otherButtonTitles:nil];
    [alert show];
}
else if([[values valueForKey:@"status"] integerValue] == 21008)
{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Receipt Error" message:[NSString stringWithFormat:@"This receipt is a production receipt, but it was sent to the sandbox service for verification."] delegate:nil cancelButtonTitle:@"Close" otherButtonTitles:nil];
    [alert show];
}
 }

0 个答案:

没有答案