Search code examples
iosobjective-creceipt-validation

Receipt validation is incorrect


I have tested on IAP of type Consumable with Sandbox environment. I want to make sure that the item I have bought is valid or not. but the result is always return with status "21004". I do nothing with share secret. So you can look the sample code that I follow apple when I succeed to purchase item:

- (void)verifyStatus:(SKPaymentTransaction *)transaction {

     NSData *receiptData = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL]];
     NSError *receiptError;
     BOOL isPresent = [[[NSBundle mainBundle] appStoreReceiptURL] checkResourceIsReachableAndReturnError:&receiptError];
     if (!isPresent) {
         NSLog(@"Validation failed");
     } 
     NSString *receiptStr = [receiptData base64EncodedStringWithOptions:0];
     NSDictionary *requestContents = @{@"receipt-data":receiptStr};
     NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents
                                                      options:0
                                                        error:nil];

     if (!requestData) { /* ... Handle error ... */ }

     NSURL *storeURL = [NSURL URLWithString:@"https://sandbox.itunes.apple.com/verifyReceipt"];
     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];
                               NSLog(@"Respond : %@",jsonResponse);
                               if (!jsonResponse) { /* ... Handle error ...*/ }
                               /* ... Send a response back to the device ... */
                           }
}];

}

What's the problem I got? Please share your experience. Thanks


Solution

  • Please try following code and steps for SECRECT KEY.

     #define SHARED_SECRET @"SECRECT KEY"
    
    -(void)checkReceipt {
        // verifies receipt with Apple
        NSError *jsonError = nil;
    
        NSString *receiptBase64 = [receiptData base64EncodedStringWithOptions:0];//receiptData NSData for validate Receipt
        NSLog(@"Receipt Base64: %@",receiptBase64);
    
        NSData *jsonData = [NSJSONSerialization dataWithJSONObject:[NSDictionary dictionaryWithObjectsAndKeys:
                                                                    receiptBase64,@"receipt-data",
                                                                    SHARED_SECRET,@"password",
                                                                    nil]
                                                           options:NSJSONWritingPrettyPrinted
                                                             error:&jsonError
                            ];
        NSLog(@"%@",jsonData);
        NSError * error=nil;
        NSDictionary * parsedData = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
        NSLog(@"%@",parsedData);
        NSLog(@"JSON: %@",[[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]);
        // URL for sandbox receipt validation; replace "sandbox" with "buy" in production or you will receive
        // error codes 21006 or 21007
        NSURL *requestURL = [NSURL URLWithString:@"https://sandbox.itunes.apple.com/verifyReceipt"];
    
        NSMutableURLRequest *req = [[NSMutableURLRequest alloc] initWithURL:requestURL];
        [req setHTTPMethod:@"POST"];
        [req setHTTPBody:jsonData];
    
    
        NSOperationQueue *queue = [[NSOperationQueue alloc] init];
        [NSURLConnection sendAsynchronousRequest:req 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];
                                       NSLog(@"Respond : %@",jsonResponse);
                                       if (!jsonResponse) { /* ... Handle error ...*/ }
                                       /* ... Send a response back to the device ... */
                                   }
                               }];
    
    }
    

    You need to change "SECRECT KEY" with the secret key that you get from iTunes Connect.sample look like 39fkjc38jd02mg72k9cn29dfkm39fk00.

    Below is the step for create/view Secreate Key.

    Login into iTunes Connect -> My Apps > Select your app > In-App Purchases > View or generate a shared secret.